39 — Forgeyard Configuration, Feature Flags, Runtime Settings & Dynamic Configuration Governance System Architecture
Document type: Core Configuration, Runtime Settings, Feature Flags, Dynamic Reload & Configuration Governance System Architecture
Project: Forgeyard CI/CD
Subsystem: layered configuration, RON manifests, runtime settings, feature flags, staged rollout, kill switches, tenant/project overrides, dynamic reload, immutable configuration snapshots, schema validation, secret references, config provenance, drift detection, rollout safety, rollback, compatibility, audit, and policy integration
Architecture style: Strongly typed, schema-versioned, layered, deterministic, immutable-snapshot based, auditable, policy-aware, secret-safe, rollbackable, and explicit about static vs dynamic configuration boundaries
Status: Target production architecture extending the Forgeyard series beyond the original 01–26 plan
Relationship to prior work: Builds on Core Config, Policy/Authz, Secrets, API/Axum, Dioxus UI, HA/Coordination, Operations/Upgrade/DR, Multi-Tenancy, Entitlements, Developer Experience, Plugins, Notifications, Audit, and Self-Hosting. This subsystem turns configuration into a governed first-class control-plane domain instead of scattered environment variables and ad-hoc files.
1. Purpose
Forgeyard contains many kinds of configuration:
server ports
database settings
CAS backends
runner pools
sandbox defaults
policy bundles
notification routes
SCM integrations
feature availability
rollout toggles
limits
timeouts
retention
UI preferences
plugin enablement
deployment defaults
Without a dedicated architecture, configuration tends to become:
environment variables
command-line flags
database rows
hidden defaults
feature booleans
provider-specific settings
spread across the codebase.
That creates drift, poor explainability, unsafe rollout, and hard-to-reproduce incidents.
The central rule is:
Forgeyard behavior is governed by validated, typed, versioned configuration snapshots. Runtime code consumes effective configuration, never an uncontrolled mixture of environment variables, raw database values, and provider settings.
A second rule is:
Static configuration and dynamically reloadable configuration are different categories. Forgeyard must never pretend a setting can be changed safely at runtime when the subsystem requires restart or migration.
A third rule is:
Feature flags are controlled rollout instruments, not a substitute for authorization, policy, entitlement, schema migration, or permanent product architecture.
2. Architectural Position
Configuration Sources
┌──────────────┼──────────────┐
▼ ▼ ▼
Defaults RON Files DB Overrides
│ │ │
└──────────────┼──────────────┘
▼
Parse / Validate
│
▼
Layer Resolution
│
▼
Config Snapshot
│
┌──────────┼──────────┐
▼ ▼ ▼
Runtime Feature Policy/
Settings Flags Entitlement
│ │ │
└──────────┼──────────┘
▼
Application Services
3. Goals
The subsystem MUST:
- define typed configuration;
- define configuration identity;
- support layered sources;
- support RON config;
- support environment-specific values;
- support tenant/org/project overrides;
- support runtime configuration;
- distinguish static/dynamic settings;
- support feature flags;
- support staged rollout;
- support kill switches;
- support validation;
- support schema versioning;
- support config migration;
- support immutable snapshots;
- support rollback;
- support config explainability;
- support drift detection;
- support secret references;
- support safe reload;
- support HA propagation;
- support audit;
- support notification;
- support policy integration;
- support entitlement integration;
- support plugin config;
- support CLI/UI administration;
- support standalone mode;
- support distributed mode;
- remain deterministic and testable.
4. Non-Goals
This subsystem does not:
replace policy
replace secrets management
replace entitlement
replace deployment configuration
replace application-level user preferences
permit arbitrary code execution from configuration
5. Workspace Structure
crates/config/
├── forgeyard-config/
├── forgeyard-config-model/
├── forgeyard-config-schema/
├── forgeyard-config-loader/
├── forgeyard-config-layer/
├── forgeyard-config-validate/
├── forgeyard-config-snapshot/
├── forgeyard-config-runtime/
├── forgeyard-config-drift/
├── forgeyard-config-migrate/
├── forgeyard-config-health/
└── forgeyard-config-testkit/
Feature flags:
crates/feature/
├── forgeyard-feature/
├── forgeyard-feature-model/
├── forgeyard-feature-evaluate/
├── forgeyard-feature-rollout/
├── forgeyard-feature-killswitch/
└── forgeyard-feature-testkit/
Use modules first; split only where dependency/security/runtime boundaries justify.
6. Configuration Domains
Separate:
SystemConfig
TenantConfig
ProjectConfig
RunnerConfig
PluginConfig
UiConfig
RuntimeConfig
FeatureConfig
7. No Giant Global Config Struct
Critical.
Prefer composable typed domains.
8. Configuration Identity
#![allow(unused)]
fn main() {
pub struct ConfigSnapshotId(Digest);
}
Content-derived from canonical effective config.
9. Configuration Schema Version
#![allow(unused)]
fn main() {
pub struct ConfigSchemaVersion(u16);
}
10. Config Source
#![allow(unused)]
fn main() {
pub enum ConfigSource {
BuiltInDefault,
SystemFile,
EnvironmentOverride,
DatabaseOverride,
TenantOverride,
OrganizationOverride,
ProjectOverride,
RuntimeAdminOverride,
}
}
11. Source Precedence
Explicit.
Recommended baseline:
built-in defaults
↓
system configuration
↓
deployment/environment configuration
↓
tenant/org/project configuration
↓
explicit runtime override
12. CLI Flags
Application startup override only for approved settings.
13. Environment Variables
Compatibility/bootstrap source only.
14. No Arbitrary Env Overlay
Critical.
Environment variables map only to explicitly declared config keys.
15. Why
Prevent hidden environment drift.
16. RON
Primary human-authored configuration format.
17. JSON
Public API transport only where appropriate.
18. Postcard
Internal snapshot/wire format where suitable.
19. Raw / Parsed / Validated
Reuse existing core model.
RawConfig
↓ parse
ParsedConfig
↓ validate
ValidatedConfig
↓ layer
EffectiveConfig
20. Canonical Effective Config
Immutable snapshot.
21. ConfigSnapshot
#![allow(unused)]
fn main() {
pub struct ConfigSnapshot {
pub id: ConfigSnapshotId,
pub schema: ConfigSchemaVersion,
pub created_at: Timestamp,
pub source_refs: Vec<ConfigSourceRef>,
pub effective: EffectiveConfig,
}
}
22. Config Source Ref
Safe metadata only.
23. Secret Values
Never included in ConfigSnapshot.
24. SecretRef
Configuration stores references.
25. Example
database: (
url: Secret("system/database/url"),
)
26. Secret Resolution
Late, at consuming boundary.
27. Static Setting
Requires process/service restart.
28. Dynamic Setting
Can reload safely at runtime.
29. Reloadability
#![allow(unused)]
fn main() {
pub enum Reloadability {
Static,
RestartComponent(ComponentKind),
Dynamic,
}
}
30. Every Config Field
Should declare reloadability metadata.
31. Why
Avoid unsafe hot reload assumptions.
32. ConfigFieldDescriptor
#![allow(unused)]
fn main() {
pub struct ConfigFieldDescriptor {
pub path: ConfigFieldPath,
pub reloadability: Reloadability,
pub sensitivity: ConfigSensitivity,
pub scope: ConfigScope,
}
}
33. Sensitivity
#![allow(unused)]
fn main() {
pub enum ConfigSensitivity {
Public,
Internal,
Sensitive,
SecretRefOnly,
}
}
34. Scope
#![allow(unused)]
fn main() {
pub enum ConfigScope {
System,
Tenant,
Organization,
Project,
RunnerPool,
Environment,
}
}
35. Not Every Field Is Overrideable at Every Scope
Critical.
36. Example
Tenant cannot override:
system CA trust
database backend
cluster coordination
security baseline
37. Override Permission Matrix
Schema defines allowed child scopes.
38. Config Layer
#![allow(unused)]
fn main() {
pub struct ConfigLayer {
pub source: ConfigSource,
pub scope: ConfigScopeRef,
pub values: ConfigPatch,
}
}
39. Config Patch
Typed partial structure.
40. No Generic JSON Merge Patch in Core
Strong typing preferred.
41. Layer Resolution
Deterministic.
42. Config Explain
For any field:
effective value
source layer
overridden layers
reloadability
43. CLI
forgeyard config explain <path>
44. Redaction
Sensitive fields show refs/status, not values.
45. Configuration Validation
Multiple levels:
syntax
schema
cross-field
capability
policy
environment
46. Syntax
RON parser.
47. Schema
Type validation.
48. Cross-Field
Example:
HA enabled but one voter configured
invalid/warn.
49. Capability
Example:
sandbox.seccomp=true
on unsupported host.
50. Policy
Example:
external plugin network enabled
may violate policy.
51. Environment
Example:
object store bucket unreachable
runtime preflight, not pure schema validation.
52. Validation Result
#![allow(unused)]
fn main() {
pub struct ConfigValidationResult {
pub errors: Vec<ConfigDiagnostic>,
pub warnings: Vec<ConfigDiagnostic>,
}
}
53. Diagnostics
Span-aware where human file source exists.
54. Config Change
#![allow(unused)]
fn main() {
pub struct ConfigChange {
pub base: ConfigSnapshotId,
pub patch: ConfigPatch,
pub actor: PrincipalId,
}
}
55. Validate Before Activate
Critical.
56. Config Activation
propose
↓
parse/validate
↓
policy/authz
↓
create immutable snapshot
↓
activate pointer
57. ActiveConfigRef
Mutable pointer to immutable snapshot.
58. Rollback
Point active ref to previous compatible snapshot.
59. No In-Place Snapshot Mutation
Critical.
60. Config History
Persist snapshots + activation events.
61. Rollback Safety
Static fields may still require restart.
62. Rollback Plan
#![allow(unused)]
fn main() {
pub struct ConfigRollbackPlan {
pub target: ConfigSnapshotId,
pub restart_components: Vec<ComponentKind>,
pub compatibility: ConfigCompatibility,
}
}
63. ConfigCompatibility
#![allow(unused)]
fn main() {
pub enum ConfigCompatibility {
SafeDynamic,
RequiresRestart,
RequiresMigration,
Unsafe,
}
}
64. Migration
Some config changes may require data/schema changes.
65. Config Does Not Perform DB Migration
Coordinates with migration subsystem.
66. Feature Flags
Separate from general config.
67. FeatureFlagId
#![allow(unused)]
fn main() {
pub struct FeatureFlagId(BoundedString);
}
68. Feature Flag
#![allow(unused)]
fn main() {
pub struct FeatureFlag {
pub id: FeatureFlagId,
pub state: FeatureFlagState,
pub rollout: FeatureRollout,
pub expires_at: Option<Timestamp>,
}
}
69. Feature Flag State
#![allow(unused)]
fn main() {
pub enum FeatureFlagState {
Disabled,
Enabled,
Rollout,
Killed,
}
}
70. Killed
Emergency hard-off.
71. Flag vs Entitlement
Important:
Feature Flag:
is functionality operationally enabled?
Entitlement:
is customer commercially allowed?
Authz:
may this principal use it?
72. Effective Feature Availability
implemented
AND
flag enabled
AND
entitled if commercial
AND
authorized
AND
policy permits
73. Feature Flag Is Not Security Boundary Alone
Critical.
74. Feature Rollout
#![allow(unused)]
fn main() {
pub enum FeatureRollout {
All,
Percentage(RolloutPercentage),
Tenants(BTreeSet<TenantId>),
Projects(BTreeSet<ProjectId>),
Principals(BTreeSet<PrincipalId>),
Cohort(FeatureCohortId),
}
}
75. Percentage Rollout
Deterministic.
76. Stable Bucketing
Hash:
flag ID
subject stable ID
rollout seed
77. No Random Per Request
Critical.
78. Rollout Seed
Versioned.
79. Percentage Meaning
Same subject consistently in/out.
80. Cohort
Explicit stored membership or deterministic rule.
81. Avoid Sensitive Profiling
Feature cohorts based on product/admin criteria, not opaque personal profiling.
82. Flag Scope
System/tenant/project.
83. Child Override
Only if schema permits.
84. Kill Switch
Emergency disable path.
85. KillSwitchId
#![allow(unused)]
fn main() {
pub struct KillSwitchId(BoundedString);
}
86. Use Cases
disable compromised plugin type
disable new release publisher
disable faulty scheduler optimization
disable remote cache writes
disable external dependency resolution
87. Kill Switch Characteristics
fast
auditable
safe default
limited scope
88. Kill Switch Should Not Require Code Deploy
89. Kill Switch Does Not Replace Incident Response
It is containment tool.
90. Kill Switch Evaluation
Prefer local in-memory snapshot for fast path.
91. Dynamic Reload
Config snapshot distributed to services.
92. Config Distribution
Mode 2:
Postgres authoritative snapshot
↓
config-change event
↓
daemon/service reload
↓
ack status
93. Event Fast Path
Reconciliation slow path.
94. No Exactly-Once Reload
Idempotent snapshot application.
95. ComponentConfigGeneration
#![allow(unused)]
fn main() {
pub struct ComponentConfigGeneration(u64);
}
96. Each Component
Tracks applied ConfigSnapshotId.
97. Configuration Drift
active snapshot = A
component reports B
drift.
98. Drift State
#![allow(unused)]
fn main() {
pub enum ConfigDriftState {
InSync,
Applying,
Drifted,
Unknown,
}
}
99. Drift Reconciler
Reapply or request restart.
100. Dynamic Reload Failure
Do not claim success.
101. Config Activation State
#![allow(unused)]
fn main() {
pub enum ConfigActivationState {
Proposed,
Validated,
Activating,
Active,
PartiallyApplied,
Failed,
RolledBack,
}
}
102. PartiallyApplied
First-class.
103. Protected Config
Can require all critical components applied before activation considered complete.
104. Rollout Strategy
Config changes can be staged.
105. ConfigRollout
#![allow(unused)]
fn main() {
pub enum ConfigRollout {
Immediate,
Rolling,
Canary(Vec<ComponentInstanceId>),
}
}
106. Static Restart Rollout
Integrates HA rolling upgrade semantics.
107. Example
Change runner-agent heartbeat:
dynamic
Change QUIC bind port:
restart component
Change DB backend:
migration/redeploy
108. No Universal Hot Reload
Critical.
109. Validation Preflight
For external resources:
test connection
check credentials
verify permissions
110. Preflight Is Side-Effect Safe
Avoid mutation.
111. Config Plan
#![allow(unused)]
fn main() {
pub struct ConfigChangePlan {
pub base: ConfigSnapshotId,
pub candidate: ConfigSnapshotId,
pub diff: ConfigDiff,
pub required_actions: Vec<ConfigApplyAction>,
}
}
112. Apply Action
DynamicReload
RestartDaemon
RestartAgent
RunMigration
ReconfigureProvider
113. Config Diff
Typed.
114. UI/CLI
Show safe before/after.
115. SecretRef Diff
Shows ref changed, never secret.
116. Config Approval
High-risk config may require approval.
117. Examples
trust root
external network
signing provider
production deployment provider
cross-tenant cache
118. Approval
Reuse policy/human workflow.
119. Config Policy Digest
Activation records PolicyDigest.
120. Audit
Every protected config activation audited.
121. Audit Fields
actor
base snapshot
new snapshot
scope
diff digest
reason
result
122. Runtime Overrides
Use sparingly.
123. RuntimeOverrideId
#![allow(unused)]
fn main() {
pub struct RuntimeOverrideId(Ulid);
}
124. Override
#![allow(unused)]
fn main() {
pub struct RuntimeOverride {
pub id: RuntimeOverrideId,
pub scope: ConfigScopeRef,
pub patch: ConfigPatch,
pub reason: BoundedString,
pub expires_at: Option<Timestamp>,
}
}
125. Expiry
Strongly recommended.
126. Temporary Incident Override
Good use.
127. Permanent Config
Move into normal config source.
128. Override Expiry
Durable timer.
129. Expired Override
Triggers new effective snapshot.
130. No Hidden “Forever” Emergency Override
Critical.
131. Environment Variables
Startup bootstrap examples:
FORGEYARD_CONFIG
FORGEYARD_DATA_DIR
FORGEYARD_LOG_LEVEL
132. Sensitive Env
Avoid.
133. Secret Providers
Configured via SecretRef/bootstrap mechanism.
134. Bootstrap Secret Problem
Some initial credentials may need OS secret/keyring/file permission protected mechanism.
135. Bootstrap Config
Small and explicitly documented.
136. Config Bootstrap Layer
Cannot depend on DB if DB connection itself is configured there.
137. Bootstrap vs Runtime Config
Separate.
138. BootstrapConfig
#![allow(unused)]
fn main() {
pub struct BootstrapConfig {
pub mode: ForgeyardMode,
pub data_dir: PathBuf,
pub metadata_backend: MetadataBootstrap,
pub initial_config_source: ConfigSourceLocation,
}
}
139. Minimal
Only enough to start config system.
140. Standalone Mode
System file/local DB.
141. Distributed Mode
Bootstrap DB/CAS/trust endpoints, then authoritative runtime config from metadata store.
142. Configuration Store
Part 2 metadata.
143. Snapshot Bytes
Can be CAS-backed.
144. Active Pointer
DB.
145. Tenant Config
Scoped rows/snapshots.
146. Effective Tenant Config
Base system snapshot + tenant layer.
147. Project Config
Further layer.
148. Resolution Cost
Cache effective snapshots.
149. EffectiveConfigCache
Key:
system snapshot
tenant layer version
org layer version
project layer version
150. Not Build Cache
Separate internal config cache.
151. Cache Invalidation
Version-based.
152. Configuration Access
Services receive typed domain config.
153. No get("foo.bar") Throughout Domain
Critical.
154. Adapter Config
Provider-specific details stay in adapter crate.
155. Example
S3 config types in CAS S3 adapter.
156. Core Config
Only normalized capability-level fields.
157. Plugin Config
Plugin manifest declares schema.
158. Plugin Config Isolation
Plugin receives only its namespace.
159. Plugin Cannot Read Full system config.
160. Plugin Secret Fields
SecretRef/host-mediated.
161. Plugin Config Schema
Versioned with plugin version/API.
162. Unknown Plugin Field
Validation error/warning per schema policy.
163. Feature Flag Lifecycle
Flags should not live forever.
164. FeatureFlagMetadata
#![allow(unused)]
fn main() {
pub struct FeatureFlagMetadata {
pub owner: PrincipalOrTeamRef,
pub created_at: Timestamp,
pub expires_at: Option<Timestamp>,
pub cleanup_issue: Option<ExternalTrackingRef>,
}
}
165. Expiry
For rollout flags.
166. Permanent Capability Switch
May become normal config instead.
167. Flag Debt
Analytics can report old flags.
168. Kill Switch
May be permanent operational control.
169. Flag Evaluation
#![allow(unused)]
fn main() {
pub trait FeatureEvaluator {
fn evaluate(
&self,
flag: FeatureFlagId,
context: FeatureContext,
) -> FeatureDecision;
}
}
170. FeatureDecision
#![allow(unused)]
fn main() {
pub enum FeatureDecision {
Enabled(FeatureDecisionReason),
Disabled(FeatureDecisionReason),
Killed,
}
}
171. Decision Reason
Explainable.
172. UI
Can show admin why subject sees feature.
173. No Secret Feature Flag Data
174. Feature Flag Performance
In-memory immutable snapshot.
175. No DB Query Per Request
Critical.
176. Snapshot Refresh
Event/reconcile.
177. Flag Change Propagation
Seconds-level expected; not instantaneous global linearizability unless explicitly built.
178. Kill Switch Critical Path
Can use coordination epoch/fast invalidation.
179. High-Risk Kill Switch
May require immediate control-plane broadcast plus local poll fallback.
180. HA
Any daemon can read authoritative snapshot.
181. Active Snapshot
DB authority.
182. Raft
Not needed for ordinary config.
183. Raft Use
Only if specific cluster-coordination setting must be serialized with leadership/membership.
184. No Config in Raft Log by Default
Critical.
185. Configuration Consistency Model
Eventual component application with explicit desired vs observed snapshot.
186. Desired
Active ConfigSnapshotId.
187. Observed
Component reports applied ID.
188. Control Plane
Can block sensitive workflow if critical component drifted.
189. Example
Signing configuration changed but signing worker not updated.
Release signing may pause.
190. Policy
Can define required config convergence.
191. Config Health
active snapshot
applied components
drifted components
failed reload
expired overrides
expired flags
192. Doctor
forgeyard config doctor
193. Doctor Checks
schema compatibility
active snapshot integrity
component drift
invalid overrides
feature flag expiry
secret ref resolution readiness
194. Config Lint
forgeyard config check
195. Config Plan
forgeyard config plan
196. Config Apply
forgeyard config apply
197. Config History
forgeyard config history
198. Config Rollback
forgeyard config rollback <snapshot>
199. Feature CLI
forgeyard feature list
forgeyard feature explain <flag>
forgeyard feature rollout <flag>
forgeyard feature kill <flag>
200. High-Risk CLI
Requires explicit confirmation/authz.
201. JSON/RON Output
Supported.
202. Dioxus UI
Pages:
Configuration
Effective Config
Config History
Runtime Overrides
Feature Flags
Kill Switches
Config Drift
203. Config Editor
Typed forms.
204. Raw RON Editor
Advanced mode only.
205. Validation Before Save
206. Diff View
Before activation.
207. Sensitive Fields
Masked/ref-only.
208. Feature Rollout UI
Shows:
state
cohort
percentage
owner
expiry
209. Kill Switch UI
Prominent, restricted.
210. Configuration Approval UI
Reuse human workflow.
211. API
Potential:
GET /v1/config/effective
GET /v1/config/history
POST /v1/config/validate
POST /v1/config/plan
POST /v1/config/apply
POST /v1/config/rollback
GET /v1/features
POST /v1/features/{id}/rollout
POST /v1/features/{id}/kill
212. Permissions
config.read
config.manage
config.apply
config.rollback
config.runtime_override
feature.read
feature.manage
feature.kill
213. Scope-Aware Permissions
Project admin cannot edit system config.
214. Config Read
Sensitive fields redacted.
215. Snapshot Export
Safe sanitized export.
216. Full Internal Snapshot
Higher permission.
217. No Secret Values Even Full Snapshot
Secret refs only.
218. Configuration Drift Types
#![allow(unused)]
fn main() {
pub enum ConfigDriftKind {
SnapshotMismatch,
RestartPending,
UnsupportedField,
FailedReload,
ExternalProviderDrift,
}
}
219. External Provider Drift
Example:
configured bucket policy vs actual
if adapter can inspect.
220. External Drift
Diagnostic only unless policy.
221. Config Reconciler
Checks desired/observed.
222. Retry
Dynamic reload idempotently.
223. Restart Required
Creates operational task/status, not automatic unsafe restart unless rollout policy.
224. Static Config Apply
Mode 2 rolling restart.
225. Standalone Static Change
Prompt restart/app restart.
226. Runtime Override Reconciliation
Expire and recompute.
227. Feature Flag Reconciliation
Expired rollout disables/defaults per declared policy.
228. Flag Expiry Behavior
Explicit:
#![allow(unused)]
fn main() {
pub enum FlagExpiryBehavior {
Disable,
Enable,
KeepCurrentAndWarn,
}
}
229. Recommended
Rollout flag -> Disable or stable target state explicitly.
230. No Ambiguous Expiry
231. Config Drift Notification
Notify admins for critical drift.
232. Kill Switch Notification
Immediate for security/production.
233. Audit Integration
Critical.
234. Search
Part 31 may index safe config metadata/history, not values.
235. Analytics
Examples:
flag age
override age
drift incidents
failed reload
236. No Tenant Sensitive Values in analytics.
237. Observability Metrics
config_activation_total
config_activation_failures_total
config_drift_components
config_reload_failures_total
feature_flag_evaluations_total
feature_killswitch_active
runtime_overrides_active
238. Labels
Low-cardinality:
component
result
scope_kind
239. No flag ID metrics if huge cardinality; analytics instead.
240. Tracing
config.load
config.validate
config.resolve
config.activate
config.reload
feature.evaluate
feature.rollout
241. Config Storage Security
Config metadata may contain internal infrastructure names.
242. At-Rest Encryption
Deployment-level.
243. Config Export
Permission gated.
244. Source-Controlled Config
Repository .forgeyard/*.ron.
245. Runtime System Config
Metadata DB.
246. Separation
Repository cannot overwrite system operational config.
247. Repository Config Trust
Untrusted project source.
248. Pipeline Config
Parsed/validated as source input.
249. System Config
Trusted admin plane.
250. Never Let Repository Config Enable Privileged Host Capability
Critical.
251. Example
Project may request:
GPU
network access
but cannot grant itself.
Policy/scheduler decide.
252. Config Request vs Config Grant
Separate.
253. Runner Config
Agent reports capabilities; admin config controls assigned trust/pool.
254. Runner Local Config
Bootstrap endpoints/certs.
255. Runner Cannot Self-Set Trust Class
Existing invariant.
256. Configuration as Evidence
Critical workflows can record ConfigSnapshotId.
257. Run
Store relevant config snapshot/reference.
258. Release
Store policy/config snapshots where semantics affect release.
259. Deployment
Runtime config exact revision/digest already required.
260. Cache
Config semantics version/key relevant where build behavior changes.
261. Reproducibility
Human config resolved to exact snapshot.
262. Config Change and Cache
Changing correctness-relevant config invalidates derivation/cache through ConfigDigest.
263. ConfigDigest
#![allow(unused)]
fn main() {
pub struct ConfigDigest(Digest);
}
264. Only Relevant Projection
Job cache key includes relevant config digest, not entire global config.
265. Avoid Unnecessary Cache Busting
Critical.
266. Config Dependency Declaration
Job/service declares config paths affecting semantics.
267. Unknown Config Dependency
Conservative: broader config digest.
268. Plugin Config Changes
Can invalidate plugin behavior/evidence.
269. Feature Flag and Cache
Runtime feature flags should generally not affect build cache unless explicitly part of build semantics.
270. Build Feature Flag
If it changes build output, it must enter derivation key.
271. UI-only Flag
Must not bust build cache.
272. Config Migration
Version N -> N+1.
273. Migration Function
Pure where possible.
274. Migration Output
New validated config snapshot.
275. No Destructive Silent Migration
276. Deprecated Fields
Warnings with replacement.
277. Removal
Major schema version.
278. N/N-1 Compatibility
For rolling upgrades.
279. Older Component
May not understand new field.
280. Activation Precheck
Ensure all required component versions understand snapshot.
281. Feature Activation After Upgrade
Same pattern as protocol feature activation.
282. Config Capability Matrix
#![allow(unused)]
fn main() {
pub struct ConfigCapabilityMatrix {
pub component: ComponentKind,
pub supported_schema: VersionRange,
pub supported_fields: BTreeSet<ConfigFieldPath>,
}
}
283. Rolling Upgrade Safety
Do not activate unsupported config mid-rollout.
284. Config Rollback After Upgrade
Only if compatible.
285. DR
Config snapshots/history backed up.
286. Bootstrap Config
Backed up separately.
287. Secret Values
Still in secret provider.
288. Restore
Restore config snapshots then active pointer.
289. Drift After Restore
Reconcile components.
290. Air-Gap
RON config + signed/verified snapshot export.
291. Config Bundle
#![allow(unused)]
fn main() {
pub struct ConfigBundle {
pub snapshot: ConfigSnapshotId,
pub schema: ConfigSchemaVersion,
pub manifest: CasObjectRef,
pub signature: Option<SignatureRef>,
}
}
292. Import
Validate schema/policy before activate.
293. Signing
Optional high-assurance.
294. Testkit
forgeyard-config-testkit/src/
├── lib.rs
├── layers.rs
├── validate.rs
├── snapshot.rs
├── reload.rs
├── drift.rs
├── migration.rs
└── assertions.rs
Feature:
forgeyard-feature-testkit/
295. Unit Tests
Layer precedence.
296. Protected Field Test
Tenant cannot override system field.
297. Secret Test
Secret value never appears in snapshot/export.
298. Dynamic Reload Test
Supported field updates without restart.
299. Static Field Test
Does not falsely report dynamic success.
300. Partial Apply Test
State becomes PartiallyApplied.
301. Drift Test
Component mismatch detected.
302. Reconcile Test
Dynamic component catches up.
303. Rollback Test
Restores previous immutable snapshot.
304. Migration Test
N->N+1 deterministic.
305. Old Component Compatibility Test
Unsupported field blocks activation.
306. Percentage Rollout Test
Stable subject bucketing.
307. Kill Switch Test
Immediate local evaluation after propagation.
308. Flag Expiry Test
Declared expiry behavior.
309. Runtime Override Expiry Test
Effective config recomputed.
310. Cache Config Digest Test
Only relevant config changes bust cache.
311. Repository Privilege Test
Project config cannot grant privileged host capability.
312. Tenant Isolation Test
Tenant config cannot affect another tenant.
313. Audit Test
Protected activation recorded.
314. DR Test
History/active snapshot restored.
315. Fuzzing
Fuzz:
RON parser boundary
config patch parser
migration decoders
feature flag evaluator inputs
316. Property Tests
Layer resolution deterministic.
317. Failure Injection
DB restart
reload worker crash
component unavailable
invalid secret ref
partial rollout
318. Scale Test
Many tenants/project overrides.
319. Implementation Phase 1 — Typed Config Domains
System/runtime/tenant/project.
320. Phase 2 — Layer Resolution/Explain
Core usability.
321. Phase 3 — Immutable Snapshots/History
Governance.
322. Phase 4 — Dynamic Reload/Drift
Runtime.
323. Phase 5 — Feature Flags
Staged rollout.
324. Phase 6 — Kill Switches
Incident control.
325. Phase 7 — Config Plan/Rollback
Operations.
326. Phase 8 — Tenant/Project Overrides
Multi-tenancy.
327. Phase 9 — Plugin Config Schemas
Extensions.
328. Phase 10 — Upgrade Compatibility Matrix
HA.
329. Phase 11 — Signed/Air-Gap Config Bundles
Enterprise.
330. Phase 12 — Scale/Fuzz/DR Hardening
Production readiness.
331. Acceptance Tests
- Forgeyard uses typed config domains rather than one giant untyped map.
- RON is primary human-authored config format.
- Environment variables map only to explicitly supported keys.
- Effective config is represented by immutable ConfigSnapshotId.
- Secret plaintext never appears in config snapshots.
- Each field declares scope/reloadability/sensitivity.
- Tenant/project layers cannot override forbidden system fields.
- Layer resolution is deterministic.
- Config explain shows effective source without leaking secrets.
- Candidate config is validated before activation.
- Active snapshot pointer changes atomically.
- Historical snapshots are never mutated.
- Dynamic settings reload idempotently.
- Static settings do not pretend to hot reload.
- Partial application is explicit.
- Component desired/observed snapshot drift is measurable.
- Reconciliation repairs dynamic config drift.
- Feature flags are not authorization or entitlement.
- Percentage rollout uses deterministic stable bucketing.
- Kill switches can disable risky functionality without code deploy.
- Kill-switch changes are audited/authorized.
- Temporary runtime overrides can expire automatically.
- Repository config cannot grant itself privileged capabilities.
- Build-affecting config enters derivation/cache semantics.
- UI-only config does not unnecessarily invalidate build cache.
- Config schema migration is versioned/tested.
- Rolling upgrade prechecks component config compatibility.
- Unsupported config is not activated during mixed-version rollout.
- Config history/active snapshot survive backup/restore.
- Air-gap config bundles are validated before activation.
- Plugin receives only its config namespace.
- Tenant config is isolated.
- Standalone/distributed share config semantics.
- CLI/UI expose plan/diff/history/rollback.
- Forgeyard dogfoods this configuration system for its own runtime.
332. Production Readiness Gates
Do not call configuration governance production-ready until:
typed schema/layering is stable
secret leakage tests pass
protected scope override rules pass
snapshot/history/rollback work
dynamic/static reload distinction is enforced
component drift detection works
feature rollout bucketing is deterministic
kill switch path is tested
mixed-version config compatibility is validated
backup/restore and air-gap config tests pass
333. Architectural Invariants
- effective behavior comes from typed validated config;
- config snapshots are immutable;
- active pointer is mutable, snapshot content is not;
- secrets are references only;
- layer precedence is deterministic;
- override scope is explicitly constrained;
- environment variables are allowlisted inputs, not universal config;
- static and dynamic settings are distinct;
- partial reload is never called fully applied;
- desired/observed config drift is first-class;
- feature flags are rollout controls, not security authority;
- entitlement/authz/policy remain separate;
- percentage rollout is stable/deterministic;
- kill switches are fast, scoped, authorized, and audited;
- temporary overrides should expire;
- repository config cannot self-grant privilege;
- config compatibility is checked during rolling upgrades;
- build-affecting config participates in derivation/cache identity;
- irrelevant config does not unnecessarily bust cache;
- config migration is versioned;
- plugin config is namespaced;
- secret fields never appear in exports;
- rollback points to previous immutable snapshot;
- config restore reconciles component drift;
- ordinary config does not live in Raft;
- dynamic propagation is idempotent/reconciled;
- standalone/distributed share semantics;
- config history is auditable;
- high-risk config can require approval;
- Forgeyard dogfoods its own configuration governance.
334. Final Target Architecture
Config Sources
│
┌────────────┼────────────┐
▼ ▼ ▼
Defaults RON DB Overrides
│ │ │
└────────────┼────────────┘
▼
Parse / Validate
│
▼
Layer Resolution
│
▼
ConfigSnapshotId
│
┌────────────┼────────────┐
▼ ▼ ▼
Dynamic Config Feature Flags Static Config
│ │ │
▼ ▼ ▼
Reload Evaluate Restart Plan
│ │ │
└────────────┼────────────┘
▼
Desired State
│
▼
Drift/Reconcile
335. Final Architectural Position
Configuration change:
base snapshot
+
typed patch
↓
validation
↓
policy/authz
↓
immutable candidate snapshot
↓
apply plan
↓
dynamic reload / restart / migration
↓
observed component convergence
Feature rollout:
FeatureFlagId
+
stable subject ID
+
rollout rule
+
seed
↓
deterministic decision
↓
entitlement/authz/policy still apply
Kill switch:
risk detected
↓
authorized kill-switch activation
↓
new immutable config/feature snapshot
↓
fast propagation
↓
reconciliation + audit
The key guarantee is:
Forgeyard can change runtime behavior safely without making production configuration mysterious or mutable in place. Every effective setting can be explained, every protected change has a versioned snapshot and audit trail, dynamic reload is used only where genuinely safe, and feature flags never replace the permanent security and policy architecture.
336. Extended Architecture Sequence
01 Core Domain & Foundation
02 Storage & Metadata
03 CAS & Artifact Data Plane
04 Pipeline IR / Parsing / Planning
05 Run / Job State Machine
06 Scheduler
07 Runner / Agent
08 Sandbox & Executor
09 Transport / QUIC / Protocol
10 Events / Reconciliation
11 Policy / Authorization / Identity
12 Secrets & Trust
13 Supply Chain / SBOM / Provenance / Signing
14 Packaging
15 Release
16 Deployment
17 Observability / Health / Doctor
18 API / Axum
19 Dioxus UI
20 Device Lab
21 SCM Provider Integrations
22 HA / Coordination / Raft
23 RBE Interop
24 Plugin / Extension Architecture
25 Operations / Backup / Upgrade / DR
26 Self-Hosting / Bootstrap / Release of Forgeyard
27 Multi-Tenancy / Quotas / Resource Governance
28 Audit / Compliance / Evidence Retention / Security Governance
29 Notifications / Alerting / Human Workflow
30 Entitlements / Licensing / Subscription / Commercial Access Control
31 Search / Indexing / Query / Operational Analytics
32 Test Results / Quality Gates / Coverage / Flaky-Test Intelligence
33 Benchmarking / Performance Regression / Load-Test / Capacity Intelligence
34 Monorepo Intelligence / Dependency Graph / Affected-Change / Incremental Execution
35 Developer Experience / Local Dev Environment / CLI Workflows / Reproducible Workstation
36 Dependency / Package Registry / Artifact Mirror / Software-Source Governance
37 Static Analysis / Code Quality / Security Scanning / Findings Management
38 Cache / Build Acceleration / Remote Cache / Cache Correctness
39 Configuration / Feature Flags / Runtime Settings / Dynamic Configuration Governance