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.