docs(adr): ADR 0103 — shared configuration as recorded presets bumped by Renovate - #6976
docs(adr): ADR 0103 — shared configuration as recorded presets bumped by Renovate#6976waynesun09 wants to merge 2 commits into
Conversation
…d update Per-repo is the only installation mode (ADR 0044) and the org config tier it removed has no working replacement: config.base.yaml presets record no provenance, agent update skips base: pins and lock.yaml (#5433, #5802), nothing checks pins in CI (#6191), and repos install has no preset concept. The fullsend-ai org bridges this with sync workflows (sed + direct push via a ruleset-bypass App, always agents main HEAD, stale hashes on non-harness paths) that replaced a working Renovate custom manager. Decide: shared configuration is a versioned preset hosted in any repo, recorded per repo in a bot-owned .fullsend/preset.lock.yaml, and bumped by each repo's Renovate job. fullsend ships a Renovate preset with custom managers for its pin formats and runs one idempotent `fullsend update` as the post-upgrade task (re-fetch preset, recompute #sha256=, regenerate lock.yaml). Tracking strategy and cadence are Renovate packageRules, minimumReleaseAge and schedule. No dedicated org repo, no org-level sync workflow, no enrollment list. Human-owned files are never written by the verb; bot-owned files are rewritten whole, so there is no three-way merge and no compile step. Verified on a live per-repo install in nonflux (fullsend-adr0103-preset, fullsend-adr0103-repo-a): one Renovate PR re-pinned agents[].source, the harness base: URL and the shim with recomputed hashes and lock; preset bumps touched only config.base.yaml and preset.lock.yaml. Prerequisites, not decided here: the dispatch Route job reads only config.yaml, and agent add/update/remove write the merged list into the overlay (must land before a preset ships agents). Annotates ADR 0003, 0044 and 0069; updates architecture.md and the governance and agent-infrastructure problem docs. Assisted-by: Claude (draft, coordination) Assisted-by: Claude gh-c-1/gh-c-2/gh-c-3 (research, walkthrough) Signed-off-by: Wayne Sun <gsun@redhat.com>
PR Summary by QodoDocument Renovate-converged shared configuration presets
AI Description
Diagram
High-Level Assessment
Files changed (7)
|
|
🤖 Review · ❌ Terminated · Started 5:01 PM UTC · Ended 5:43 PM UTC Commit: |
Code Review by Qodo
1. ADR 0103 bundles multiple decisions
|
| 1. **A preset is a git-hosted `config.base.yaml`** plus the harness bases, | ||
| skills and policies it references by URL, schema-validated on fetch. It | ||
| lives in whichever repo already hosts the org's shared Renovate config; | ||
| no dedicated org repo, no org-level workflow and no enrollment list are |
There was a problem hiding this comment.
1. Adr 0103 bundles multiple decisions 📜 Skill insight ⚙ Maintainability
The Decision section separately establishes the preset format, file ownership, Renovate integration, update behavior, and tracking policy. These independent decisions must be split rather than recorded in one ADR.
Agent Prompt
## Issue description
ADR 0103 records multiple distinct decisions in one Decision section.
## Issue Context
The preset model, ownership boundaries, Renovate integration, update command behavior, and tracking policy should be separated into focused ADRs or reduced to one architectural decision with non-decision details moved elsewhere.
## Fix Focus Areas
- docs/ADRs/0103-shared-config-presets-converged-by-fullsend-update.md[59-98]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| > **Note (2026-09-03):** Per-org installation is deprecated | ||
| > ([ADR 0044](0044-deprecate-per-org-installation-mode.md)). A dedicated | ||
| > `<org>/.fullsend` repo is no longer required: shared configuration is a | ||
| > preset hosted in any repo and bumped per consuming repo by Renovate | ||
| > ([ADR 0103](0103-shared-config-presets-converged-by-fullsend-update.md)). |
There was a problem hiding this comment.
6. Adr 0003 edit undisclosed 📘 Rule violation § Compliance
The PR modifies accepted ADR 0003, but the PR description does not identify ADR 0003 or summarize this new superseding note. Accepted ADR edits must be explicitly called out in the PR description.
Agent Prompt
## Issue description
Add ADR 0003 and a summary of its annotation to the PR description.
## Issue Context
The accepted ADR now notes that a dedicated organization configuration repository is no longer required and links ADRs 0044 and 0103.
## Fix Focus Areas
- docs/ADRs/0003-org-config-repo-convention.md[25-29]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| > **Note (2026-09-03):** Preset provenance (a bot-owned | ||
| > `.fullsend/preset.lock.yaml`) and the refresh path (Renovate running | ||
| > `fullsend update` as a post-upgrade task) are decided in | ||
| > [ADR 0103](0103-shared-config-presets-converged-by-fullsend-update.md). |
There was a problem hiding this comment.
7. Adr 0069 edit undisclosed 📘 Rule violation § Compliance
The PR modifies accepted ADR 0069, but the PR description does not identify ADR 0069 or summarize its new provenance and refresh-path note. Accepted ADR edits must be explicitly called out in the PR description.
Agent Prompt
## Issue description
Add ADR 0069 and a summary of its annotation to the PR description.
## Issue Context
The accepted ADR now points preset provenance and refresh behavior to ADR 0103.
## Fix Focus Areas
- docs/ADRs/0069-ready-made-configuration-presets.md[22-25]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Site previewPreview: https://92820f53-site.fullsend-ai.workers.dev Commit: |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
🤖 Finished Review · ❌ Failure (validation failed after 2 iteration(s)) · Started 5:01 PM UTC · Completed 5:43 PM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high |
|
I don't know if I agree or not because I don't fully understand why is this needed. Do we want to lock up stuff more? Do we want stuff to auto-update (hence the Renovate config)? Did we have a problem with tracking where things come from? It is really needed? Also simplify the wording, it is exhausting to read (there is phrase with 57 words). |
Short sentences, motivation first, one-sentence consequences, under 100 content lines. Restore the original architecture bullet and add a one-line decided statement; make architecture.md, governance.md and agent-infrastructure.md say what the ADR says (Renovate bumps the pins, the verb refreshes only tooling-owned files, any repo may host the preset). Assisted-by: Claude (draft) Signed-off-by: Wayne Sun <gsun@redhat.com>
|
Thanks — fair on both counts. Pushed
|
|
🤖 Finished Review · ✅ Success · Started 2:54 PM UTC · Completed 3:35 PM UTC Commit: Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $5.20 |
|
Risk Assessment: low (1/5) DetailsPure documentation PR adding ADR 0103 and cross-referencing existing ADRs — no source code, no protected paths, no security-sensitive files, no dependency changes; the only notable signal is docs/architecture.md being a high-churn file, but the change is a 5-line addition, keeping overall risk minimal. |
ReviewFindingsLow
Next steps:
|
| Per-repo installation mode ([ADR 0033](0033-per-repo-installation-mode.md)) | ||
| becomes the sole supported installation model. | ||
|
|
||
| > **Note (2026-09-03):** The "no centralized policy" and "per-repo setup |
There was a problem hiding this comment.
[low] internal consistency
Two annotations added in the same PR give inconsistent impressions of how completely ADR 0103 resolves the 'no centralized policy' cost. The ADR 0044 annotation says both costs 'are decided in recorded presets and fullsend update,' implying full resolution. The governance.md annotation in the same PR correctly qualifies: 'enforcing a policy floor remains open.' ADR 0103 itself confirms enforcement is out of scope: 'Refusing to run when a repo drifts from its preset is a separate decision; this ADR only makes drift visible.' Additionally, the verb 'decided' is imprecise when applied to 'costs' — costs are not 'decided in' a mechanism; they are 'addressed by' or 'mitigated by' one.
Suggested fix: Reword the annotation to: '> Note (2026-09-03): The "no centralized policy" and "per-repo setup overhead" costs listed below are partially addressed by recorded presets and fullsend update (ADR 0103); enforcing a policy floor remains open.' This aligns with the governance.md annotation in the same PR and uses a semantically correct verb.
Summary
Organizations want one shared agent configuration for many repos, with each repo picking up updates automatically the way Renovate already bumps packages and Actions pins. Per-repo installation (ADR 0044) removed the org config repo that used to do this and left nothing in its place. The building blocks exist but do not connect:
config.base.yamlpresets record no provenance,agent updatedoes not re-pinbase:or regeneratelock.yaml(#5433, #5802), nothing checks pins in CI (#6191), andrepos installdoes not know presets. The fullsend-ai org fills the gap withsync-agent-digests.yml/sync-scaffold.yml(sed + direct push through a ruleset-bypass App, alwaysmain, stale hashes outsideharness/), which replaced a Renovate custom manager that did the bump correctly but ran in one repo (fullsend-ai/.fullsend#174).Decision (ADR 0103): shared configuration is a preset — a versioned
config.base.yamlin any repo — recorded in each consuming repo in a tooling-owned.fullsend/preset.lock.yamland bumped by that repo's own Renovate job. fullsend ships a Renovate preset withcustom.regexmanagers for the preset record,agents[].sourceURLs and harnessbase:URLs, and one idempotentfullsend updatethat Renovate runs as its post-upgrade task (refreshconfig.base.yaml, recompute#sha256=, regeneratelock.yaml). Which ref to track,minimumReleaseAgeandscheduleare ordinary RenovatepackageRules. Humans ownconfig.yamland local harnesses; tooling never writes them, so there is no three-way merge and no compile step. No dedicated org repo, no org-level workflow, no enrollment list.Verified on a live install
nonflux throwaway repos (
fullsend-adr0103-presettagged v1/v2/v3,fullsend-adr0103-repo-aconsumer), CLI from48eac1aee, self-hosted Renovate 44.61.3:github setup --config <raw url @v1> --config-hashlandedconfig.base.yamlbyte-identical to the tag.agents[].sourceentry and the harnessbase:URL with recomputed#sha256=and a regeneratedlock.yaml; the built-ingithub-actionsmanager bumped both shim workflows in the same job.config.base.yaml+preset.lock.yaml;config.yamlnever changed.agent addcopied a preset-only entry intoconfig.yaml, where it shadows the preset — hence the prerequisite below.Hashes re-verified independently. Research with pinned sources: https://github.com/waynesun09/ai-workspace-public/blob/main/research/fullsend-shared-config-at-scale.md
Prerequisites (not decided here; to be filed as issues)
.fullsend/config.yaml, so a preset'skill_switch/roles/agents[].enabledare ignored for built-in stages and a preset-only agent never dispatches (Route job should inherit org-level agent enabled/disabled when per-repo config omits agents key #6422's class).agent add/update/removewrite the merged agent list back into the overlay, freezing preset entries there. Must land before any preset ships agents; the file is currently owned by feat(cli):fullsend agent new— generate a complete custom agent from minimal parameters #6966.Edits to accepted ADRs and living docs (called out per the ADR conventions)
<org>/.fullsendrepo is no longer required; links ADR 0044 and 0103.preset.lock.yaml) and the refresh path (Renovate runningfullsend update) are decided in ADR 0103.docs/architecture.md— one new decided bullet plus a two-line addition to the per-repo inheritance paragraph; the existing preset bullet is unchanged.docs/problems/governance.md,docs/problems/agent-infrastructure.md— one-line cross-references to ADR 0103.Closes on implementation (follow-up PRs): #5433, #5802, #6191. Related: #6422, #6597, #6607, agents#983.
Assisted-by: Claude (draft, coordination), Claude gh-c-1/gh-c-2/gh-c-3 (research, walkthrough)