Skip to content
Merged
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
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,6 @@ The term "tier" is used in multiple distinct contexts across this codebase. Alwa
|---|---|---|
| **credential delivery tier** | The four-tier model for how agents receive credentials: (1) prefetch + post-process, (2) providers + L7, (3) host-side REST server, (4) host files | [ADR 0025](docs/ADRs/0025-provider-credential-delivery-for-sandboxed-agents.md) |
| **intent authorization tier** | The four-tier model for change authorization: (0) standing rules, (1) tactical/issue, (2) strategic, (3) organizational | [intent-representation.md](docs/problems/intent-representation.md) |
| **configuration tier** | The three-tier inheritance model for agent configuration: upstream defaults → org config → per-repo overrides | [ADR 0035](docs/ADRs/0035-layered-content-resolution.md) |
| **configuration tier** | The three-tier inheritance model for agent configuration: upstream defaults → org config → per-repo overrides. The `customized/` overlay mechanism (ADR-0035) is deprecated; use config-driven agent registration per [ADR 0064](docs/ADRs/0064-deprecate-customized-directory-overlay.md) | [ADR 0035](docs/ADRs/0035-layered-content-resolution.md) |

**Do not** use bare "Tier N" or "tier" without a prefix — the same number means different things in different contexts (e.g., "Tier 2" could be provider-based credential delivery or strategic intent authorization). External tier references (e.g., "GitLab Free tier", "GitHub plan tiers") are exempt from this convention.
2 changes: 1 addition & 1 deletion docs/ADRs/0033-per-repo-installation-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ Per-repo requirements: repo admin + org admin to install GitHub Apps on the repo
target-repo/
├── .github/workflows/fullsend.yml ← single workflow file (~70 lines, shim)
├── .fullsend/ ← in-repo config workspace (optional)
│ ├── customized/ ← user overrides (same convention as per-org)
│ ├── customized/ ← user overrides (deprecated by ADR-0064)
│ │ ├── agents/ ← agent prompt overrides
│ │ ├── harness/ ← harness config overrides
│ │ ├── policies/ ← sandbox policies
Expand Down
5 changes: 5 additions & 0 deletions docs/ADRs/0045-forge-portable-harness-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,11 @@ forge-specific artifact. The harness and agent definition are portable.
removing an agent is deleting a file, adding one is creating a thin
wrapper with `base:`.

- **Bidirectional composition.** The `base:` merge semantics have an
inverse (`DiffHarness`) used by [ADR 0064](0064-deprecate-customized-directory-overlay.md)'s
`migrate-customizations` command. Changes to merge rules must be
reflected in both directions.

- **Default URL allowlist for `base` composition.** `fullsend install`
sets `allowed_remote_resources` in `config.yaml` to include the
fullsend scaffold URL prefix
Expand Down
2 changes: 1 addition & 1 deletion docs/ADRs/0056-per-repo-precommit-tools-registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Related: [#1270](https://github.com/fullsend-ai/fullsend/issues/1270)
PR #1055 introduced `.pre-commit-tools.yaml` — a registry mapping
pre-commit hooks to the system tools they require. The registry can be
fully replaced at the org level via `customized/scripts/` (L1 override,
[ADR 0035](0035-layered-content-resolution.md)), but repos needing one extra tool must copy the entire file.
[ADR 0035](0035-layered-content-resolution.md); `customized/` deprecated by [ADR 0064](0064-deprecate-customized-directory-overlay.md)), but repos needing one extra tool must copy the entire file.

## Decision

Expand Down
3 changes: 2 additions & 1 deletion docs/ADRs/0058-agent-registration.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ scaffold-discovered agents; collision is keyed by agent name (explicit
favor of config, enabling gradual migration. Once all first-party agents are extracted, config
becomes authoritative and the scaffold fallback is removed.

A `fullsend agent` CLI subcommand (`add`, `list`, `update`, `remove`)
A `fullsend agent` CLI subcommand (`add`, `list`, `update`, `remove`;
plus `migrate-customizations` per [ADR 0064](0064-deprecate-customized-directory-overlay.md))
manages entries (single-user CLI operations; no concurrency guard on
config read/write) and auto-pins URLs to a commit SHA with an
integrity hash. Per-repo config gains `allowed_remote_resources` so per-repo
Expand Down
2 changes: 2 additions & 0 deletions docs/ADRs/0064-deprecate-customized-directory-overlay.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ implemented and in production.

- Users who placed files in `customized/` must migrate to `base:`
composition, URL references, or config-based registration.
`fullsend agent migrate-customizations` automates this conversion and
delivers the changes via pull request.
- Deprecation warnings during install and updated documentation will guide
migration.
- The reusable workflows become simpler — no overlay loop, no
Expand Down
4 changes: 4 additions & 0 deletions docs/agents/review.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ You can also overload it at the org level in your `.fullsend` config repo at
`customized/skills/issue-labels/SKILL.md`. At runtime, your version replaces
the upstream default -- no other configuration needed.

> **Deprecated (ADR-0064):** The `customized/` overlay is deprecated. Use
> config-driven agent registration instead. Run `fullsend agent migrate-customizations`
> to migrate existing overrides.

See [Customizing with AGENTS.md](../guides/user/customizing-with-agents-md.md) and
[Customizing with Skills](../guides/user/customizing-with-skills.md).

Expand Down
4 changes: 4 additions & 0 deletions docs/agents/triage.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ You can also overload it at the org level in your `.fullsend` config repo at
`customized/skills/issue-labels/SKILL.md`. At runtime, your version replaces
the upstream default — no other configuration needed.

> **Deprecated (ADR-0064):** The `customized/` overlay is deprecated. Use
> config-driven agent registration instead. Run `fullsend agent migrate-customizations`
> to migrate existing overrides.

Here's an example that encodes domain-specific labeling rules:

```markdown
Expand Down
2 changes: 1 addition & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ Fullsend provides a base set of agent definitions. The adopting organization's *
- Config-level agent registration: an `agents` list in both `OrgConfig` and `PerRepoConfig` declares agent harness sources as pinned URLs or local paths, replacing compiled-in agent discovery ([ADR 0058](ADRs/0058-agent-registration.md)).
- Runtime resolution: `fullsend run <name>` resolves agents in three tiers: (1) config entries from `OrgConfig.Agents` (highest priority), (2) runtime fallback to the `fullsend-ai/agents` repository for known first-party agents not in config, (3) scaffold-embedded harnesses on disk. The agents-repo fallback is a transitional mechanism for the [agent extraction](plans/agent-extraction-to-agents-repo.md); it will be removed once all users have migrated to config-driven registration (ADR 0058 Phase 5).
- Additive merge: config entries overlay scaffold-discovered agents (config wins on name collision), enabling gradual extraction of first-party agents without disrupting existing installations. Builds on [ADR 0045](ADRs/0045-forge-portable-harness-schema.md) harness identity model.
- CLI management: `fullsend agent add/list/update/remove` manages config entries and auto-pins URLs to a commit SHA with an integrity hash.
- CLI management: `fullsend agent add|list|update|remove|migrate-customizations` manages config entries and auto-pins URLs to a commit SHA with an integrity hash.

**Open questions:**

Expand Down
2 changes: 1 addition & 1 deletion docs/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Download the latest binary from [GitHub Releases](https://github.com/fullsend-ai
| Command | Description |
|---------|-------------|
| `fullsend run` | Execute an agent locally in a sandbox. See [running agents locally](../guides/user/running-agents-locally.md). |
| `fullsend agent` | Manage agent registrations in config (add, list, update, remove) |
| `fullsend agent` | Manage agent registrations in config. Subcommands: `add`, `list`, `update`, `remove` (CRUD) and `migrate-customizations` (one-time migration of `customized/` overrides to config-driven agents per ADR-0064) |
| `fullsend lock [agent-name]` | Pin remote dependencies to `lock.yaml` |
| `fullsend scan` | Run security scanners on agent input/output |

Expand Down
32 changes: 30 additions & 2 deletions docs/guides/dev/cli-internals.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ fullsend
│ ├── add <url-or-path> # Register an agent (URL auto-pinned)
│ ├── list # List registered agents
│ ├── update <name> [sha] # Re-pin URL agent to new commit SHA
│ └── remove <name> # Unregister agent from config
│ ├── remove <name> # Unregister agent from config
│ └── migrate-customizations # Migrate customized/ → config agents
│ ├── --fullsend-dir <dir> # Base directory with .fullsend layout
│ ├── --repo <owner/repo> # Target repo for migration PR
│ └── --dry-run # Preview changes without PR
├── lock [agent-name] # Pin remote deps to lock.yaml
│ ├── --all # Lock all harnesses in the harness directory
│ ├── --fullsend-dir <path> # Base directory with .fullsend layout
Expand Down Expand Up @@ -85,6 +89,28 @@ fullsend
└── --role <string> # Agent role for minting (required with --mint-url)
```

### Migrate Customizations

The `fullsend agent migrate-customizations` command converts `customized/` directory overlays (deprecated by [ADR-0064](../../ADRs/0064-deprecate-customized-directory-overlay.md)) into config-driven agents with `base:` composition harnesses. It scans the local `customized/` directory, classifies each override, and delivers changes via PR:

```bash
# Preview what would change (no PR created)
fullsend agent migrate-customizations --fullsend-dir .fullsend --dry-run

# Create a migration PR
fullsend agent migrate-customizations --fullsend-dir .fullsend --repo owner/repo
```

Migration actions per agent:

| Override type | Detection | Action |
|---------------|-----------|--------|
| Dead | Agent already registered in config | Delete customized files |
| Custom | Not in upstream scaffold | Move files, register local path in config |
| Modified | Standard scaffold agent, not in config | Compute `base:` composition harness via `DiffHarness`, register in config |

The diff engine (`internal/harness/diff.go`) computes the minimal child harness that reproduces the customized version when composed with the upstream base. It mirrors `mergeBaseIntoChild` semantics: scalar overrides, slice concatenation extras, map merge deltas, and security fields always included.

### Command Decomposition

The `mint`, `inference`, and `github` subcommands decompose setup into role-specific operations for organizations that separate GCP and GitHub responsibilities:
Expand Down Expand Up @@ -186,7 +212,8 @@ Both per-org and per-repo modes share the same core pipeline. The code follows t
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Phase 5: Write scaffold + config files │ │
│ │ │ │
│ │ Both modes: write workflow files + customized/ dirs │ │
│ │ Both modes: write workflow files (customized/ deprecated │ │
│ │ by ADR-0064; use migrate-customizations to convert) │ │
│ │ CommitScaffoldFiles() delivery modes: │ │
│ │ Default (PR): create feature branch → commit → open PR │ │
│ │ --direct: try CommitFiles (default branch) │ │
Expand Down Expand Up @@ -549,6 +576,7 @@ var executableFiles = map[string]struct{}{
|------|-------|---------|
| `internal/cli/root.go` | ~34 | CLI entry point, command registration |
| `internal/cli/admin.go` | ~2415 | Install/uninstall/analyze/enable/disable |
| `internal/cli/migrate.go` | ~520 | Migrate customized/ overrides to config-driven agents |
| `internal/cli/mint.go` | ~1022 | Mint deploy/enroll/unenroll/status |
| `internal/cli/inference.go` | ~408 | Inference WIF provision/status |
| `internal/cli/github.go` | ~966 | GitHub setup/set/status/uninstall/sync-scaffold/enroll/unenroll |
Expand Down
1 change: 1 addition & 0 deletions docs/guides/getting-started/operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ For organizations that separate GCP and GitHub responsibilities across teams, fu
| Developer | `fullsend agent list` | List registered agents and their sources |
| Developer | `fullsend agent update <name> [sha]` | Re-pin a URL agent to a new commit SHA |
| Developer | `fullsend agent remove <name>` | Unregister an agent from config |
| Developer | `fullsend agent migrate-customizations` | Migrate `customized/` overlays to config-driven agents via PR |

The typical handoff: a GCP admin runs `mint deploy` + `mint enroll` + `inference provision`, then passes the mint URL and WIF provider resource name to a GitHub maintainer who runs `github setup --mint-url=... --inference-wif-provider=...`.

Expand Down
6 changes: 6 additions & 0 deletions docs/guides/user/building-custom-agents.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Building custom agents

> **Deprecated:** This guide uses the `customized/` directory overlay, which is
> deprecated per [ADR-0064](../../ADRs/0064-deprecate-customized-directory-overlay.md).
> For new custom agents, register them in `config.yaml` with a local `source:`
> path instead. Run `fullsend agent migrate-customizations --dry-run` to
> preview migrating existing customizations.

This guide walks through creating a new custom agent from scratch on a per-repo fullsend installation.

For customizing existing agents (overriding harnesses, skills, or policies), see [Customizing agents](customizing-agents.md).
Expand Down
30 changes: 25 additions & 5 deletions docs/guides/user/customizing-agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,22 @@ security: # Security is enabled by default with fail_mode

## Layered Configuration Resolution

> **Deprecated:** The `customized/` directory overlay mechanism described
> below is deprecated per [ADR-0064](../../ADRs/0064-deprecate-customized-directory-overlay.md).
> Use `base:` composition instead: register agents in `config.yaml` with a
> `base:` URL pointing to the upstream harness, and override only the fields
> that differ. See [ADR-0045](../../ADRs/0045-forge-portable-harness-schema.md)
> for the composition model and [ADR-0058](../../ADRs/0058-agent-registration.md)
> for config-driven registration.
> Run `fullsend agent migrate-customizations --dry-run` to preview the
> migration, then `fullsend agent migrate-customizations --repo owner/repo`
> to apply it.

Fullsend uses a three-tier configuration inheritance model for all configuration: agent definitions, skills, policies, harness definitions, and guardrails. Each configuration tier can extend or override the one below it.

```
┌──────────────────────────────────────────────────────────────┐
Configuration Layering (ADR 0035)
│ Configuration Layering (ADR 0035, deprecated by ADR 0064)
├──────────────────────────────────────────────────────────────┤
│ │
│ Priority (highest wins): │
Expand Down Expand Up @@ -149,15 +160,18 @@ For per-repo mode, the same structure lives at `.fullsend/customized/` within th

### How Override Resolution Works

> **Deprecated:** This section describes the deprecated `customized/` overlay.
> See the [deprecation notice above](#layered-configuration-resolution).

**File-level replacement, not field-level merging.** When you place a file in `customized/harness/code.yaml`, it completely replaces the upstream `harness/code.yaml`. There is no YAML field merging.

**Example: Adding a skill to the code agent**

To add a custom skill to the code agent's harness:
To add a custom skill to the code agent's harness (deprecated — use `base:` composition instead):

1. **Copy the full upstream harness** from `fullsend-ai/fullsend` to your customization directory:
```bash
# Get upstream harness
# ⚠ Deprecated: use `fullsend agent migrate-customizations` to convert to config-driven agents
curl -o .fullsend/customized/harness/code.yaml \
https://raw.githubusercontent.com/fullsend-ai/fullsend/main/internal/scaffold/fullsend-repo/harness/code.yaml
```
Expand Down Expand Up @@ -190,6 +204,10 @@ To add a custom skill to the code agent's harness:

### Customizing Pre-commit Tool Dependencies

> **Note:** The `customized/scripts/.pre-commit-tools.yaml` L1 overlay path
> referenced below uses the deprecated `customized/` mechanism.
> The per-repo L2 path (`.pre-commit-tools.yaml` at repo root) is unaffected.

Fullsend auto-detects and installs tools required by a target repo's pre-commit hooks. The resolver reads `.pre-commit-config.yaml`, matches hooks against a tools registry, and installs missing dependencies before the authoritative pre-commit check runs.

Only hooks that pre-commit **cannot self-serve** need registry entries:
Expand Down Expand Up @@ -300,7 +318,8 @@ Each agent role has its own identity, permissions, and purpose:

### Adding a Custom Skill

Create `.fullsend/customized/skills/my-skill/SKILL.md` in your config repo:
Create `.fullsend/customized/skills/my-skill/SKILL.md` in your config repo
(deprecated — use config-driven agent registration instead):

```markdown
# My Custom Skill
Expand All @@ -316,7 +335,8 @@ The skill will be automatically available to all agents that include `skills/my-

### Overriding an Agent Definition

Create `.fullsend/customized/agents/code.md` to override the default code agent with org-specific instructions:
Create `.fullsend/customized/agents/code.md` to override the default code agent
with org-specific instructions (deprecated — use `base:` composition instead):

```markdown
# Code Agent (Customized)
Expand Down
2 changes: 1 addition & 1 deletion docs/guides/user/customizing-with-agents-md.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ takes precedence.
cannot write files regardless of what AGENTS.md says)
- Remove or replace built-in skills — use
[`customized/skills/`](customizing-with-skills.md#overriding-built-in-skills)
for that
for that (deprecated per ADR-0064; use config-driven agent registration instead)
- Change the agent's model or execution parameters

### Injection handling
Expand Down
7 changes: 6 additions & 1 deletion docs/guides/user/customizing-with-skills.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ when available.

## Overriding built-in skills

> **Deprecated:** The `customized/` overlay described below is deprecated per
> [ADR-0064](../../ADRs/0064-deprecate-customized-directory-overlay.md).
> Use `base:` composition and config-driven agent registration instead.

To intentionally **replace** a built-in skill with your own version, use the
`customized/` overlay ([ADR 0035](../../ADRs/0035-layered-content-resolution.md)).
This replaces the skill at the config layer before the agent starts — the
Expand All @@ -134,7 +138,8 @@ engine, not through project-level skill discovery.

### Built-in skills

These skills ship with fullsend and can be overridden via `customized/skills/`:
These skills ship with fullsend and can be overridden via `customized/skills/`
(deprecated per ADR-0064 — use config-driven agent registration instead):

| Agent | Skill | Purpose |
|-------|-------|---------|
Expand Down
5 changes: 5 additions & 0 deletions docs/guides/user/running-agents-locally.md
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,11 @@ cp -r /tmp/fullsend-ai_fullsend/internal/scaffold/fullsend-repo/. /tmp/agents/

Then apply your organization customizations, if any:

> **Note:** The `customized/` overlay mechanism is deprecated per
> [ADR-0064](../../ADRs/0064-deprecate-customized-directory-overlay.md).
> Orgs that have migrated to config-driven agents should skip these
> `cp -r customized/` steps and use the registered harness paths directly.

```bash
git clone --depth 1 https://github.com/{org}/.fullsend.git /tmp/org-fullsend/
cp -r /tmp/org-fullsend/customized/. /tmp/agents/
Expand Down
6 changes: 6 additions & 0 deletions docs/plans/agent-registration.md
Original file line number Diff line number Diff line change
Expand Up @@ -450,3 +450,9 @@ PRs 2 and 3 can be developed in parallel after PR 1 merges. PR 4
is the cleanup that depends on everything else. Phase 5 is a
follow-up tracked by a GitHub issue, filed once all first-party
agents have been extracted from the scaffold.

**Related:** `fullsend agent migrate-customizations` (implemented in
ADR-0064 / PR #2932) migrates existing `customized/` overrides into
config-driven agents. It uses `DiffHarness` to compute minimal `base:`
composition harnesses and registers agents via the same config schema
defined in Phase 1.
Loading
Loading