Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/ADRs/0003-org-config-repo-convention.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ Date: 2026-03-25

Accepted

> **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)).
Comment on lines +25 to +29

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

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


## Context

An organization adopting fullsend must configure it: the intent repo, the
Expand Down
4 changes: 4 additions & 0 deletions docs/ADRs/0044-deprecate-per-org-installation-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ Deprecates the per-org installation mode established in
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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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.

> overhead" costs listed below are decided in recorded presets and
> `fullsend update` ([ADR 0103](0103-shared-config-presets-converged-by-fullsend-update.md)).

## Context

Fullsend's original installation model is per-org: `fullsend admin install <org>`
Expand Down
5 changes: 5 additions & 0 deletions docs/ADRs/0069-ready-made-configuration-presets.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ Date: 2026-06-29

Accepted

> **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).
Comment on lines +22 to +25

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

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


## Context

`fullsend github setup` today spreads installation decisions across many CLI
Expand Down
105 changes: 105 additions & 0 deletions docs/ADRs/0103-shared-config-presets-converged-by-fullsend-update.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
---
title: "103. Shared configuration as recorded presets bumped by Renovate"
status: Accepted
relates_to:
- governance
- agent-infrastructure
topics:
- configuration
- installation
- distribution
- presets
---

# 103. Shared configuration as recorded presets bumped by Renovate

Date: 2026-09-03

## Status

Accepted

<!-- ADRs are point-in-time records, but not fully frozen after acceptance.
Minor annotations are welcome: cross-references to related ADRs, short
notes linking to newer decisions, or clarifying remarks. However, do not
substantially rewrite the Context, Decision, or Consequences sections. If
the decision itself needs to change, write a new ADR that supersedes this
one. For evolving design narrative, use docs/architecture.md. -->

## Context

An organization wants one shared agent configuration for many repos, and
wants each repo to pick up updates automatically, the way Renovate already
bumps its packages and GitHub Actions pins. Per-repo installation
([ADR 0044](0044-deprecate-per-org-installation-mode.md)) removed the org
config repo that used to do this and left nothing in its place.

The building blocks exist but do not connect. A shared
`config.base.yaml` can be installed with `github setup --config`
([ADR 0069](0069-ready-made-configuration-presets.md)), but nothing records
where it came from, so nothing can refresh it. Agent pins carry a commit
SHA and a `#sha256=` hash, but `agent update` does not re-pin `base:` in
local harness files and does not regenerate `lock.yaml` (#5433, #5802).
No command checks pins in CI (#6191). `repos install`
([ADR 0074](0074-repos-command-consolidation.md)) does not know presets.

Today the fullsend-ai org fills the gap with a workflow that `sed`-rewrites
`config.yaml` in a hard-coded list of repos and pushes to `main` through a
ruleset-bypass App. It always tracks `main`, offers no review, and leaves
stale hashes on any path outside `harness/`. It replaced a Renovate custom
manager that did the bump correctly but ran in only one repo
(fullsend-ai/.fullsend#174). Two readers also ignore the base layer and
are fixed as prerequisites, not decided here: the dispatch Route job reads
only `config.yaml` (#6422's class), and `agent add/update/remove` copy
preset entries into `config.yaml`, where they shadow the preset.

## Decision

Shared configuration is a **preset**: a versioned `config.base.yaml` in
any repo, recorded in each consuming repo by provenance, and bumped by that
repo's own Renovate job.

1. **Preset.** The preset is a `config.base.yaml` plus the harness bases,
skills and policies it references by URL. It lives in whichever repo
hosts the org's shared Renovate config. There is no dedicated org repo,
no org-level workflow and no enrollment list.
2. **Two kinds of files.** Humans own `config.yaml` and local harness
files. Tooling owns `config.base.yaml` (a byte-identical copy of the
preset), `lock.yaml`, the shim, and a new `.fullsend/preset.lock.yaml`
whose `source` URL names the preset and its tracked ref; the resolved
SHA and `sha256` are derived from it. Tooling never writes the human
files. That split is why no three-way merge and no compile step are
needed.
3. **Renovate bumps the pins.** fullsend ships a Renovate preset with
`custom.regex` managers for the preset record, `agents[].source` URLs
and harness `base:` URLs (never `config.base.yaml`). A repo's
`renovate.json` extends it. Renovate's built-in `github-actions` manager
already bumps the shim.
4. **`fullsend update` does the rest.** Renovate runs it as the
`postUpgradeTasks` command. It re-fetches the preset into
`config.base.yaml`, recomputes every `#sha256=`, and regenerates
`lock.yaml` without re-resolving unchanged dependencies. Run by hand it
also bumps the shim ref. `--check` writes nothing and exits non-zero on
drift from a tag or SHA. `repos install` applies the preset on a fresh
install.
5. **Policy is Renovate's.** Which ref to track, how long to wait
(`minimumReleaseAge`) and how often to run (`schedule`) are ordinary
Renovate `packageRules`, shared through the org's Renovate preset.

Repos with no explicit `agents:` entry follow the fullsend build tag for
first-party agents, so the shim bump is their agent bump. Agents generated
by `fullsend agent new` (#6966) are local files and are left alone.

## Consequences

- Agent and preset bumps arrive as ordinary Renovate pull requests, and the
fullsend-ai sync workflows are retired.
- #5433, #5802 and #6191 close on the verb; #6597 and #6607 become
Renovate policy.
- `postUpgradeTasks` needs self-hosted Renovate with an anchored
`allowedCommands` entry, so a repo without Renovate runs `fullsend
update` by hand.
- The preset URL is a supply-chain trust surface covered by
`allowed_remote_resources` and `--config-hash`; signing is a follow-on.
- Refusing to run when a repo drifts from its preset is a separate
decision; this ADR only makes drift visible.
5 changes: 5 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ the dedicated org-level `<org>/.fullsend` config repo is deprecated
- Multi-repo management: a `fullsend repos` subcommand group with a declarative `repos.yaml` manifest for managing per-repo installations at scale — install, convergence (provision, sync, upgrade), status, and uninstall across repos and orgs ([ADR 0057](ADRs/0057-repos-management.md), [ADR 0074](ADRs/0074-repos-command-consolidation.md)).
- Dispatch version-skew resolution: per-repo `reusable-dispatch.yml` inlines stage workflow jobs directly, eliminating `@v0` references to `reusable-{stage}.yml` ([ADR 0062](ADRs/0062-dispatch-version-skew.md)).
- Ready-made configuration presets: `fullsend github setup --config <path-or-url>` installs a vendor preset as `.fullsend/config.base.yaml` and a stub `.fullsend/config.yaml` overlay in the target repository; mint URL, inference backend, and related settings live in configuration files resolved through accessor methods, not CLI flags. Shared-infrastructure presets will reduce per-adopter enrollment (target state): mint via `job_workflow_ref` trust per [ADR 0059](ADRs/0059-public-mint-mode-with-wildcard-allowlists.md); inference authorization model undecided ([ADR 0069](ADRs/0069-ready-made-configuration-presets.md)); enrollment remains required until follow-on ADRs land.
- Shared presets bumped by Renovate: a bot-owned `.fullsend/preset.lock.yaml` records the preset's source and tracked ref; Renovate custom managers bump the preset record, `agents[].source` and harness `base:` pins, and run `fullsend update` as a post-upgrade task to refresh `config.base.yaml`, recompute hashes and regenerate `lock.yaml` ([ADR 0103](ADRs/0103-shared-config-presets-converged-by-fullsend-update.md)).
- GitLab event dispatch: two-path model — native CI triggers (`merge_request_event`) for MR events, cron-based polling for issues/comments/labels. No external infrastructure (no webhook bridge). Bot PAT stored as a protected CI/CD variable. Per-repo only ([ADR 0067](ADRs/0067-gitlab-cron-polling-event-dispatch.md)).

**Open questions:**
Expand Down Expand Up @@ -533,6 +534,10 @@ Fullsend uses a three-tier configuration inheritance model for all configuration
In per-repo installation the middle tier is replaced by files inside the
target repo: `.fullsend/config.base.yaml` (vendor preset or baseline) and
`.fullsend/config.yaml` (repo overlay), with code defaults below both. The
preset may live in any repo; Renovate bumps its pins and `fullsend update`
refreshes the tooling-owned files (`config.base.yaml`, `preset.lock.yaml`,
`lock.yaml`), never `config.yaml` or local harness files
([ADR 0103](ADRs/0103-shared-config-presets-converged-by-fullsend-update.md)). The
org-tier box above describes the historical per-org model, now deprecated
([ADR 0044](ADRs/0044-deprecate-per-org-installation-mode.md),
[ADR 0069](ADRs/0069-ready-made-configuration-presets.md)).
Expand Down
2 changes: 1 addition & 1 deletion docs/problems/agent-infrastructure.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ Many fullsend scenarios skew toward **ephemeral, task-scoped** execution (triage

- **Agent architecture** — Instance topology (per-repo vs shared) and “local vs remote” for pre-PR review depend on what infrastructure we have. Infrastructure enables or constrains those choices.
- **Security threat model** — Isolation and “separate execution environments” are implemented by this layer. Supply chain (what base images and dependencies the runtime uses) also lives here.
- **Governance** — Policy may be applied at runtime by agents reading from a policy repo; infrastructure determines where that runtime runs and how it accesses policy.
- **Governance** — Policy may be applied at runtime by agents reading from a policy repo; infrastructure determines where that runtime runs and how it accesses policy. Shared configuration reaches per-repo installs as a recorded preset bumped by Renovate ([ADR 0103](../ADRs/0103-shared-config-presets-converged-by-fullsend-update.md)); the same pinned-remote-reference model maps onto Tekton remote resolution if stages later run there.
- **Repo readiness** — Repos need reliable CI and signals; agent infrastructure may consume or depend on the same CI (e.g. for “run tests” or “run linters”) and should not conflict with it. Headless runtimes amplify **feedback latency** and **workspace handoff** costs when CI is the only execution path.

## Open questions
Expand Down
2 changes: 1 addition & 1 deletion docs/problems/governance.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Agent configuration is itself a security-critical attack surface. If someone can

**Open design questions:**
- Where does agent policy live? In the repos it governs (as CLAUDE.md, agent config files)? In a separate policy repo? In a central configuration system?
- If policy lives in a separate repo, how does it get applied to target repos? Push-based (policy repo pushes to targets) or pull-based (agents read from policy repo at runtime)?
- If policy lives in a separate repo, how does it get applied to target repos? Push-based (policy repo pushes to targets) or pull-based (agents read from policy repo at runtime)? (Push-based as Renovate pull requests, from a preset hosted in any repo — decided in [ADR 0103](../ADRs/0103-shared-config-presets-converged-by-fullsend-update.md); agents still read the merged layers at runtime, and enforcing a policy floor remains open.)
- How do we audit changes to agent configuration? Git history helps if policy is in git, but we also need to detect unauthorized runtime changes.
- How do we handle the bootstrap problem — who sets up the initial agent configuration for a new repo, and how is that initial setup secured? (Preset-based install and `config.base.yaml` / `config.yaml` layering decided in [ADR 0069](../ADRs/0069-ready-made-configuration-presets.md); workflow pinning and backend policy remain open.)

Expand Down
Loading