Spec 003: layered overrides#3
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ba35af58ba
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4988714b5c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
* Restrict managed config paths to selected services * Enforce service selection for host config overrides
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9f1adfccc0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
* Track removed managed config files during observed-state read * Preserve cloned repo lifetime in layered repo loader
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 48d0745985
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- Socket drop-in changes now restart the owning socket unit after reload, so ListenStream updates take effect without manual intervention. - Drop-in validation now only considers selected services (both base drop-ins and host overrides). Unselected services can no longer block reconciliation.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e3acbb79b6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c7b4a11881
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: da1a0f6341
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Resolves the four MEDIUM-severity findings from the post-tasks analysis pass: - F1 (spec.md Edge Case #3): replace stale "FR-008" reference with "FR-006" — the verbatim-from-real-invocation rule is the actual mitigation for walkthrough drift. - F2 (spec.md Edge Case #3): replace stale "Phase 5" reference with "polish phase / Phase 7" — re-validation lives in tasks.md Phase 7 (T021/SC-007a), not Phase 5 (US3 Mermaid). - F3 (tasks.md T011/T012): drop [P] from T012 and document the serialization rationale — apply mutates `--host immich` state that T011's pre-apply plan reads. Sequential by default; parallel only on isolated hosts. Updated Phase 4 dependency note and Parallel Opportunities accordingly. - F4 (spec.md US2 Independent Test + Why-this-priority): update "the static block" (singular) phrasing to reflect post-clarify FR-006 two-block structure (plan + idempotent re-run). LOW findings (F5–F10) deferred — cosmetic / acknowledged-tradeoff / stale-on-arrival line references that don't affect implementation. No constitution alignment changes, no new FRs/SCs, no new tasks. Validation re-passes as exempt under always_exempt_documentation_or_formatting. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resolves the four MEDIUM-severity findings from the post-tasks analysis pass: - F1 (spec.md Edge Case #3): replace stale "FR-008" reference with "FR-006" — the verbatim-from-real-invocation rule is the actual mitigation for walkthrough drift. - F2 (spec.md Edge Case #3): replace stale "Phase 5" reference with "polish phase / Phase 7" — re-validation lives in tasks.md Phase 7 (T021/SC-007a), not Phase 5 (US3 Mermaid). - F3 (tasks.md T011/T012): drop [P] from T012 and document the serialization rationale — apply mutates `--host immich` state that T011's pre-apply plan reads. Sequential by default; parallel only on isolated hosts. Updated Phase 4 dependency note and Parallel Opportunities accordingly. - F4 (spec.md US2 Independent Test + Why-this-priority): update "the static block" (singular) phrasing to reflect post-clarify FR-006 two-block structure (plan + idempotent re-run). LOW findings (F5–F10) deferred — cosmetic / acknowledged-tradeoff / stale-on-arrival line references that don't affect implementation. No constitution alignment changes, no new FRs/SCs, no new tasks. Validation re-passes as exempt under always_exempt_documentation_or_formatting. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Resolves the four MEDIUM-severity findings from the post-tasks analysis pass: - F1 (spec.md Edge Case #3): replace stale "FR-008" reference with "FR-006" — the verbatim-from-real-invocation rule is the actual mitigation for walkthrough drift. - F2 (spec.md Edge Case #3): replace stale "Phase 5" reference with "polish phase / Phase 7" — re-validation lives in tasks.md Phase 7 (T021/SC-007a), not Phase 5 (US3 Mermaid). - F3 (tasks.md T011/T012): drop [P] from T012 and document the serialization rationale — apply mutates `--host immich` state that T011's pre-apply plan reads. Sequential by default; parallel only on isolated hosts. Updated Phase 4 dependency note and Parallel Opportunities accordingly. - F4 (spec.md US2 Independent Test + Why-this-priority): update "the static block" (singular) phrasing to reflect post-clarify FR-006 two-block structure (plan + idempotent re-run). LOW findings (F5–F10) deferred — cosmetic / acknowledged-tradeoff / stale-on-arrival line references that don't affect implementation. No constitution alignment changes, no new FRs/SCs, no new tasks. Validation re-passes as exempt under always_exempt_documentation_or_formatting. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Feature Specification: Layered Overrides for Reusable Desired State
Feature Branch:
[003-layered-overrides]Created: 2026-03-20
Status: Draft
Input: User description: "Specify the next iteration of the Fedora CoreOS Quadlet GitOps controller around reusable desired state through native layered overrides rather than a custom templating language. Context: The current iteration already supports unattended systemd operation, journald audit integration, secure remote Git access, and reconciliation of container, volume, and socket artifacts on a single host. The next iteration should make desired state reusable across hosts while staying close to native Quadlet and systemd mechanisms. Goals: - allow shared service definitions to be reused across multiple hosts - support host-specific customization without introducing a general templating language - preserve native system semantics, deterministic evaluation, idempotence, and observability Core design direction: - reuse should be achieved through layered overrides - Quadlet-managed artifacts should support Quadlet-native drop-ins such as artifact.container.d/.conf - native systemd artifacts should support systemd drop-ins such as artifact.socket.d/.conf - the controller should evaluate shared base artifacts plus host-specific drop-ins into concrete desired state before diff/plan/apply - avoid custom placeholder syntax and avoid
${...}-style substitution because it may collide with native systemd semantics Requirements: - define a repository model for shared artifacts and per-host overlays/drop-ins - define how the controller determines host identity for selecting host-specific overlays - define merge/evaluation semantics for base artifacts and drop-ins - distinguish clearly between Quadlet-native drop-ins and native systemd drop-ins - ensure the evaluation phase is deterministic, side-effect free, and testable - preserve the existing reconciliation model after evaluation produces concrete desired state - support common real-world reuse scenarios such as shared Traefik definitions with slight host-level variations Constraints: - do not introduce a general templating language - do not introduce arbitrary expression evaluation, loops, or conditionals - do not reuse${...}as a controller-specific parameter syntax - preserve functional core / imperative shell architecture - preserve explicit failure behavior and clear operator diagnostics - remain within the project’s existing scope of native host primitives rather than becoming a generic configuration management system Non-goals: - fleet coordination or cross-host orchestration - secret distribution systems - generic host file content management beyond the existing supported artifact model - arbitrary environment-file management as a first-class abstraction - full template engines or Helm-like rendering The specification should define: - the user/operator problem this iteration solves - the repository structure and desired-state model - evaluation/merge semantics - validation and failure rules for conflicting or invalid overlays - acceptance criteria for shared base definitions with host-specific overrides - risks and open questions for implementation"Clarifications
Session 2026-03-20
User Scenarios & Testing (mandatory)
User Story 1 - Reuse shared base definitions across hosts (Priority: P1)
As an operator, I want to define shared base artifacts once and reuse them across
multiple hosts while selecting which shared services each host should include so
that consistent services can be deployed without duplication or overreach.
Why this priority: Reuse is the central value of this iteration and enables
consistent operations across hosts without a templating language.
Independent Test: Apply the same repository to two hosts with different
service selections and verify each host converges only to its selected shared
services, with no host-specific overlays present.
Acceptance Scenarios:
host evaluates desired state, Then the evaluation output contains only
the base artifacts selected for that host.
state with different selections, Then each produces a concrete desired
state limited to its selected services.
User Story 2 - Apply host-specific drop-ins without templating (Priority: P2)
As an operator, I want host-specific drop-ins to override shared base artifacts
and config payloads without using a templating language so that each host can
adjust behavior using native Quadlet/systemd mechanisms and bounded host paths.
Why this priority: Host-level customization is the key practical need for
reusable desired state while preserving native semantics.
Independent Test: Add a host-specific drop-in and a config override and
verify only that host’s concrete desired state and config materialization change,
while other hosts remain unchanged.
Acceptance Scenarios:
host evaluates desired state after selecting services, Then the drop-in
is applied only to selected base artifacts in the resulting concrete desired
state.
desired state, Then each host’s concrete desired state includes only its
own overlays.
When evaluation runs, Then the config materialized for that host
reflects base payloads with host overrides layered by replacement or
directory overlay rules.
User Story 3 - Deterministic, testable evaluation (Priority: P3)
As an operator, I want evaluation to be deterministic and side-effect free so
that results are testable, repeatable, and safe to run before apply.
Why this priority: Deterministic evaluation preserves GitOps trust and makes
reconciliation outcomes predictable.
Independent Test: Run evaluation twice for the same host and verify identical
outputs and stable diagnostics.
Acceptance Scenarios:
Then the resulting desired state is byte-for-byte identical.
explicitly with a clear diagnostic before planning or applying.
Edge Cases
Requirements (mandatory)
Functional Requirements
across multiple hosts without duplication.
formats for Quadlet artifacts (
artifact.container.d/*.conf,artifact.volume.d/*.conf)and native systemd drop-ins for socket units (
artifact.socket.d/*.conf).artifacts from host-specific overlays and drop-ins.
default, with an explicit CLI/env override for selecting hosts/.
mechanism where host.yaml declares an explicit service list (no groups/roles).
into a concrete desired state before diff/plan/apply, applying native drop-in
ordering (lexicographic) with host overrides layered after base drop-ins.
artifacts, invalid file types, or host selections that reference undefined
services, with explicit diagnostics.
evaluation produces concrete desired state.
placeholder substitution.
systemd drop-ins in validation and evaluation rules.
that are materialized to bounded host paths (e.g.,
/etc/<service>) and thenmounted or referenced by Quadlets.
host-specific overrides using whole-file replacement and directory layering.
config formats and MUST preserve explicit boundaries to avoid becoming a
general configuration management system.
Key Entities (include if feature involves data)
per-host overlays.
hosts/<host>/host.yamlfile that declares thehost identity and selected services.
mechanisms.
included in desired state.
evaluation, passed to planning and apply.
services/directory containing reusablebase artifacts and their native drop-ins.
hosts/<host>/overrides/tree containing host-specificdrop-ins layered after service selection.
materialized to bounded host paths and referenced by Quadlets.
layer on top of base config payloads.
Repository Structure Example
Example
hosts/kadath/host.yaml:Constitution Alignment (mandatory)
filesystem and systemd interactions remain in boundary layers.
explicit data structures.
outputs with no unintended changes.
clear diagnostics.
plan/audit data.
evaluation produces concrete state.
deterministic output.
Success Criteria (mandatory)
Measurable Outcomes
concrete desired state.
diagnostics before planning.
selection and overlays to at least three hosts without duplicating base
artifacts.
on a single host.
Assumptions
Risks & Open Questions
re-provisioning may require explicit operator configuration.
clear and actionable.
must avoid surprising merges.