diff --git a/docs/ADRs/0003-org-config-repo-convention.md b/docs/ADRs/0003-org-config-repo-convention.md new file mode 100644 index 0000000000..352902af23 --- /dev/null +++ b/docs/ADRs/0003-org-config-repo-convention.md @@ -0,0 +1,273 @@ +--- +title: "3. Org-level configuration lives in a conventional repo" +status: Proposed +relates_to: + - governance + - codebase-context + - intent-representation + - architectural-invariants + - agent-architecture + - agent-infrastructure +topics: + - configuration + - adoption + - convention +--- + +# 3. Org-level configuration lives in a conventional repo + +Date: 2026-03-25 + +## Status + +Proposed + +## Context + +An organization adopting fullsend must configure it: the intent repo, the +architecture documentation, runtime and model, infrastructure, sandbox +defaults, org-specific agents and skills, and per-repo overrides. (See issue +#75.) + +Today no conventional location exists. Without one, every tool must be told +where to find config, or each tool invents its own convention. + +## Options + +### Option 1: `/.fullsend` repo + +Each adopting organization creates a repo named `.fullsend` in their org or +group (GitHub org, GitLab group, Forgejo org, or equivalent) — the single +entry point for all fullsend configuration. + +The dot-prefix mirrors `.github` for org-level configuration, signaling +"infrastructure/meta" rather than application code. The name avoids collisions +with other tooling. + +**Pros:** +- Clean, memorable convention. Tooling looks in exactly one place. +- Org-owned — the adopting org controls configuration, permissions, and review. +- Decoupled from fullsend's release cycle. +- Dot-prefix follows an established pattern (`.github`, `.gitlab`). +- CODEOWNERS enforces appropriate approval on configuration changes. + +**Cons:** +- Dot-prefixed repos sort differently and sometimes hide in forge UIs. +- Adopters must learn a new convention. +- Dot-prefix visibility varies across platforms. + +### Option 2: `/fullsend-config` repo + +Same as Option 1, without the dot-prefix. + +**Pros:** +- Appears in normal alphabetical listings on all forges. +- Name is self-documenting. + +**Cons:** +- Lacks the dot-prefix signal for "meta/infra." +- Slightly more generic name; collision unlikely but possible. + +### Option 3: Configuration inside an existing platform meta-repo + +Put fullsend configuration in a subdirectory of the org's existing platform +meta-repo (GitHub's `.github` or equivalent). GitLab and Forgejo lack an +equivalent convention — itself a problem with this option. + +**Pros:** +- No new repo on platforms that already have a meta-repo. +- Permissions may already exist. + +**Cons:** +- Mixes concerns. Meta-repos serve issue templates, CI config, and community + health files; adding agent configuration overloads their purpose. +- Tooling must look inside a subdirectory of a multi-purpose repo. +- CODEOWNERS for fullsend config must coexist with other CODEOWNERS rules. +- Growing fullsend config (agents, skills, workflows) would dominate the + meta-repo. +- Not portable: GitHub's `.github` has no equivalent on GitLab or Forgejo. + +### Option 4: External configuration management system + +Use a runtime configuration store (Consul, etcd, HashiCorp Vault, AWS +Parameter Store) as the source of truth for org-level config. + +**Pros:** +- Purpose-built for configuration: dynamic updates, access control, secret + storage. +- Some organizations already run these systems. + +**Cons:** +- Breaks the "everything auditable in version control" principle — no PR + review, no CODEOWNERS, no merge history. +- Introduces infrastructure dependencies that vary across environments. +- Each store has its own API, auth model, and operational requirements. +- Config changes bypass the review and governance processes fullsend relies + on. +- Structural configuration (agents, workflows, intent repo location) belongs + in version control; only secrets and dynamic runtime values belong in + systems like Vault. + +### Option 5: Forge-native org/group settings + +Store fullsend configuration in the forge's own org-level settings (GitHub +org settings API, GitLab group variables, Forgejo org settings). + +**Pros:** +- No additional repo or system. + +**Cons:** +- Opaque: no version control, no merge-request review, no audit trail + beyond platform logs. +- Each platform exposes different settings APIs; a model that works on + GitHub may not map to GitLab or Forgejo. +- Key-value or flat structures lack the expressiveness for agent + definitions, workflow overrides, or layered inheritance. +- Platform admin permissions govern changes, not CODEOWNERS-style + path-level review. + +### Option 6: Hosted control plane / SaaS + +A hosted web service where orgs configure fullsend via a UI or API. + +**Pros:** +- Could offer a polished experience with validation, previews, and guided + setup. + +**Cons:** +- Introduces a central dependency the org does not control. +- Moves configuration out of version control — no PR review, no CODEOWNERS, + no git history. +- Creates a high-value attack target: compromising the control plane + compromises every org. +- Contradicts fullsend's design philosophy: the repo is the coordinator, + not a service. + +### Option 7: Configuration inside the fullsend repo itself + +Each adopting org gets a directory in the fullsend repo (e.g., `orgs/nonflux/`). + +**Pros:** +- Everything in one place; maintainers see all adopters. + +**Cons:** +- Couples org config to fullsend's release cycle and permissions. +- Orgs cannot modify config without a PR to fullsend. +- Violates the principle that org config is org-owned. +- Conflates the framework with its instances. + +## Decision + +Adopting organizations create a **`/.fullsend`** repo as the conventional +location for all org-level fullsend configuration. + +This repo is the root of the dependency graph for fullsend in an org. All +tooling — harness, trigger layer, agent runtimes, drift scanners — starts here. +The convention is: + +1. **Tooling looks for `/.fullsend`** to bootstrap. If the repo exists, + the org has adopted fullsend. If not, there is nothing to configure. +2. **The `.fullsend` repo points to everything else:** the intent repo, + architecture repo, infrastructure config, agent definitions, workflow + definitions, sandbox profiles, and per-repo overrides. +3. **The adopting org governs the `.fullsend` repo.** Its CODEOWNERS, branch + protection, and review requirements follow the org's governance model. + Changes here are governance-level changes (see + [governance.md](../problems/governance.md) — configuration security). +4. **Agents cannot modify this repo.** The `.fullsend` repo defines agent + behavior; agents must not modify their own configuration. Enforcement: + exclude bot/service accounts from write access and require human approval + via CODEOWNERS on all paths. This aligns with the principle that CODEOWNERS + files are always human-owned. + +### Repo structure (initial) + +``` +.fullsend/ + config.yaml # Top-level org configuration + guardrails.yaml # Org-wide guardrails (separate file for CODEOWNERS) + agents/ # Org-specific agent definitions (extends base set) + skills/ # Org-specific skills (extends base set) + workflows/ # Workflow overrides/extensions + repos/ # Per-repo configuration overrides + .yaml +``` + +The `config.yaml` contains pointers and org-wide defaults. This repo holds +structural configuration only; secrets (API keys, credentials) are managed +separately via the org's secret management system (Vault, sealed secrets, etc.). + +```yaml +version: 1 # Schema version for future evolution + +# Where to find org-specific resources +intent_repo: /features # or /intent +architecture_repo: /architecture + +# Agent runtime defaults +runtime: + harness: claude-code # or opencode + model: claude-sonnet-4-6 + +# Infrastructure +infrastructure: + platform: kubernetes # or github-actions, etc. + # platform-specific config follows + +# Sandbox defaults +sandbox: + network_policy: restricted + filesystem: ephemeral +``` + +Per-repo overrides in `repos/.yaml` can override org defaults +(within the bounds of org-wide guardrails that cannot be weakened). + +The exact schema will evolve. The decision here is about the convention and +location, not the schema details. + +### Inheritance model + +Base fullsend provides default agents, skills, and workflows. The `.fullsend` +repo extends or overrides them for the org. Per-repo config in +`repos/.yaml` further overrides for specific repos. The layering is: + +``` +fullsend defaults < org .fullsend config < per-repo overrides +``` + +Org config can add agents, skills, and workflows. It can override defaults. It +cannot weaken org-wide guardrails. Guardrails live in a separate +`guardrails.yaml` file so that CODEOWNERS can enforce stricter review on that +file specifically (CODEOWNERS operates on file paths, not YAML sections). + +**Limitation:** per-repo overrides in `repos/.yaml` use the same +layering mechanism as org-over-upstream. Without additional enforcement, a repo +override could weaken org-level guardrails. The exact mechanism for protecting +org guardrails from repo-level override is tracked as a follow-up (see issue +#84). + +## Consequences + +- **Single, discoverable configuration root.** No ambiguity about where + config lives. +- **Org-owned.** The adopting org controls permissions, review, and release + cadence for its own config — no PRs to fullsend needed. +- **Security-critical asset.** The `.fullsend` repo defines agent behavior + and must be protected accordingly: restricted write access, required + reviews, audit logging. (See [governance.md](../problems/governance.md) — + configuration security.) +- **Stable convention for tooling.** Harness assembly, trigger layer, and + CLI tooling all assume `.fullsend` exists and follow pointers from there. +- **Centralized per-repo overrides.** All org configuration is auditable in + one place rather than scattered across repos. +- **`docs/problems/applied/` stays for problem analysis**, not operational + config. +- **Natural bootstrap for adoption.** A fullsend installer's first step is + creating the `.fullsend` repo and populating initial config. Everything + else flows from that repo existing. +- **Guardrail override gap.** The inheritance model does not yet define how + an org protects specific settings from being weakened by per-repo overrides. + Separating guardrails into their own file solves the org-level CODEOWNERS + problem, but the repo-level override boundary needs further design (issue + #84). diff --git a/docs/architecture.md b/docs/architecture.md index 4a37a8b9dd..4cbd5525ed 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -12,6 +12,8 @@ The compute and orchestration layer that runs agent workloads. Responsible for p This is the "where do agents physically run" question — whether that's a managed platform, internal Kubernetes, CI runners repurposed for agent work, or something purpose-built. +Infrastructure platform choice and configuration are specified in the org's `/.fullsend` repo. (See [ADR 0003](ADRs/0003-org-config-repo-convention.md).) + **Open questions:** - Do we adopt a 3rd party platform, use existing internal infrastructure, or build our own? (See [agent-infrastructure.md](problems/agent-infrastructure.md) for the three directions.) @@ -24,6 +26,8 @@ The isolation boundary around a running agent. Responsible for filesystem access The sandbox is a security primitive. Its job is containment: if an agent is compromised or misbehaves, the blast radius is limited to what the sandbox permits. +Sandbox defaults (network policy, filesystem restrictions) are configured in the org's `/.fullsend` repo and can be overridden per-repo. (See [ADR 0003](ADRs/0003-org-config-repo-convention.md).) + **Open questions:** - What is the right isolation level — process, container, microVM, or separate cluster? (See [agent-infrastructure.md](problems/agent-infrastructure.md) and [security-threat-model.md](problems/security-threat-model.md).) @@ -37,12 +41,13 @@ The configuration and context layer that prepares an agent for its task. Respons The harness is what makes a generic LLM into a specific agent with a specific role. It assembles what the agent needs to know and what it's allowed to do before the agent starts working. +The harness draws its configuration from the org's `/.fullsend` repo — skills, workflow definitions, and agent behavioral instructions are assembled from the layered config (fullsend defaults < org config < per-repo overrides). (See [ADR 0003](ADRs/0003-org-config-repo-convention.md).) + **Open questions:** - Does the harness live inside the sandbox (configuring the agent from within its isolation boundary) or outside it (preparing the environment before the agent starts)? - How is codebase context assembled? (See [codebase-context.md](problems/codebase-context.md).) - How do we version and test harness configurations? (See [testing-agents.md](problems/testing-agents.md).) -- Is the harness per-role, per-repo, or both? ## Agent Runtime @@ -89,9 +94,10 @@ Where agent behavioral rules live. Responsible for holding autonomy levels, revi Policy is distinct from the harness (which configures *how* an agent works) and from intent (which defines *what* work is authorized). Policy defines the *boundaries* of agent behavior — what an agent is allowed to do regardless of what it's asked to do. +The org's `/.fullsend` repo is the natural home for policy configuration — org-wide guardrails, per-repo autonomy levels, and escalation rules all live there, governed by the org's own CODEOWNERS and review process. (See [ADR 0003](ADRs/0003-org-config-repo-convention.md).) + **Open questions:** -- Where does policy live — a dedicated repo, per-repo configuration files, or a combination? (See [governance.md](problems/governance.md).) - How is policy versioned, and how do we ensure agents run under the correct policy version? - Who can change policy, and what approval process governs policy changes? (See [governance.md](problems/governance.md).) - How does policy interact with the autonomy spectrum — is the auto-merge vs. escalate decision a policy setting? (See [autonomy-spectrum.md](problems/autonomy-spectrum.md).) @@ -102,9 +108,11 @@ The system that provides authorized intent for agent work. Responsible for repre Intent answers the question "should this change exist?" before anyone asks "is this change correct?" Without authorized intent, an agent has no basis for deciding what to work on or whether its output matches what was asked for. +The org's `/.fullsend` repo holds the pointer to the intent source (e.g., `intent_repo: /features`), so tooling discovers where intent lives without hardcoding. (See [ADR 0003](ADRs/0003-org-config-repo-convention.md).) + **Open questions:** -- What is the right representation — GitHub issues, a dedicated intent repo, RFCs, or tiered combinations? (See [intent-representation.md](problems/intent-representation.md).) +- What is the right representation — forge issues, a dedicated intent repo, RFCs, or tiered combinations? (See [intent-representation.md](problems/intent-representation.md).) - How do agents verify that intent is authentic and hasn't been tampered with? - How do different tiers of intent (standing rules, tactical issues, strategic features) map to different authorization requirements? - How does intent interact with the "try it" phase — agents building exploratory drafts before authorization? (See [intent-representation.md](problems/intent-representation.md).) @@ -129,9 +137,10 @@ The catalog of available agent roles and their configurations. Responsible for d The registry is the bridge between the abstract roles defined in [agent-architecture.md](problems/agent-architecture.md) (correctness agent, intent alignment agent, etc.) and the concrete runtime configurations that the harness uses to set up each agent. +Fullsend provides a base set of agent definitions. The org's `/.fullsend` repo extends this with org-specific agents in its `agents/` directory, following the inheritance model: fullsend defaults < org config < per-repo overrides. (See [ADR 0003](ADRs/0003-org-config-repo-convention.md).) + **Open questions:** -- Is the registry a formal system (a database, a config repo) or an informal convention (a directory of harness configurations)? - How are new agent roles added, tested, and promoted to production? (See [testing-agents.md](problems/testing-agents.md).) - Does the registry include version information, so we can roll back to a previous agent configuration? - How does the registry relate to the policy store — does policy reference registry entries, or are they independent?