constitution firewall
This commit is contained in:
@@ -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
|
||||
|
||||
### [PRINCIPLE_1_NAME]
|
||||
<!-- Example: I. Library-First -->
|
||||
[PRINCIPLE_1_DESCRIPTION]
|
||||
<!-- Example: Every feature starts as a standalone library; Libraries must be self-contained, independently testable, documented; Clear purpose required - no organizational-only libraries -->
|
||||
### I. Constitution Authority
|
||||
This constitution is the source of truth for Speckit-driven planning and
|
||||
implementation work in this repository. Plans, specs, tasks, and runtime
|
||||
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]
|
||||
<!-- Example: II. CLI Interface -->
|
||||
[PRINCIPLE_2_DESCRIPTION]
|
||||
<!-- Example: Every library exposes functionality via CLI; Text in/out protocol: stdin/args → stdout, errors → stderr; Support JSON + human-readable formats -->
|
||||
### II. Module and Host Boundaries
|
||||
Code MUST live in the directory that owns the behavior. Shared feature logic
|
||||
belongs under `modules/`; host-specific assembly belongs under `hosts/<name>/`;
|
||||
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]
|
||||
<!-- Example: III. Test-First (NON-NEGOTIABLE) -->
|
||||
[PRINCIPLE_3_DESCRIPTION]
|
||||
<!-- Example: TDD mandatory: Tests written → User approved → Tests fail → Then implement; Red-Green-Refactor cycle strictly enforced -->
|
||||
### III. Host-Local Firewall Ownership
|
||||
Any host that contains firewall rules MUST keep firewall-related logic in
|
||||
`hosts/<name>/firewall.nix`. Host `configuration.nix` files MAY import that
|
||||
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]
|
||||
<!-- Example: IV. Integration Testing -->
|
||||
[PRINCIPLE_4_DESCRIPTION]
|
||||
<!-- Example: Focus areas requiring integration tests: New library contract tests, Contract changes, Inter-service communication, Shared schemas -->
|
||||
### IV. Nix Structure and Ordering
|
||||
Nix code MUST preserve grouped parents when they have multiple children and
|
||||
MUST flatten only single-child chains. Siblings that share a parent MUST live
|
||||
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]
|
||||
<!-- Example: V. Observability, VI. Versioning & Breaking Changes, VII. Simplicity -->
|
||||
[PRINCIPLE_5_DESCRIPTION]
|
||||
<!-- Example: Text I/O ensures debuggability; Structured logging required; Or: MAJOR.MINOR.BUILD format; Or: Start simple, YAGNI principles -->
|
||||
### V. Secure Host and Secrets Discipline
|
||||
Secret-dependent behavior MUST stay behind `config.my.secureHost`. Secrets MUST
|
||||
live in the appropriate `secrets/*.yaml` file by purpose, and hosts marked
|
||||
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]
|
||||
<!-- Example: Additional Constraints, Security Requirements, Performance Standards, etc. -->
|
||||
## Repository Constraints
|
||||
|
||||
[SECTION_2_CONTENT]
|
||||
<!-- Example: Technology stack requirements, compliance standards, deployment policies, etc. -->
|
||||
- Host definitions live in `hosts/<name>/configuration.nix` with optional
|
||||
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]
|
||||
<!-- Example: Development Workflow, Review Process, Quality Gates, etc. -->
|
||||
## Delivery Workflow
|
||||
|
||||
[SECTION_3_CONTENT]
|
||||
<!-- Example: Code review requirements, testing gates, deployment approval process, etc. -->
|
||||
- Every plan MUST include a constitution check that validates module ownership,
|
||||
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
|
||||
<!-- Example: Constitution supersedes all other practices; Amendments require documentation, approval, migration plan -->
|
||||
|
||||
[GOVERNANCE_RULES]
|
||||
<!-- Example: All PRs/reviews must verify compliance; Complexity must be justified; Use [GUIDANCE_FILE] for runtime development guidance -->
|
||||
This constitution supersedes conflicting Speckit planning assumptions for this
|
||||
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]
|
||||
<!-- Example: Version: 2.1.1 | Ratified: 2025-06-13 | Last Amended: 2025-07-16 -->
|
||||
**Version**: 1.0.0 | **Ratified**: 2026-04-01 | **Last Amended**: 2026-04-01
|
||||
|
||||
@@ -31,7 +31,12 @@
|
||||
|
||||
*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
|
||||
|
||||
|
||||
@@ -89,11 +89,13 @@
|
||||
- **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-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:*
|
||||
|
||||
- **FR-006**: 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-007**: System MUST authenticate users via [NEEDS CLARIFICATION: auth method not specified - email/password, SSO, OAuth?]
|
||||
- **FR-008**: System MUST retain user data for [NEEDS CLARIFICATION: retention period not specified]
|
||||
|
||||
### Key Entities *(include if feature involves data)*
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ description: "Task list template for feature implementation"
|
||||
- **[P]**: Can run in parallel (different files, no dependencies)
|
||||
- **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3)
|
||||
- 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
|
||||
|
||||
@@ -68,6 +70,8 @@ Examples of foundational tasks (adjust based on your project):
|
||||
- [ ] T007 Create base models/entities that all stories depend on
|
||||
- [ ] T008 Configure error handling and logging infrastructure
|
||||
- [ ] 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
|
||||
|
||||
@@ -83,17 +87,17 @@ Examples of foundational tasks (adjust based on your project):
|
||||
|
||||
> **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] Integration test for [user journey] in tests/integration/test_[name].py
|
||||
- [ ] T011 [P] [US1] Contract test for [endpoint] in tests/contract/test_[name].py
|
||||
- [ ] T012 [P] [US1] Integration test for [user journey] in tests/integration/test_[name].py
|
||||
|
||||
### Implementation for User Story 1
|
||||
|
||||
- [ ] T012 [P] [US1] Create [Entity1] model in src/models/[entity1].py
|
||||
- [ ] T013 [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 [endpoint/feature] in src/[location]/[file].py
|
||||
- [ ] T016 [US1] Add validation and error handling
|
||||
- [ ] T017 [US1] Add logging for user story 1 operations
|
||||
- [ ] T013 [P] [US1] Create [Entity1] model in src/models/[entity1].py
|
||||
- [ ] T014 [P] [US1] Create [Entity2] model in src/models/[entity2].py
|
||||
- [ ] T015 [US1] Implement [Service] in src/services/[service].py (depends on T013, T014)
|
||||
- [ ] T016 [US1] Implement [endpoint/feature] in src/[location]/[file].py
|
||||
- [ ] T017 [US1] Add validation and error handling
|
||||
- [ ] T018 [US1] Add logging for user story 1 operations
|
||||
|
||||
**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) ⚠️
|
||||
|
||||
- [ ] T018 [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
|
||||
- [ ] T019 [P] [US2] Contract test for [endpoint] in tests/contract/test_[name].py
|
||||
- [ ] T020 [P] [US2] Integration test for [user journey] in tests/integration/test_[name].py
|
||||
|
||||
### Implementation for User Story 2
|
||||
|
||||
- [ ] T020 [P] [US2] Create [Entity] model in src/models/[entity].py
|
||||
- [ ] T021 [US2] Implement [Service] in src/services/[service].py
|
||||
- [ ] T022 [US2] Implement [endpoint/feature] in src/[location]/[file].py
|
||||
- [ ] T023 [US2] Integrate with User Story 1 components (if needed)
|
||||
- [ ] T021 [P] [US2] Create [Entity] model in src/models/[entity].py
|
||||
- [ ] T022 [US2] Implement [Service] in src/services/[service].py
|
||||
- [ ] T023 [US2] Implement [endpoint/feature] in src/[location]/[file].py
|
||||
- [ ] T024 [US2] Integrate with User Story 1 components (if needed)
|
||||
|
||||
**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) ⚠️
|
||||
|
||||
- [ ] T024 [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
|
||||
- [ ] T025 [P] [US3] Contract test for [endpoint] in tests/contract/test_[name].py
|
||||
- [ ] T026 [P] [US3] Integration test for [user journey] in tests/integration/test_[name].py
|
||||
|
||||
### Implementation for User Story 3
|
||||
|
||||
- [ ] T026 [P] [US3] Create [Entity] model in src/models/[entity].py
|
||||
- [ ] T027 [US3] Implement [Service] in src/services/[service].py
|
||||
- [ ] T028 [US3] Implement [endpoint/feature] in src/[location]/[file].py
|
||||
- [ ] T027 [P] [US3] Create [Entity] model in src/models/[entity].py
|
||||
- [ ] T028 [US3] Implement [Service] in src/services/[service].py
|
||||
- [ ] T029 [US3] Implement [endpoint/feature] in src/[location]/[file].py
|
||||
|
||||
**Checkpoint**: All user stories should now be independently functional
|
||||
|
||||
|
||||
@@ -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`.
|
||||
- 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.
|
||||
- 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.
|
||||
- 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.
|
||||
@@ -21,6 +22,7 @@
|
||||
- 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.
|
||||
- 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
|
||||
config.services.jellyfin.enable = true; # preferred single-leaf form
|
||||
@@ -78,6 +80,7 @@ config.services = {
|
||||
|
||||
## 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 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.
|
||||
- Validation: Confirm discoverability within two clicks (constitution → reference map/playbook), secrets map completeness, and alignment with success criteria SC-001–SC-004.
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
## Hosts and Roles
|
||||
- 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`.
|
||||
- Active NixOS hosts: `workstation`, `server`, `miniserver`, `galaxy`, `emacs`, `vps`.
|
||||
- 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`.
|
||||
- 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.
|
||||
- Host firewall placement: host-specific firewall rules, NAT, nftables tables, and forward-port definitions belong in `hosts/<name>/firewall.nix`.
|
||||
|
||||
## Secrets Map
|
||||
- Files and purposes:
|
||||
|
||||
@@ -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`.
|
||||
- **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).
|
||||
|
||||
## 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).
|
||||
|
||||
Reference in New Issue
Block a user