Skip to content

69. Ready-made configuration presets for simplified installation ​

Date: 2026-06-29

Status ​

Accepted

Context ​

fullsend github setup today spreads installation decisions across many CLI flags (--mint-url, --inference-project, --inference-region, and others) and separate enrollment steps: operators run fullsend mint enroll to register repos with the token mint, and the installer provisions inference WIF infrastructure via the inference layer (ADR 0033, ADR 0029). The all-in-one fullsend admin install command is deprecated in favor of fullsend github setup.

Per-repo configuration lives in .fullsend/config.yaml within the target repository (ADR 0033), but key runtime settings (mint endpoint, inference backend) are only partially represented there; much of the effective configuration still comes from flags and ephemeral provisioning. That makes repeatable, vendor-curated installs harder than they need to be.

ADR 0064 deprecates the customized/ directory overlay; config.base.yaml is the successor mechanism for distributing a shared baseline into each target repo's .fullsend/.

This ADR applies only to per-repo installation. Per-org installation via a dedicated <org>/.fullsend config repo is deprecated and out of scope (ADR 0044).

ADR 0029 already treats job_workflow_ref as the trust binding for mint authorization. Shared-infrastructure mint workflow pinning and job_workflow_ref validation are decided in ADR 0059. How shared inference backends authorize callers — for example via job_workflow_ref, org/repo allowlists on inference WIF, or streamlined enrollment rather than full per-repo provisioning — is undecided and left to follow-on ADRs. This ADR does not presuppose that inference follows the mint public-mode model.

Options ​

  • Flags only (status quo): Flexible for advanced operators, but every adopter must understand mint and inference provisioning details.
  • Single monolithic config.yaml: Simpler than flags, but mixes vendor-provided defaults with repo-specific overrides and complicates upgrades of the preset layer.
  • Layered base + overlay files (chosen): Separate vendor baseline (.fullsend/config.base.yaml) from repo overrides (.fullsend/config.yaml), resolved through accessor methods. Supports preset distribution and clean upgrades.

Decision ​

1. Move installation settings into configuration files. Mint URL, inference provider and backend parameters, and other values currently supplied via CLI flags belong in the per-repo configuration under .fullsend/. The installer reads configuration instead of reconstructing it from flags. Decision 1 applies to fullsend github setup (single-repo install). The ADR 0057 bulk manifest path (fullsend repos install / sync) remains a distinct operator mechanism using GitHub Secrets and Variables until a follow-on change migrates it to per-repo config files.

2. Layered configuration with accessor-based lookup. Configuration is stored in the target repository as:

  • .fullsend/config.base.yaml — the base layer (vendor preset or repo baseline).
  • .fullsend/config.yaml — the user overlay for repo-specific customization.

Relationship to the three-tier model. ADR 0003 and docs/architecture.md describe configuration inheritance as upstream defaults, then org .fullsend, then per-repo overrides. Per-repo installation is the sole supported deployment model; the dedicated org config repo is deprecated (ADR 0044). config.base.yaml in each target repo fills the org tier's former configuration role — not a revival of per-org installs. A vendor preset committed as config.base.yaml can be reused across repos in one org or distributed unchanged across org boundaries without a separate <org>/.fullsend repository. config.yaml remains the per-repo overlay. Lookup order is overlay → base → code defaults in internal/config (and related packages): values not set in either file still resolve from compiled-in defaults, as today. Accessor methods implement that full chain; direct struct field access does not.

All runtime and installer lookups go through methods on a configuration accessor (for example MintURL(), InferenceProvider()), not direct struct field access. Each accessor implements its own merge and fallback rules across layers (scalar override, deep merge, or required-in-overlay semantics as appropriate). The design must allow additional file layers beyond base + overlay in the future without changing call sites.

3. --config install flag for ready-made presets. fullsend github setup accepts --config <path-or-url> and optional --config-hash <sha256>. The installer:

  1. Fetches or reads the preset document. When --config-hash is supplied, the installer validates fetched content against that hash; signing and preset URL allowlisting are deferred to a follow-on ADR.
  2. Commits it as .fullsend/config.base.yaml in the target repository.
  3. Writes a stub .fullsend/config.yaml containing only comments and empty or minimal override fields for the adopter to customize.

Presets may be local files or HTTPS URLs. The flag is optional; advanced installs that assemble configuration manually remain supported.

4. Reduce per-adopter enrollment for shared infrastructure (target state). When a preset targets shared infrastructure, the installer should minimize install-time backend registration. For mint, workflow pinning and job_workflow_ref validation are decided in ADR 0059. For inference, follow-on ADRs will choose among authorization models (which may include job_workflow_ref pinning, org/repo-scoped inference WIF allowlists with streamlined enrollment, or continued explicit provisioning for self-managed paths). Until those ADRs land, preset-based installs continue requiring inference enrollment and WIF provisioning where applicable.

Consequences ​

  • Common installs become a single command with a preset URL instead of a long flag list plus separate mint and inference enrollment steps.
  • The internal/config package gains a layered accessor API; direct field reads outside that package become a lint or review violation.
  • Preset upgrades can refresh .fullsend/config.base.yaml while preserving repo edits in .fullsend/config.yaml, provided merge semantics are documented per field.
  • Existing installations without config.base.yaml remain valid — accessors treat a missing base file as an empty layer, falling through to code defaults.
  • Preset URLs are a supply-chain trust surface; signing and preset URL allowlisting are follow-on concerns (--config-hash validation is in scope for --config installs).
  • Self-managed and air-gapped deployments keep working via hand-authored configuration or flags that bypass shared presets.
  • Mint operators shift from per-repo onboarding to backend policy (workflow allowlists per ADR 0059). Inference operator policy and install-time enrollment shape remain open; security review for shared presets covers preset curation regardless of which inference authorization model is chosen.