-
Notifications
You must be signed in to change notification settings - Fork 94
docs(adr): add ADR 0080 and 0081 for config.yaml vs. agent env scope #5798
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
8a964d3
docs(adr): add ADR 0080 for config.yaml vs. agent env var scope
ralphbean e94e2e6
docs(adr): add clarified-by link from ADR 0049 to ADR 0080
ralphbean eb2c2d9
docs(byoa): document config.yaml vs. agent env var naming convention
ralphbean 9dcdffe
docs: tweak language and drop unnecessary reference
ralphbean f9d3289
fix: address review feedback on PR #5798
fullsend-ai-coder[bot] a8d654a
docs(adr): address review feedback on ADR 0080
ralphbean d6fced4
docs(adr): fix incorrect failure mode for passthrough syntax in ADR 0080
fullsend-ai-coder[bot] 164abd0
fix(adr): tighten config.yaml vs env var boundary in ADR 0080
ralphbean 76dc57e
docs(adr): add ADR 0081 reserving CI workflow env: for infra plumbing
ralphbean a7b4585
docs: align review.md guidance with ADR 0081 and cross-ref ADR 0024
fullsend-ai-coder[bot] afc0e1a
fix(adr): address round 2 review feedback on ADRs 0080/0081
ralphbean 30c7d80
docs(adr): explain AGENT_ prefix rationale for single-agent env vars
ralphbean File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| --- | ||
| title: "80. config.yaml vs. agent env vars: where a config option belongs" | ||
| status: Accepted | ||
| relates_to: | ||
| - agent-infrastructure | ||
| - governance | ||
| topics: | ||
| - configuration | ||
| - harness | ||
| - conventions | ||
| --- | ||
|
|
||
| # 80. config.yaml vs. agent env vars: where a config option belongs | ||
|
|
||
| Date: 2026-07-31 | ||
|
|
||
| Amends: [ADR 0049](0049-agent-configuration-env-var-convention.md) | ||
|
|
||
| ## Status | ||
|
|
||
| Accepted | ||
|
|
||
| ## Context | ||
|
|
||
| [fullsend-ai/agents#567](https://github.com/fullsend-ai/agents/pull/567) | ||
| added `TRIAGE_AUTO_CODE` as a harness `env.runner` default in | ||
| `harness/triage.yaml`. A reviewer flagged that fullsend-ai/fullsend#1754, | ||
| the issue that requested the knob, asked for it to "live in the per-repo/ | ||
| per-org config surface" — i.e. `.fullsend/config.yaml` — not a harness | ||
| default (see the [review | ||
| discussion](https://github.com/fullsend-ai/agents/pull/567#discussion_r3686020058)). | ||
| `config.yaml` already carries fields like `create_issues.allow_targets` | ||
| that are unrelated to any single agent, per the [governance](../problems/governance.md) | ||
| and [agent infrastructure](../problems/agent-infrastructure.md) problem | ||
| docs. [ADR 0049](0049-agent-configuration-env-var-convention.md) defines | ||
| how agent config env vars are *named* (`{AGENT}_{SETTING_NAME}`) and | ||
| requires separate per-agent vars when the same concept is independently | ||
| tunable per agent (e.g. `CODE_MAX_FILE_SIZE` vs `REVIEW_MAX_FILE_SIZE`), | ||
| but it draws no line against `config.yaml` — nothing in it says when a | ||
| knob should live there instead of as an env var, so there was no rule to | ||
| check the PR against. | ||
|
|
||
| ## Decision | ||
|
|
||
| A config option belongs in exactly one of the two surfaces, based on | ||
| whether its behavior is meaningful to more than one agent. This narrows | ||
| ADR 0049's per-agent-vars rule (a setting that applies to multiple agents | ||
| gets separate vars per agent) to the case where each agent needs its own | ||
| independently tunable value; a single value meant to apply the same way | ||
| across every agent is a different case, and belongs in `config.yaml` | ||
| instead: | ||
|
|
||
| - **Pipeline/dispatch policy — governs whether or how agents run, or | ||
| applies the same way across every agent, rather than tuning one agent's | ||
| own inference-time logic:** it is a `config.yaml` field. It gets a plain | ||
| name with no `{AGENT}_` prefix, and it is not also settable via | ||
| environment variable — `config.yaml` (`internal/config` accessors) is | ||
| the single source of truth. `roles`, `kill_switch`, and | ||
| `create_issues.allow_targets` are existing examples. | ||
| - **Single-agent behavior tuning — adjusts how one specific agent does its | ||
| own job:** it is an `{AGENT}_`-prefixed env var per ADR 0049, delivered | ||
|
ralphbean marked this conversation as resolved.
|
||
| via that agent's `env.runner`/`env.sandbox`. The prefix matters even | ||
| though the var lives in one agent's harness: `.env` files can be sourced | ||
| together and `runner_env`/`env.sandbox` can share a host environment, so | ||
| the agent name scopes the var and prevents collisions in those shared | ||
| contexts (ADR 0049, Consequences). It is not also settable as | ||
| a `config.yaml` field — overriding it per repo or org means overriding | ||
| the harness (e.g. via `base:` composition, per ADR 0045), not adding a | ||
| parallel field to `config.yaml`. | ||
|
|
||
| **Override convention:** `env.runner`/`env.sandbox` values are agent | ||
| defaults. A per-repo or per-org override edits the harness (`base:` | ||
| composition, per ADR 0045), not the CI workflow `env:` block. | ||
| [ADR 0081](0081-reserve-workflow-env-for-infra-plumbing.md) reserves that | ||
| block for infrastructure plumbing (credentials, project IDs, regions), | ||
| not agent behavior knobs — overriding ADR 0049's "CI workflow injection" | ||
| delivery mechanism for behavior knobs specifically; see that ADR for the | ||
| full rule and its exceptions. This also means behavior defaults in | ||
| `env.runner`/`env.sandbox` must be literals (e.g. `TRIAGE_AUTO_CODE: | ||
| "on"`), not shell-style passthrough expressions (e.g. | ||
| `${TRIAGE_AUTO_CODE:-on}`) — `env.runner`/`env.sandbox` support `${VAR}` | ||
| host-variable expansion (see [ADR 0055](0055-unified-env-var-delivery.md), | ||
| § Runner behavior), not shell default-value syntax, so passthrough syntax | ||
| is rejected at harness load: env validation treats `TRIAGE_AUTO_CODE:-on` | ||
| as a host variable name and fails with `host variable … is not set`; even | ||
| absent validation, `os.Expand` would resolve the whole reference to an | ||
| empty string, not the intended default. | ||
|
|
||
|
ralphbean marked this conversation as resolved.
|
||
| A knob only moves from one surface to the other by a deliberate migration, | ||
| not by adding a second way to set the same value. Applying this rule to | ||
| `TRIAGE_AUTO_CODE` is a boundary case: it decides whether the code agent | ||
| runs next, which sounds like dispatch policy, but that decision is made | ||
| inside triage's own post-script, as part of triage's inference-time | ||
| behavior — not by a shared dispatch/CLI layer gating multiple agents | ||
| uniformly. That keeps it single-agent behavior tuning today, so it | ||
| correctly belongs in `harness/triage.yaml` `env.runner`, not | ||
| `config.yaml`. If the check is ever lifted out of triage's post-script | ||
| into a shared dispatch layer, it becomes pipeline/dispatch policy and | ||
| should move to `config.yaml` as a deliberate migration, not before. | ||
| fullsend-ai/fullsend#1754's "per-repo/per-org config | ||
| surface" request is satisfied by documenting the existing harness override | ||
|
ralphbean marked this conversation as resolved.
|
||
| path (`base:` composition or an org/repo harness copy), not by adding a | ||
| `config.yaml` field — the gap the reviewer found is a documentation gap, | ||
| not a placement gap. | ||
|
|
||
| ## Consequences | ||
|
|
||
| - Resolves the fullsend-ai/agents#567 ambiguity: `TRIAGE_AUTO_CODE` stays | ||
| an env var; `docs/agents/<agent>.md`'s Variables table must state how to | ||
| override it (which harness layer to edit), matching the guidance ADR | ||
| 0049 already expects. | ||
| - `config.yaml` cannot accumulate `{agent}_foo`-style fields — any such | ||
| field is a signal the knob was misplaced. | ||
| - An env var cannot quietly gain a `config.yaml` mirror with its own | ||
| precedence rules; there is one settable location per config option. | ||
| - A knob whose scope grows from one agent to several requires a new | ||
| decision (an ADR update or explicit review), not a silent field | ||
| addition to `config.yaml`. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| --- | ||
| title: "81. Reserve CI workflow env: for infrastructure plumbing, not agent behavior" | ||
| status: Accepted | ||
| relates_to: | ||
| - agent-infrastructure | ||
| - governance | ||
| topics: | ||
| - configuration | ||
| - harness | ||
| - conventions | ||
| --- | ||
|
|
||
| # 81. Reserve CI workflow env: for infrastructure plumbing, not agent behavior | ||
|
|
||
| Date: 2026-07-31 | ||
|
|
||
| Amends: [ADR 0049](0049-agent-configuration-env-var-convention.md) | ||
|
|
||
| ## Status | ||
|
|
||
| Accepted | ||
|
|
||
| ## Context | ||
|
|
||
| [ADR 0080](0080-config-yaml-vs-agent-env-var-scope.md) states that a | ||
| per-repo or per-org override of an agent behavior knob means overriding | ||
| the harness (`base:` composition, per [ADR 0045](0045-forge-portable-harness-schema.md)), | ||
| not the CI workflow `env:` block. Review of that ADR found the practice | ||
| already drifting: fullsend-ai/agents#567's docs describe setting | ||
| `TRIAGE_AUTO_CODE` via the workflow `env:` block, "matching the | ||
| convention used for `REVIEW_FINDING_SEVERITY_THRESHOLD`" — but | ||
| [ADR 0055](0055-unified-env-var-delivery.md)'s own canonical example sets | ||
| `REVIEW_FINDING_SEVERITY_THRESHOLD` in the harness's `env.sandbox`, not | ||
| the workflow file. Nothing had stated the workflow-env path was out of | ||
| bounds for behavior knobs, so nothing caught the drift. | ||
|
|
||
| ADR 0049 lists "CI workflow injection" as one of three delivery | ||
| mechanisms for agent config vars, alongside `.env` files and | ||
| `runner_env`, without distinguishing infrastructure values (credentials, | ||
| project IDs, regions) from agent behavior knobs. | ||
|
|
||
| ## Decision | ||
|
|
||
| The CI workflow `env:` block (`.github/workflows/<agent>.yml`) is | ||
| reserved for infrastructure plumbing — credentials, project IDs, | ||
| regions, and other infrastructure values sourced from CI-native inputs | ||
| (secrets, org/repo variables). Agent behavior knobs, as scoped by ADR | ||
| 0080 and named per ADR 0049, are never set there. They go through harness | ||
| composition instead: `env.runner`/`env.sandbox` defaults live in the | ||
| canonical harness, and a per-repo or per-org override edits those | ||
| defaults via `base:` composition (ADR 0045). | ||
|
|
||
| The one exception: a value that can only be computed at CI runtime — | ||
|
ralphbean marked this conversation as resolved.
|
||
| derived from `github.event.*`, a build matrix variable, or a secret that | ||
| cannot be expressed as static harness data — may be set in the workflow | ||
| `env:` block even if it configures agent behavior. This ADR does not try | ||
| to enumerate every such case up front; a genuine new one can be added | ||
| here by minor annotation as it turns up. | ||
|
|
||
| This narrows ADR 0049's "CI workflow injection" delivery mechanism: it | ||
| remains valid for infrastructure vars and CI-runtime-only values, not for | ||
| static agent behavior defaults. | ||
|
|
||
| ## Consequences | ||
|
|
||
| - fullsend-ai/agents#567's docs need correcting: `TRIAGE_AUTO_CODE`'s | ||
| override path is harness composition, not CI workflow `env:` — the | ||
| precedent it cited was itself non-conformant. The fullsend-ai/agents | ||
| repo's own `docs/review.md` carries the same non-conformant guidance | ||
| for `REVIEW_FINDING_SEVERITY_THRESHOLD` that this PR fixed in | ||
| `fullsend`'s copy, and needs the equivalent fix. | ||
| - `CODE_ALLOWED_TARGET_BRANCHES: ''` is still hardcoded in | ||
| `reusable-code.yml`/`reusable-dispatch.yml`'s workflow `env:` block, | ||
| even though [ADR 0053](0053-agent-driven-branch-targeting.md) already | ||
| decided this value belongs in the harness's `runner_env`, not the | ||
| workflow YAML. It's a pre-existing non-conformance this ADR's rule | ||
| makes explicit; removing it from the workflow files is a follow-up, | ||
| not part of this decision. | ||
| - New agent behavior knobs get one documented override path (harness | ||
| `base:` composition), removing the ambiguity between three candidate | ||
| mechanisms. | ||
| - A workflow `env:` entry that sets an agent behavior default, and isn't | ||
| one of the CI-runtime-only exceptions, is a signal the knob was placed | ||
| in the wrong layer. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.