Project and Change Governance
- Type: Policy
- Status: Current
- Scope: Repository, fleet changes, and project documentation
- Canonical sources:
AGENTS.md;README.md(Change Lifecycle and Project Tracking in Forgejo);.forgejo/ai-review.md; Documentation Map and Scope- Last verified: Source commit
556df88494686003b1c4f20c8e0b99b5afc16a6e(2026-09-12)- Review triggers: Changes to branching, review, validation, deployment, project tracking, documentation ownership, or publication policy
This policy defines where work is tracked, how a proposed change progresses,
and what evidence is required before it is considered complete. It applies to
human and agent-authored work in nixos-config.
Policy
Planned and active work belongs in Forgejo. Executable configuration belongs in the source repository. Knowledge that remains useful after work closes belongs in the wiki. No one surface should be used as a substitute for the others.
Changes must receive validation and rollout evidence proportional to their blast radius. Completion means more than merging code: any required live evidence must exist, unfinished work must remain tracked, and durable knowledge must have an appropriate home.
Work tracking
Use one Forgejo milestone for a project or workstream and one issue for each meaningful phase or deliverable. Issues must be executable without a local planning file and should state:
- context and intended outcome;
- scope, relevant hosts, services, and repository paths;
- constraints, risks, and rollback requirements;
- ordered work where sequencing or handoff matters;
- objective completion criteria and required evidence.
Use prefixed labels for filterable scope, such as project:<workstream>,
host:<name>, host:fleet, service:<name>, and phase:<name>. The milestone
defines the project boundary; labels support queries across projects and do not
replace it.
An issue remains the record of progress, pending decisions, validation, and
acceptance evidence while work is active. Do not create a projects/ planning
tree in the source repository, and do not move live checklists into the wiki.
Change path by risk
| Change shape | Normal path | Minimum evidence |
|---|---|---|
| Documentation only | Focused review; direct wiki or repository commit is acceptable | Content, link, and formatting review appropriate to the edited pages |
| Small, bounded configuration change with limited blast radius | Direct commit to main may be used |
Targeted validation and, where applicable, just test on an affected host |
| Cross-cutting, service, CI/workflow, security, or multi-host change | Forgejo issue, dedicated branch, and merge request sharing the issue milestone | Relevant local validation, required MR checks, and rollout evidence below |
| Irreversible or externally stateful change | Tracked change path plus an explicit recovery checkpoint | Risk-specific backup or annotated pre-change tag, rollback plan, validation, and live evidence |
Examples of changes that require special recovery treatment include disk or filesystem migration, secret or key rotation, host reprovisioning, bootloader/encryption changes, and service moves that mutate external state. Routine package additions and ordinary rebuilds do not justify recovery tags.
Validation and review
Choose gates by what the change affects, not merely by filename:
- Nix modules or host configuration require
nix flake check. - Shell, updater, workflow, and policy changes require their relevant lint or regression tests.
- Changes crossing those boundaries require all applicable gates.
- New
.nixfiles must be staged before flake validation because flakes cannot see untracked files. - Diagnostic warnings must be reviewed even when they appear unrelated.
Merge requests must reference the governing issue, share its milestone, and state completed validation plus any live evidence still outstanding. Required Forgejo checks must pass before merge. AI review supplements these deterministic gates; it does not replace them.
Before committing or publishing, update the working tree with
git pull --rebase --autostash. Forgejo automation can update flake.lock, so
this is an operational concurrency requirement rather than cosmetic hygiene.
Canary and deployment evidence
Every deployment-affecting change needs a canary appropriate to its risk. Where both a documented command and a systemd service are user-facing interfaces, exercise both.
Use just test for NixOS test activation because it preserves the active
specialisation. For remote testing, create an auto-update hold before the test
and release it only after validation. Electra hardware-specific work must also
record whether base, igpu, or dgpu was active.
Fleet-wide and auto-update changes require one genuine deployment and an immediate no-op follow-up before issue closure. A merge request should use a closing keyword only when all required deployment evidence already exists. If evidence must be collected after merge, leave the issue open and close it after recording the merge and deployment results.
Knowledge promotion and closure
Before closing an issue:
- Record the final validation and deployment evidence in Forgejo.
- Ensure every unfinished item is represented by an open issue.
- Promote reusable procedures, reference facts, policies, and consequential rationale to the appropriate wiki page.
- Link the issue to that durable material where it helps future readers.
- Retire one-off logs and obsolete planning commentary instead of copying them into permanent documentation.
The Documentation Map and Scope defines the full ownership boundary. Use Architecture Decisions for lasting rationale and Operations and Runbooks for reusable procedures.
Exceptions and enforcement
The direct-commit path is an accepted exception for genuinely bounded work; it is not a way to bypass validation. If scope expands during implementation, move the work to an issue, branch, and merge request before publication.
The person or agent publishing a change is responsible for selecting and recording the gates. Reviewers should block completion when the evidence does not match the risk, when live behavior is inferred from configuration without required verification, or when durable knowledge exists only in conversation or agent memory.