constitution firewall

This commit is contained in:
Danilo Reyes
2026-04-01 23:59:58 -06:00
parent 4eeed32002
commit 78c37081d7
7 changed files with 129 additions and 57 deletions

View File

@@ -1,50 +1,101 @@
# [PROJECT_NAME] Constitution <!--
<!-- Example: Spec Constitution, TaskFlow Constitution, etc. --> Sync Impact Report
- Version change: template -> 1.0.0
- Modified principles:
- Template Principle 1 -> I. Constitution Authority
- Template Principle 2 -> II. Module and Host Boundaries
- Template Principle 3 -> III. Host-Local Firewall Ownership
- Template Principle 4 -> IV. Nix Structure and Ordering
- Template Principle 5 -> V. Secure Host and Secrets Discipline
- Added sections:
- Repository Constraints
- Delivery Workflow
- Removed sections:
- None
- Templates requiring updates:
- ✅ updated `.specify/templates/plan-template.md`
- ✅ updated `.specify/templates/spec-template.md`
- ✅ updated `.specify/templates/tasks-template.md`
- ✅ updated `docs/constitution.md`
- ✅ updated `docs/reference/index.md`
- ✅ updated `specs/001-ai-docs/research.md`
- ✅ no `.specify/templates/commands/*.md` files present
- Follow-up TODOs:
- None
-->
# NixOS Repository Constitution
## Core Principles ## Core Principles
### [PRINCIPLE_1_NAME] ### I. Constitution Authority
<!-- Example: I. Library-First --> This constitution is the source of truth for Speckit-driven planning and
[PRINCIPLE_1_DESCRIPTION] implementation work in this repository. Plans, specs, tasks, and runtime
<!-- Example: Every feature starts as a standalone library; Libraries must be self-contained, independently testable, documented; Clear purpose required - no organizational-only libraries --> guidance MUST align with it. When another document conflicts with this
constitution, the conflicting document MUST be updated in the same change set
or the conflict MUST be recorded in `specs/001-ai-docs/research.md`.
### [PRINCIPLE_2_NAME] ### II. Module and Host Boundaries
<!-- Example: II. CLI Interface --> Code MUST live in the directory that owns the behavior. Shared feature logic
[PRINCIPLE_2_DESCRIPTION] belongs under `modules/`; host-specific assembly belongs under `hosts/<name>/`;
<!-- Example: Every library exposes functionality via CLI; Text in/out protocol: stdin/args → stdout, errors → stderr; Support JSON + human-readable formats --> factory helpers belong under `modules/factories/`; repo-wide shared options
belong under `modules/modules.nix` or the relevant shared module. New behavior
MUST NOT be placed in an unrelated host or module file for convenience.
### [PRINCIPLE_3_NAME] ### III. Host-Local Firewall Ownership
<!-- Example: III. Test-First (NON-NEGOTIABLE) --> Any host that contains firewall rules MUST keep firewall-related logic in
[PRINCIPLE_3_DESCRIPTION] `hosts/<name>/firewall.nix`. Host `configuration.nix` files MAY import that
<!-- Example: TDD mandatory: Tests written → User approved → Tests fail → Then implement; Red-Green-Refactor cycle strictly enforced --> file, but MUST NOT become the long-term home for firewall rule definitions,
NAT rules, nftables tables, forward-port rules, or other firewall-specific
logic. Firewall changes in specs, plans, and task lists MUST reference the
host-local `firewall.nix` path explicitly.
### [PRINCIPLE_4_NAME] ### IV. Nix Structure and Ordering
<!-- Example: IV. Integration Testing --> Nix code MUST preserve grouped parents when they have multiple children and
[PRINCIPLE_4_DESCRIPTION] MUST flatten only single-child chains. Siblings that share a parent MUST live
<!-- Example: Focus areas requiring integration tests: New library contract tests, Contract changes, Inter-service communication, Shared schemas --> under one parent block instead of being split across disconnected assignments.
Within module bodies, `options` MUST appear before `config`. Within attribute
sets, `inherit` statements MUST come first, then boolean leaves, then other
leaf assignments, then nested attribute sets.
### [PRINCIPLE_5_NAME] ### V. Secure Host and Secrets Discipline
<!-- Example: V. Observability, VI. Versioning & Breaking Changes, VII. Simplicity --> Secret-dependent behavior MUST stay behind `config.my.secureHost`. Secrets MUST
[PRINCIPLE_5_DESCRIPTION] live in the appropriate `secrets/*.yaml` file by purpose, and hosts marked
<!-- Example: Text I/O ensures debuggability; Structured logging required; Or: MAJOR.MINOR.BUILD format; Or: Start simple, YAGNI principles --> non-secure MUST avoid secret-dependent services and secret loading. Proxy-only
or network-only changes MUST still respect secret ownership, secure-host
gating, and host-local boundaries.
## [SECTION_2_NAME] ## Repository Constraints
<!-- Example: Additional Constraints, Security Requirements, Performance Standards, etc. -->
[SECTION_2_CONTENT] - Host definitions live in `hosts/<name>/configuration.nix` with optional
<!-- Example: Technology stack requirements, compliance standards, deployment policies, etc. --> imports such as `hosts/<name>/firewall.nix` and `hosts/<name>/toggles.nix`.
- Module categories remain `apps`, `dev`, `scripts`, `servers`, `services`,
`shell`, `websites`, `network`, `users`, and `nix`, with feature directories
preferred over new flat modules.
- Service ports intrinsic to a server module SHOULD live with that module;
miscellaneous shared ports SHOULD live in `my.ports`.
- Firewall rules, NAT, nftables tables, and forward-port declarations for a
host MUST be reviewed as one unit inside that host's `firewall.nix`.
## [SECTION_3_NAME] ## Delivery Workflow
<!-- Example: Development Workflow, Review Process, Quality Gates, etc. -->
[SECTION_3_CONTENT] - Every plan MUST include a constitution check that validates module ownership,
<!-- Example: Code review requirements, testing gates, deployment approval process, etc. --> host ownership, secure-host impact, and whether firewall work belongs in
`hosts/<name>/firewall.nix`.
- Every spec that changes networking or exposure MUST state which host owns the
change and which firewall file is affected.
- Every task list that includes firewall work MUST name the concrete
`hosts/<name>/firewall.nix` path.
- Runtime guidance docs that describe repository structure MUST be updated when
host boundary rules change.
## Governance ## Governance
<!-- Example: Constitution supersedes all other practices; Amendments require documentation, approval, migration plan -->
[GOVERNANCE_RULES] This constitution supersedes conflicting Speckit planning assumptions for this
<!-- Example: All PRs/reviews must verify compliance; Complexity must be justified; Use [GUIDANCE_FILE] for runtime development guidance --> repository. Amendments MUST be made in the same change set as any dependent
template or runtime guidance updates. Versioning follows semantic versioning:
MAJOR for incompatible governance changes or principle removals, MINOR for new
principles or materially expanded rules, PATCH for clarifications that do not
change required behavior. Compliance review is mandatory for every plan, spec,
and tasks artifact that claims alignment with this constitution.
**Version**: [CONSTITUTION_VERSION] | **Ratified**: [RATIFICATION_DATE] | **Last Amended**: [LAST_AMENDED_DATE] **Version**: 1.0.0 | **Ratified**: 2026-04-01 | **Last Amended**: 2026-04-01
<!-- Example: Version: 2.1.1 | Ratified: 2025-06-13 | Last Amended: 2025-07-16 -->

View File

@@ -31,7 +31,12 @@
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
[Gates determined based on constitution file] - Confirm each change lives in the directory that owns the behavior.
- Confirm shared logic stays in `modules/` and host-specific assembly stays in
`hosts/<name>/`.
- Confirm any firewall, NAT, nftables, or port-forwarding work is scoped to
`hosts/<name>/firewall.nix` for the affected host.
- Confirm any secret-dependent behavior respects `config.my.secureHost`.
## Project Structure ## Project Structure

View File

@@ -89,11 +89,13 @@
- **FR-003**: Users MUST be able to [key interaction, e.g., "reset their password"] - **FR-003**: Users MUST be able to [key interaction, e.g., "reset their password"]
- **FR-004**: System MUST [data requirement, e.g., "persist user preferences"] - **FR-004**: System MUST [data requirement, e.g., "persist user preferences"]
- **FR-005**: System MUST [behavior, e.g., "log all security events"] - **FR-005**: System MUST [behavior, e.g., "log all security events"]
- **FR-006**: If the feature changes host firewall behavior, the spec MUST name
the affected `hosts/<name>/firewall.nix` file explicitly.
*Example of marking unclear requirements:* *Example of marking unclear requirements:*
- **FR-006**: System MUST authenticate users via [NEEDS CLARIFICATION: auth method not specified - email/password, SSO, OAuth?] - **FR-007**: System MUST authenticate users via [NEEDS CLARIFICATION: auth method not specified - email/password, SSO, OAuth?]
- **FR-007**: System MUST retain user data for [NEEDS CLARIFICATION: retention period not specified] - **FR-008**: System MUST retain user data for [NEEDS CLARIFICATION: retention period not specified]
### Key Entities *(include if feature involves data)* ### Key Entities *(include if feature involves data)*

View File

@@ -17,6 +17,8 @@ description: "Task list template for feature implementation"
- **[P]**: Can run in parallel (different files, no dependencies) - **[P]**: Can run in parallel (different files, no dependencies)
- **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3) - **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3)
- Include exact file paths in descriptions - Include exact file paths in descriptions
- If firewall behavior changes, tasks MUST reference `hosts/<name>/firewall.nix`
instead of only `hosts/<name>/configuration.nix`
## Path Conventions ## Path Conventions
@@ -68,6 +70,8 @@ Examples of foundational tasks (adjust based on your project):
- [ ] T007 Create base models/entities that all stories depend on - [ ] T007 Create base models/entities that all stories depend on
- [ ] T008 Configure error handling and logging infrastructure - [ ] T008 Configure error handling and logging infrastructure
- [ ] T009 Setup environment configuration management - [ ] T009 Setup environment configuration management
- [ ] T010 If networking changes, update the affected `hosts/<name>/firewall.nix`
and import wiring in `hosts/<name>/configuration.nix`
**Checkpoint**: Foundation ready - user story implementation can now begin in parallel **Checkpoint**: Foundation ready - user story implementation can now begin in parallel
@@ -83,17 +87,17 @@ Examples of foundational tasks (adjust based on your project):
> **NOTE: Write these tests FIRST, ensure they FAIL before implementation** > **NOTE: Write these tests FIRST, ensure they FAIL before implementation**
- [ ] T010 [P] [US1] Contract test for [endpoint] in tests/contract/test_[name].py - [ ] T011 [P] [US1] Contract test for [endpoint] in tests/contract/test_[name].py
- [ ] T011 [P] [US1] Integration test for [user journey] in tests/integration/test_[name].py - [ ] T012 [P] [US1] Integration test for [user journey] in tests/integration/test_[name].py
### Implementation for User Story 1 ### Implementation for User Story 1
- [ ] T012 [P] [US1] Create [Entity1] model in src/models/[entity1].py - [ ] T013 [P] [US1] Create [Entity1] model in src/models/[entity1].py
- [ ] T013 [P] [US1] Create [Entity2] model in src/models/[entity2].py - [ ] T014 [P] [US1] Create [Entity2] model in src/models/[entity2].py
- [ ] T014 [US1] Implement [Service] in src/services/[service].py (depends on T012, T013) - [ ] T015 [US1] Implement [Service] in src/services/[service].py (depends on T013, T014)
- [ ] T015 [US1] Implement [endpoint/feature] in src/[location]/[file].py - [ ] T016 [US1] Implement [endpoint/feature] in src/[location]/[file].py
- [ ] T016 [US1] Add validation and error handling - [ ] T017 [US1] Add validation and error handling
- [ ] T017 [US1] Add logging for user story 1 operations - [ ] T018 [US1] Add logging for user story 1 operations
**Checkpoint**: At this point, User Story 1 should be fully functional and testable independently **Checkpoint**: At this point, User Story 1 should be fully functional and testable independently
@@ -107,15 +111,15 @@ Examples of foundational tasks (adjust based on your project):
### Tests for User Story 2 (OPTIONAL - only if tests requested) ⚠️ ### Tests for User Story 2 (OPTIONAL - only if tests requested) ⚠️
- [ ] T018 [P] [US2] Contract test for [endpoint] in tests/contract/test_[name].py - [ ] T019 [P] [US2] Contract test for [endpoint] in tests/contract/test_[name].py
- [ ] T019 [P] [US2] Integration test for [user journey] in tests/integration/test_[name].py - [ ] T020 [P] [US2] Integration test for [user journey] in tests/integration/test_[name].py
### Implementation for User Story 2 ### Implementation for User Story 2
- [ ] T020 [P] [US2] Create [Entity] model in src/models/[entity].py - [ ] T021 [P] [US2] Create [Entity] model in src/models/[entity].py
- [ ] T021 [US2] Implement [Service] in src/services/[service].py - [ ] T022 [US2] Implement [Service] in src/services/[service].py
- [ ] T022 [US2] Implement [endpoint/feature] in src/[location]/[file].py - [ ] T023 [US2] Implement [endpoint/feature] in src/[location]/[file].py
- [ ] T023 [US2] Integrate with User Story 1 components (if needed) - [ ] T024 [US2] Integrate with User Story 1 components (if needed)
**Checkpoint**: At this point, User Stories 1 AND 2 should both work independently **Checkpoint**: At this point, User Stories 1 AND 2 should both work independently
@@ -129,14 +133,14 @@ Examples of foundational tasks (adjust based on your project):
### Tests for User Story 3 (OPTIONAL - only if tests requested) ⚠️ ### Tests for User Story 3 (OPTIONAL - only if tests requested) ⚠️
- [ ] T024 [P] [US3] Contract test for [endpoint] in tests/contract/test_[name].py - [ ] T025 [P] [US3] Contract test for [endpoint] in tests/contract/test_[name].py
- [ ] T025 [P] [US3] Integration test for [user journey] in tests/integration/test_[name].py - [ ] T026 [P] [US3] Integration test for [user journey] in tests/integration/test_[name].py
### Implementation for User Story 3 ### Implementation for User Story 3
- [ ] T026 [P] [US3] Create [Entity] model in src/models/[entity].py - [ ] T027 [P] [US3] Create [Entity] model in src/models/[entity].py
- [ ] T027 [US3] Implement [Service] in src/services/[service].py - [ ] T028 [US3] Implement [Service] in src/services/[service].py
- [ ] T028 [US3] Implement [endpoint/feature] in src/[location]/[file].py - [ ] T029 [US3] Implement [endpoint/feature] in src/[location]/[file].py
**Checkpoint**: All user stories should now be independently functional **Checkpoint**: All user stories should now be independently functional

View File

@@ -11,6 +11,7 @@
- Module auto-import: `modules/modules.nix` auto-imports legacy flat modules under `modules/apps`, `modules/dev`, `modules/scripts`, `modules/servers`, `modules/services`, `modules/shell`, `modules/websites`, and `modules/network`, excluding `librewolf.nix`, and also discovers nested `nixos.nix` files under those trees. `config/base.nix` registers `modules/home-manager.nix` as a Home Manager shared module, which discovers nested `home.nix` files under `modules/` for every Home Manager user. Factories live in `modules/factories/` (`mkserver`, `mkscript`), and shared options are in `modules/nix` and `modules/users`. - Module auto-import: `modules/modules.nix` auto-imports legacy flat modules under `modules/apps`, `modules/dev`, `modules/scripts`, `modules/servers`, `modules/services`, `modules/shell`, `modules/websites`, and `modules/network`, excluding `librewolf.nix`, and also discovers nested `nixos.nix` files under those trees. `config/base.nix` registers `modules/home-manager.nix` as a Home Manager shared module, which discovers nested `home.nix` files under `modules/` for every Home Manager user. Factories live in `modules/factories/` (`mkserver`, `mkscript`), and shared options are in `modules/nix` and `modules/users`.
- Home Manager helper layer: Common Home Manager wrapper logic belongs in `parts/core.nix` helpers under `inputs.self.lib` when it is repeated across multiple `home.nix` modules. Current helpers include split-loader support plus `hmModule`, `hmShellType`, and `hmOnlyUser` for shared enablement and shell-selection patterns. - Home Manager helper layer: Common Home Manager wrapper logic belongs in `parts/core.nix` helpers under `inputs.self.lib` when it is repeated across multiple `home.nix` modules. Current helpers include split-loader support plus `hmModule`, `hmShellType`, and `hmOnlyUser` for shared enablement and shell-selection patterns.
- Hosts and toggles: Host definitions live in `hosts/<name>/configuration.nix` with host-specific toggles in `hosts/<name>/toggles.nix`. The `my` namespace carries toggles for apps/dev/scripts/services/shell, feature flags like `enableProxy` and `enableContainers`, and per-host `interfaces` and `ips` maps. - Hosts and toggles: Host definitions live in `hosts/<name>/configuration.nix` with host-specific toggles in `hosts/<name>/toggles.nix`. The `my` namespace carries toggles for apps/dev/scripts/services/shell, feature flags like `enableProxy` and `enableContainers`, and per-host `interfaces` and `ips` maps.
- Host-local firewall ownership: Hosts that define firewall rules MUST keep firewall-related logic in `hosts/<name>/firewall.nix`, imported from `hosts/<name>/configuration.nix` as needed. Host `configuration.nix` files are the assembly point, not the long-term home for firewall rule definitions.
- Standalone Home Manager hosts: Home-only hosts may live under `hosts/<name>/home.nix` with `hosts/<name>/toggles.nix`, and should only enable modules that have a `home.nix` surface or are otherwise known to be Home Manager-compatible on that platform. - Standalone Home Manager hosts: Home-only hosts may live under `hosts/<name>/home.nix` with `hosts/<name>/toggles.nix`, and should only enable modules that have a `home.nix` surface or are otherwise known to be Home Manager-compatible on that platform.
- Port assignment: Service ports should live with the service module when the port is intrinsic to a server definition under `modules/servers/`. Miscellaneous or host-specific ports that do not belong to a server module should be centralized in `my.ports` in `modules/modules.nix` and referenced via `config.my.ports.*` (use `toString config.my.ports.*` where a string is required). - Port assignment: Service ports should live with the service module when the port is intrinsic to a server definition under `modules/servers/`. Miscellaneous or host-specific ports that do not belong to a server module should be centralized in `my.ports` in `modules/modules.nix` and referenced via `config.my.ports.*` (use `toString config.my.ports.*` where a string is required).
- Main server and proxies: `my.mainServer` selects the host that should serve traffic by default (default `vps`). Reverse proxies use helpers in `parts/core.nix` (`proxy`, `proxyReverse`, `proxyReverseFix`, `proxyReversePrivate`) and pick IPs from `my.ips` plus the hostName/ip set by `mkserver` options. Nginx defaults to `proxyReverse` for any server with `enableProxy = true` unless `useDefaultProxy = false` or the server is listed in the Fix/Private proxy lists. - Main server and proxies: `my.mainServer` selects the host that should serve traffic by default (default `vps`). Reverse proxies use helpers in `parts/core.nix` (`proxy`, `proxyReverse`, `proxyReverseFix`, `proxyReversePrivate`) and pick IPs from `my.ips` plus the hostName/ip set by `mkserver` options. Nginx defaults to `proxyReverse` for any server with `enableProxy = true` unless `useDefaultProxy = false` or the server is listed in the Fix/Private proxy lists.
@@ -21,6 +22,7 @@
- Minimize comments; prefer clear naming and shared helpers (`modules/factories/mkserver.nix`, `modules/factories/mkscript.nix`) to avoid duplication. - Minimize comments; prefer clear naming and shared helpers (`modules/factories/mkserver.nix`, `modules/factories/mkscript.nix`) to avoid duplication.
- Use business-level, technology-agnostic language in AI docs; reserve implementation detail for module code. - Use business-level, technology-agnostic language in AI docs; reserve implementation detail for module code.
- Nix structure: flatten single-child attribute sets into their full path; keep multi-child sets nested for readability; merge siblings under a shared parent; flatten the shallowest subtree first to reduce indentation without losing clarity. - Nix structure: flatten single-child attribute sets into their full path; keep multi-child sets nested for readability; merge siblings under a shared parent; flatten the shallowest subtree first to reduce indentation without losing clarity.
- Parent ownership rule: when a parent has multiple children, keep them grouped under that parent instead of splitting them across scattered assignments. Flatten only single-child chains.
- Nix attribute ordering: prefer `options` before `config` in module bodies; inside attribute sets keep `inherit` statements first, then boolean leaf assignments, then other leaf assignments, then nested attribute sets; when simple leaves and nested children share a parent, place the simple leaves first. - Nix attribute ordering: prefer `options` before `config` in module bodies; inside attribute sets keep `inherit` statements first, then boolean leaf assignments, then other leaf assignments, then nested attribute sets; when simple leaves and nested children share a parent, place the simple leaves first.
```nix ```nix
config.services.jellyfin.enable = true; # preferred single-leaf form config.services.jellyfin.enable = true; # preferred single-leaf form
@@ -78,6 +80,7 @@ config.services = {
## Maintenance Triggers and Update Process ## Maintenance Triggers and Update Process
- Triggers: New factory/helper, new module category, new host, new toggle set, new proxy rule, new secret category/file, change to `my.mainServer` or `my.ips`, stylix scheme changes, or new auto-import filters/import trees. - Triggers: New factory/helper, new module category, new host, new toggle set, new proxy rule, new secret category/file, change to `my.mainServer` or `my.ips`, stylix scheme changes, or new auto-import filters/import trees.
- Triggers: New factory/helper, new module category, new host, new toggle set, new proxy rule, new host firewall ownership rule or `hosts/<name>/firewall.nix` layout change, new secret category/file, change to `my.mainServer` or `my.ips`, stylix scheme changes, or new auto-import filters/import trees.
- Update flow: (1) Amend the relevant module or toggle files; (2) Update `docs/constitution.md` for rules/terminology changes; (3) Update playbooks under `docs/playbooks/` affected by the change; (4) Update `docs/reference/index.md` for navigation paths; (5) Note the decision in `specs/001-ai-docs/research.md` and refresh `quickstart.md` if discoverability shifts. - Update flow: (1) Amend the relevant module or toggle files; (2) Update `docs/constitution.md` for rules/terminology changes; (3) Update playbooks under `docs/playbooks/` affected by the change; (4) Update `docs/reference/index.md` for navigation paths; (5) Note the decision in `specs/001-ai-docs/research.md` and refresh `quickstart.md` if discoverability shifts.
- Validation: Confirm discoverability within two clicks (constitution → reference map/playbook), secrets map completeness, and alignment with success criteria SC-001SC-004. - Validation: Confirm discoverability within two clicks (constitution → reference map/playbook), secrets map completeness, and alignment with success criteria SC-001SC-004.

View File

@@ -39,6 +39,7 @@
## Hosts and Roles ## Hosts and Roles
- NixOS configs: `hosts/<name>/configuration.nix` with toggles in `hosts/<name>/toggles.nix`. - NixOS configs: `hosts/<name>/configuration.nix` with toggles in `hosts/<name>/toggles.nix`.
- Firewall-bearing hosts: keep firewall logic in `hosts/<name>/firewall.nix` and import it from `hosts/<name>/configuration.nix`.
- Standalone Home Manager configs: `hosts/<name>/home.nix` with optional toggles in `hosts/<name>/toggles.nix`. - Standalone Home Manager configs: `hosts/<name>/home.nix` with optional toggles in `hosts/<name>/toggles.nix`.
- Active NixOS hosts: `workstation`, `server`, `miniserver`, `galaxy`, `emacs`, `vps`. - Active NixOS hosts: `workstation`, `server`, `miniserver`, `galaxy`, `emacs`, `vps`.
- Active Home Manager hosts: `mac`. - Active Home Manager hosts: `mac`.
@@ -64,6 +65,7 @@
- Default proxying: any server with `enableProxy = true` gets a `proxyReverse` vhost unless `useDefaultProxy = false` or it is listed in `proxyReverseFix` / `proxyReversePrivate`. - Default proxying: any server with `enableProxy = true` gets a `proxyReverse` vhost unless `useDefaultProxy = false` or it is listed in `proxyReverseFix` / `proxyReversePrivate`.
- Main server selection: `my.mainServer` chooses where services live by default (default `vps`); `mkserver` sets `isLocal` based on this and picks IPs from `my.ips`. - Main server selection: `my.mainServer` chooses where services live by default (default `vps`); `mkserver` sets `isLocal` based on this and picks IPs from `my.ips`.
- Firewall generation: `inputs.self.lib.generateFirewallPorts` combines static ports, additional ports, and service ports from `my.servers` (excluding native firewall services). Use `my.network.firewall` settings and `getServicesWithNativeFirewall` to derive open ports. - Firewall generation: `inputs.self.lib.generateFirewallPorts` combines static ports, additional ports, and service ports from `my.servers` (excluding native firewall services). Use `my.network.firewall` settings and `getServicesWithNativeFirewall` to derive open ports.
- Host firewall placement: host-specific firewall rules, NAT, nftables tables, and forward-port definitions belong in `hosts/<name>/firewall.nix`.
## Secrets Map ## Secrets Map
- Files and purposes: - Files and purposes:

View File

@@ -54,3 +54,8 @@
- **Decision**: Standardize Nix structure so single-child attribute sets are flattened into dotted attrpaths, siblings that share a parent are merged into one nested attribute set, simple leaf assignments appear before nested attribute sets, `inherit` statements appear first within a set, boolean leaves appear before other leaves, and module bodies place `options` before `config`. - **Decision**: Standardize Nix structure so single-child attribute sets are flattened into dotted attrpaths, siblings that share a parent are merged into one nested attribute set, simple leaf assignments appear before nested attribute sets, `inherit` statements appear first within a set, boolean leaves appear before other leaves, and module bodies place `options` before `config`.
- **Rationale**: This keeps modules scan-friendly, reduces unnecessary indentation, and makes the high-signal contract (`options`) appear before implementation (`config`) consistently across the repo. - **Rationale**: This keeps modules scan-friendly, reduces unnecessary indentation, and makes the high-signal contract (`options`) appear before implementation (`config`) consistently across the repo.
- **Alternatives considered**: (a) Leave structure to formatter defaults only (rejected: formatters do not enforce these semantic grouping rules); (b) prefer fully flattened attrpaths everywhere (rejected: harms readability once a parent has multiple children); (c) keep `config` before `options` when it was written first (rejected: makes module interfaces harder to scan). - **Alternatives considered**: (a) Leave structure to formatter defaults only (rejected: formatters do not enforce these semantic grouping rules); (b) prefer fully flattened attrpaths everywhere (rejected: harms readability once a parent has multiple children); (c) keep `config` before `options` when it was written first (rejected: makes module interfaces harder to scan).
## Decision 12 (2026-04-01): Host-local firewall files
- **Decision**: Any host that owns firewall rules MUST keep firewall-related logic in `hosts/<name>/firewall.nix`, with `hosts/<name>/configuration.nix` importing that file rather than accumulating the firewall logic inline.
- **Rationale**: Firewall behavior is a distinct host concern that becomes hard to review and maintain when mixed into general host assembly. A dedicated `firewall.nix` preserves ownership boundaries and makes networking changes easier to audit.
- **Alternatives considered**: (a) Keep firewall rules inline in `configuration.nix` (rejected: mixes host assembly with a dense, security-sensitive subsystem); (b) centralize all firewall logic under `modules/network/` (rejected: hides host-specific rule ownership and deployment context).