AI-Development-Server/SERVER-STANDARDS.md

180 lines
8.2 KiB
Markdown

# Server Standards
These standards apply to infrastructure documentation, installation scripts, operational scripts, configuration templates, tests, and manual server changes for Atlas.
Unknowns must be written exactly as `TODO: Confirm during the relevant implementation phase.`
## Bash Script Conventions
- Use Bash for repository-managed server automation unless a better tool is explicitly adopted by an ADR.
- Start executable scripts with `#!/usr/bin/env bash`.
- Use `set -Eeuo pipefail`.
- Prefer explicit named variables over positional parameters.
- Quote variable expansions unless word splitting is intentional.
- Keep functions small and named by behaviour.
- Use long option names where they improve readability.
- Avoid hidden dependencies on the current working directory. Resolve paths explicitly.
- Place shared helpers only when repeated logic justifies them.
## Idempotency
- Scripts must be safe to run more than once.
- Check current state before making changes.
- Prefer create-or-update behaviour over delete-and-recreate behaviour.
- Do not assume users, packages, directories, mounts, services, firewall rules, or configuration files are absent.
- Print a clear message when a step is already satisfied.
- Avoid overwriting local state unless the script owns that file and has a documented rollback path.
## Error Handling
- Fail early when prerequisites are missing.
- Use meaningful error messages that identify the failed operation.
- Do not continue after a failed critical step.
- Use traps when cleanup or failure context is useful.
- Validate inputs before making changes.
- Treat unset variables as errors.
## Logging
- Print concise progress messages.
- Use consistent prefixes: `[INFO]`, `[WARN]`, `[ERROR]`, `[OK]`.
- Do not print secrets, tokens, passwords, connection strings, private keys, or certificate material.
- Long-term logs must be stored outside this repository.
- Repository scripts may write temporary logs only under documented temporary paths and must clean them up where practical.
## Exit Codes
- `0`: success.
- `1`: general failure.
- `2`: invalid arguments or missing required input.
- `3`: unmet prerequisite.
- `4`: validation failed.
- `5`: unsafe state detected.
## File Ownership and Permissions
- Repository files should be owned by the dedicated development user.
- Use executable permissions only for scripts intended to be run directly.
- Use root ownership only for system files that require it.
- Do not change ownership recursively outside documented paths.
- Secrets outside the repository must use the narrowest practical permissions.
- Templates in the repository must not contain live secrets.
## Configuration Locations
- Repository-managed templates belong under `config/` or `templates/`.
- Generated or live service configuration belongs in the service's normal system location, usually under `/etc`, and should be produced from repository templates where practical.
- Local overrides must not be committed.
- Application-specific paths must not be locked in until the relevant implementation phase confirms them.
## Service Naming
- Use clear, stable service names.
- Prefer names that identify the application or function rather than the implementation detail.
- Prefix Atlas-specific helper services consistently when a naming convention is established.
- Avoid renaming services without a migration and rollback note.
- Service naming convention: `TODO: Confirm during the relevant implementation phase.`
## systemd Conventions
- Store systemd unit templates under `config/systemd/` or `templates/` when introduced.
- Install live units under the appropriate systemd directory only through documented scripts.
- Run `systemctl daemon-reload` after unit changes.
- Enable services only when the intended boot behaviour is documented.
- Prefer environment files outside the repository for secret-bearing configuration.
- Include validation steps for service status and logs.
## nginx Conventions
- Store nginx templates under `config/nginx/` or `templates/` when introduced.
- Do not commit live TLS private keys or certificates.
- Validate nginx configuration before reloads.
- Reload nginx only after successful validation.
- Keep reverse proxy rules explicit and reviewed.
- Public DNS, TLS, and exposure policy: `TODO: Confirm during the relevant implementation phase.`
## SQL Server Data Locations
- `/sql` is the intended SQL data volume.
- SQL Server data, logs, and backups must not be stored in this repository.
- SQL Server paths must be confirmed during the SQL Server implementation phase before automation is created.
- Backup destination, retention, encryption, and restore validation are not yet established.
## Repository Locations
- `/srv` is the primary development volume.
- Git repositories should live under `/srv/repos`.
- This infrastructure repository lives at `/srv/repos/AI-Development-Server`.
- Do not assume application repository names or paths until they are confirmed.
## Deployment Locations
- Deployment locations must be outside this infrastructure repository.
- Deployed applications should be separated from source repositories and build artefacts.
- Intended deployment root: `TODO: Confirm during the relevant implementation phase.`
- Deployment scripts must document rollback and validation.
## Backup Locations
- Backups must not be committed.
- Backup storage location: `TODO: Confirm during the relevant implementation phase.`
- Backup retention: `TODO: Confirm during the relevant implementation phase.`
- Backup encryption: `TODO: Confirm during the relevant implementation phase.`
- Restore testing schedule: `TODO: Confirm during the relevant implementation phase.`
## Temporary File Handling
- Use `mktemp` for script-created temporary files and directories.
- Clean temporary files on exit where practical.
- Do not place temporary files in the repository unless they are intentionally version-controlled examples.
- Never store secret-bearing temporary files in world-readable locations.
## Secrets Management
- Never commit live secrets, tokens, passwords, private keys, SQL backups, `.env` files, generated credentials, or Codex authentication material.
- Use `.example`, `.template`, placeholder values, or documented environment variable names.
- Store secret-bearing live configuration outside the repository.
- Rotate credentials after suspected exposure.
- Secret storage mechanism: `TODO: Confirm during the relevant implementation phase.`
## Package Installation
- Installation scripts must use the system package manager where practical.
- Add third-party package repositories only when documented and justified.
- Validate repository signing keys and sources.
- Avoid installing packages in ad hoc scripts without recording why they are needed.
- Do not install application dependencies globally unless required.
## Version Pinning
- Pin versions when reproducibility, compatibility, or security requires it.
- Document why a version is pinned and when it should be reviewed.
- If using latest available packages, document that choice.
- Do not record planned component versions as installed until verified.
## Testing Requirements
- Add smoke tests for scripts that change services, network state, mounts, databases, deployments, or backup behaviour.
- Tests should verify observable outcomes, not only exit codes.
- Tests must avoid requiring secrets where practical.
- Tests must not mutate production data unless explicitly designed and approved.
- Run relevant tests before committing.
## Documentation Requirements
- Update documentation with every change that affects rebuild, operation, security, backup, restore, deployment, or architecture.
- Update [docs/BUILD-LOG.md](docs/BUILD-LOG.md) for meaningful manual or automated infrastructure milestones.
- Update runbooks when manual steps become automated.
- Link related ADRs where decisions are recorded.
- Use UK English.
## Change Control
- Plan substantial changes before implementation.
- Human approval is required for architecture changes.
- Review `git diff` before commit.
- Do not commit without explicit approval.
- Keep commits focused and reversible.
- Document rollback expectations for risky changes.
- Git rollback restores repository state only. It does not automatically undo server changes already applied.