Decompose Collector config only when it pays
OllyGarden's default is restraint: decomposition reduces review and ownership scope, but makes every
reader reconstruct the whole. A deliberate no-op is the correct result when indirection costs more
than it saves.
Use upstream skills for facts that change independently:
otel-collector — current providers, merge behavior, commands, component keys, and distribution
support.
ollygarden-otel-collector-config-validation — behavioral proof for a processor or connector.
ollygarden-otel-collector-k8s-daemonset — a consumer of this workflow, not its source of truth.
Workflow
- Inspect the monolith, environment variants, ownership, and deployment command. Record the exact
Collector distribution and version, feature-gate set, and ordered configuration URIs.
- Count the pressures below. If fewer than two are meaningful, stop without changing files.
- If warranted, choose the split from actual change and ownership boundaries.
- Read
references/mechanics.md, then write the split directly unless
the user requested a plan or the workspace is read-only.
- Validate and compare the fully resolved monolith and split using
references/verifying.md. Do not call the refactor complete without
both checks.
- Return the decision report.
Decision gate
Decompose when at least two of these are substantial:
- reviews regularly struggle with a config of hundreds of lines;
- independently changing traces, metrics, or logs pipelines share one file;
- copied environment variants are drifting;
- different teams own ingress, processing, egress, or signal pipelines;
- one independently owned block dominates the file, such as sampling policies or scrape jobs.
Keep one file when it fits on a screen, has one pipeline, one owner, and no environment drift. A
single weak signal is not enough.
An existing split or a request to split is not itself a pressure; judge the underlying config.
Select the boundary
Read references/strategies.md for layouts and overlay mechanics.
- Independent signal teams → by signal:
common.yaml plus complete signal files. This is the usual
default and keeps each pipeline together.
- Stage-owning teams → by component: a service/pipeline base plus component-type files.
- Same structure, different values → environment overlays on either layout.
- One large independently owned sub-block → one nested
file: inclusion; do not fragment small
blocks.
When several fit, prefer the smallest file set that follows the strongest real boundary. Do not
invent an ownership model to justify a pattern.
Non-negotiable preservation rules
- Keep each pipeline's
receivers, processors, and exporters sequence in one file. Under the
default merge behavior, later sequences replace earlier ones. Even when
confmap.enableMergeAppendOption is enabled, only service.extensions and pipeline receivers
and exporters append; processors still replace, and processor order is behavior.
- Define shared components once. Distinct
service.pipelines.<name> map entries may live with their
owning signal.
- Preserve component IDs, values, provider expressions, extensions, connectors, service telemetry,
and pipeline membership unless the user separately authorized a behavior change.
- Treat environment overlays as ordered inputs. Record their order, exact configuration URIs, and
feature-gate set.
- Validate the complete ordered source set, never a fragment in isolation.
- Compare fully resolved output from the monolith with fully resolved output from the split under
the same pinned Collector and environment. Raw YAML versus resolved YAML is not an equivalence
test.
- Structural equality does not prove that an OTTL rule, processor, or connector behaves correctly;
explicitly hand that question to
ollygarden-otel-collector-config-validation in the report.
Decision report
End with:
Decision: <decomposed | left as one file>
Why: <criteria met or absent>
Strategy: <by-signal | by-component | overlays | nested | n/a>
Files: <created/changed files or unchanged>
Verification: <merged validation and resolved-equivalence result, pending reason, or n/a>
1---2name: ollygarden-otel-collector-config-decomposition3description: Decide and execute plain-file decomposition for OpenTelemetry Collector YAML. Use for "should I split this collector config?", "break up this otelcol YAML", "organize it by signal or team", or "create environment overlays". Leaves simple configs intact and proves warranted splits equivalent after merge. Not for Helm, Kustomize, or Terraform packaging; use otel-collector for component facts and ollygarden-otel-collector-config-validation for behavioral proof.4license: Apache-2.05---67# Decompose Collector config only when it pays89OllyGarden's default is restraint: decomposition reduces review and ownership scope, but makes every10reader reconstruct the whole. A deliberate no-op is the correct result when indirection costs more11than it saves.1213Use upstream skills for facts that change independently:1415- `otel-collector` — current providers, merge behavior, commands, component keys, and distribution16 support.17- `ollygarden-otel-collector-config-validation` — behavioral proof for a processor or connector.18- `ollygarden-otel-collector-k8s-daemonset` — a consumer of this workflow, not its source of truth.1920## Workflow21221. Inspect the monolith, environment variants, ownership, and deployment command. Record the exact23 Collector distribution and version, feature-gate set, and ordered configuration URIs.242. Count the pressures below. If fewer than two are meaningful, stop without changing files.253. If warranted, choose the split from actual change and ownership boundaries.264. Read [`references/mechanics.md`](references/mechanics.md), then write the split directly unless27 the user requested a plan or the workspace is read-only.285. Validate and compare the fully resolved monolith and split using29 [`references/verifying.md`](references/verifying.md). Do not call the refactor complete without30 both checks.316. Return the decision report.3233## Decision gate3435Decompose when at least two of these are substantial:3637- reviews regularly struggle with a config of hundreds of lines;38- independently changing traces, metrics, or logs pipelines share one file;39- copied environment variants are drifting;40- different teams own ingress, processing, egress, or signal pipelines;41- one independently owned block dominates the file, such as sampling policies or scrape jobs.4243Keep one file when it fits on a screen, has one pipeline, one owner, and no environment drift. A44single weak signal is not enough.45An existing split or a request to split is not itself a pressure; judge the underlying config.4647## Select the boundary4849Read [`references/strategies.md`](references/strategies.md) for layouts and overlay mechanics.5051- Independent signal teams → by signal: `common.yaml` plus complete signal files. This is the usual52 default and keeps each pipeline together.53- Stage-owning teams → by component: a service/pipeline base plus component-type files.54- Same structure, different values → environment overlays on either layout.55- One large independently owned sub-block → one nested `file:` inclusion; do not fragment small56 blocks.5758When several fit, prefer the smallest file set that follows the strongest real boundary. Do not59invent an ownership model to justify a pattern.6061## Non-negotiable preservation rules6263- Keep each pipeline's `receivers`, `processors`, and `exporters` sequence in one file. Under the64 default merge behavior, later sequences replace earlier ones. Even when65 `confmap.enableMergeAppendOption` is enabled, only `service.extensions` and pipeline receivers66 and exporters append; processors still replace, and processor order is behavior.67- Define shared components once. Distinct `service.pipelines.<name>` map entries may live with their68 owning signal.69- Preserve component IDs, values, provider expressions, extensions, connectors, service telemetry,70 and pipeline membership unless the user separately authorized a behavior change.71- Treat environment overlays as ordered inputs. Record their order, exact configuration URIs, and72 feature-gate set.73- Validate the complete ordered source set, never a fragment in isolation.74- Compare fully resolved output from the monolith with fully resolved output from the split under75 the same pinned Collector and environment. Raw YAML versus resolved YAML is not an equivalence76 test.77- Structural equality does not prove that an OTTL rule, processor, or connector behaves correctly;78 explicitly hand that question to `ollygarden-otel-collector-config-validation` in the report.7980## Decision report8182End with:8384```text85Decision: <decomposed | left as one file>86Why: <criteria met or absent>87Strategy: <by-signal | by-component | overlays | nested | n/a>88Files: <created/changed files or unchanged>89Verification: <merged validation and resolved-equivalence result, pending reason, or n/a>90```