ADR-0009: Every option in one registry, set in a reviewed file, with a default
- Status: Proposed
- Date: 2026-10-06
- Deciders: Process maintainer
Context
Section titled “Context”The factory’s features (the driver, the chain, auto-merge, the reader, the models, the budgets, the deploy target, the nudge, the idea inbox) were each switched on a different surface in the estate it came from: some by enabling a workflow in the forge’s settings, some by a literal in a workflow file, some by a repository variable, some by a field in a plan. Nobody could list them, a new adopter could not find them, and a setting changed in a settings page left no trace in review. The owner’s rule is that every option ships with a default and that the person installing it is shown each default and how to change it later.
Decision
Section titled “Decision”- One registry,
factory/options.tsv. Every option has a key, a default, its choices, its scope (each service repo, or the ops repo), how it takes effect, whether onboarding asks it, one line on what it does, and how to change it later. The onboarding,xal-factory config, the defaults every seeded repo reads and the docs all read this one file. - Values live in
.xal/factory.conf, in the repo, reviewed like code. The seeder writes.xal/factory.defaultsfrom the registry; a repo sets only what differs..xal/is a protected path, so a driven session cannot widen its own autonomy. Unknown keys are refused, because a misspelt key that falls back to its default reads as configured and is not. - Two exceptions, stated:
runs-onandtimeout-minutesare evaluated before any step can read a file, so the runner stays theXAL_RUNNERrepository variable, recorded in the conf asci.runnerand applied by the CLI. - A switch is a key that also acts. An option whose
applyisworkflow:<file>is enforced by that workflow being enabled or disabled;xal-factory applymakes the forge match the conf, anddoctorreports any difference. Disabled workflows stay committed, so their fixtures keep proving them. - The ops repo’s conf is the factory profile. Service options set there are the starting
values for every service
xal-factory seedcreates. - Auto-merge off is a disabled
merge.yml, not an unset level. The driver refusesautonomy_level: unset(ADR-0008), so withpipeline.auto_merge = offthe planner writescode-onlyand the merge workflow is disabled.
Consequences
Section titled “Consequences”- Gate 11 holds the registry whole: every default valid, every key a script reads registered, every registered key read by something shipped.
- A repo seeded before an option existed does not know it, which is the seed model: the repo
owns what it was seeded with, and
xal-factory doctornames what it lacks. - A plan’s values are copied from the conf at planning time and approved with the plan, so a conf change applies to plans emitted afterwards, never to an approved one.