Skip to content

Default agents vs. custom agents

Fullsend ships six default agents: triage, prioritize, code, review, fix, and retro. Each can be configured and extended. At some point, enough modification turns a configured default agent into a custom agent that re-uses parts of a default. This document defines where that line is.

Why the distinction matters

This is a bit of a Ship of Theseus exercise. The question has a practical purpose, though. We want two things simultaneously:

  1. Encourage custom agents. The harness, sandbox, and base composition system exist so teams can build agents tailored to their workflows.
  2. Encourage contribution to default agents. When a change improves a default agent for everyone, it should flow upstream rather than live in a private fork.

Knowing whether you are running a configured default agent or a custom agent helps you decide: should this change be contributed back, or does it only make sense for my team?

Default to contributing. If your modification would benefit other users, contribute it to the default agent's definition. Build a custom agent only when your needs genuinely diverge from what the default agent is designed to do.

The rule

If a modification uses a method documented as a recommended extension point for that agent, the result is still a configured default agent. If it uses any other method, the result is a custom agent that re-uses parts of a default.

Each default agent documents its extension points in docs/agents/<agent>.md. The review agent, for example, documents REVIEW_FINDING_SEVERITY_THRESHOLD as a configuration variable and issue-labels as an overloadable skill. Using those mechanisms produces a configured review agent, not a custom one.

The base lineage test

The base field in a harness YAML (ADR 0045) is the first thing to check. If a harness's base chain — through one or more levels of inheritance — traces back to a default agent harness in fullsend-ai/fullsend, the harness started from a default agent. What you override on top of that base determines whether the result is still a configured default or has crossed into custom territory.

If the base chain does not trace back to a default agent harness, the agent is custom by definition — regardless of how similar it looks.

Classification by harness field

ModificationStill a default agent?Rationale
Set a documented configuration variable (e.g., REVIEW_FINDING_SEVERITY_THRESHOLD)YesDocumented extension point. The agent was designed for this.
Add environment variables via env:YesEnv vars augment behavior without changing identity.
Add skills via skills:YesSkills extend knowledge. The agent's core behavior is unchanged.
Add repo-level skills in .agents/skills/YesRepo skills are discovered automatically; no harness change needed.
Add project instructions via AGENTS.mdYesAll agents read AGENTS.md. This is the standard customization path.
Override a built-in skill via customized/skills/YesDocumented extension point (Customizing with Skills).
Replace the sandbox image with one based on the default imageYesThe agent's behavior is unchanged; the environment is augmented.
Add plugins via plugins:YesPlugins extend tooling without changing the agent's identity.
Add host files via host_files:YesAdditional data for the sandbox. The agent itself is unchanged.
Replace the agent system prompt (agent:)CustomThe system prompt defines what the agent is. Replacing it creates a different agent.
Replace pre or post scripts (pre_script:, post_script:)CustomScripts control the agent's integration with external systems. Different scripts mean different behavior at the pipeline boundary.
Replace the app role slug (slug:)Custom*The slug determines who the agent authenticates as. A different identity is a different agent.
Replace the validation loop (validation_loop:)CustomThe validation loop defines the contract between the agent and the harness. Changing it changes what the agent is expected to produce.
Replace the sandbox policy (policy:)CustomPolicies define the agent's capabilities and trust boundary.

* Replacing the slug is acceptable in limited cases we may document in the future — for example, granting the review agent merge rights via a different GitHub App. When a specific agent's documentation recommends a slug override for a stated purpose, that override does not make the agent custom.

Summary

A configured default agent uses only the extension points documented for that agent. A custom agent uses base inheritance to re-use parts of a default agent while replacing components that define the agent's identity — its system prompt, scripts, slug, validation contract, or security policy.

Both are valid. The distinction helps you decide where a change belongs: upstream in the default agent, or in your own configuration.

See also