Compare commits

...

3 Commits

Author SHA1 Message Date
e67f9d7d4f docs(generic): add commit conventions and autonomous-commit guidance
Document Conventional Commits as the required syntax and spell out when
agentic contributors should commit without approval vs. hold off. The
concern is commit-history pollution from speculative attempts, not the
autonomy itself — a clean commit that ends a thread of work doesn't need
an approval prompt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 12:14:58 +03:00
3261b3274c docs: add README explaining the repo's purpose and usage
Introduce a README that frames this repo as living, cross-project
architectural guidance — required reading for human and agentic
contributors to any project under my control. Explains what's here,
how to use it, and how it evolves.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 12:07:32 +03:00
9db5743531 docs(generic): reflect actual firewalld zone usage (default zone only)
The infrastructure uses only the default zone created at OS install
(FedoraServer on servers, FedoraWorkstation on workstations). Remove the
aspirational internal/wg zone guidance and have deploy.sh resolve the
default zone via firewall-cmd --get-default-zone on the target.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 12:07:29 +03:00
2 changed files with 44 additions and 6 deletions

27
README.md Normal file
View File

@@ -0,0 +1,27 @@
# architecture
Living documentation for the conventions and scaffolding defaults I use across every project I maintain. If you're contributing to one of those projects — as a human or as an AI coding agent — this repo is required reading.
## What this is
A single place where decisions about workspace layout, deployment, infrastructure, service hardening, firewall rules, SELinux posture, and similar cross-cutting concerns are written down once and reused everywhere. Rather than re-deriving (or forgetting) the same defaults in every repo, each project points here and inherits them.
The goal is boring consistency: the same crate layout, the same deploy flow, the same systemd hardening, the same firewalld approach across every app I own, so that context switching between projects doesn't mean re-learning the shape of things.
## What's here
- **`generic.md`** — the baseline. Applies to every project unless that project explicitly overrides a section. Covers workspace layout, separation of concerns, configuration, secrets, deployment, service accounts, firewalld, SELinux, and code quality.
More files will appear here over time as guidance that's more specific than `generic.md` gets extracted — per-stack, per-deployment-target, or per-problem-domain documents. When a project needs guidance that isn't generic, it belongs in a new file here, not buried in one project's repo.
## How to use it
- **If you're scaffolding a new project:** start from `generic.md` and follow it. Deviations should be deliberate and noted in that project's own README.
- **If you're contributing to an existing project of mine:** read `generic.md` first. The project's local `CLAUDE.md` or `README.md` will note any intentional deviations; everything else defaults to what's here.
- **If you're an AI agent:** treat this repo's contents as authoritative defaults for any project under my control. When the surrounding project doesn't specify, fall back to the guidance here. When it does specify, the project wins — but flag the deviation so it's visible.
## How this evolves
This is living documentation, not a spec frozen at a point in time. When a convention changes — because something broke, because a better pattern emerged, or because the infrastructure itself changed — the update lands here first, and projects catch up on their next touch.
If you find guidance here that contradicts what's actually running in production, the guidance is wrong. Open an issue or a PR.

View File

@@ -372,21 +372,24 @@ For each component with a firewalld service definition:
1. `rsync` the XML to `/etc/firewalld/services/<app>-<component>.xml` on the target. 1. `rsync` the XML to `/etc/firewalld/services/<app>-<component>.xml` on the target.
2. `firewall-cmd --reload` to pick up the new definition. 2. `firewall-cmd --reload` to pick up the new definition.
3. Check if the service is already enabled in the target zone (default zone unless the manifest specifies otherwise): 3. Resolve the host's default zone (`firewall-cmd --get-default-zone`) and check if the service is already enabled there:
``` ```
firewall-cmd --zone=<zone> --query-service=<app>-<component> zone=$(firewall-cmd --get-default-zone)
firewall-cmd --zone=$zone --query-service=<app>-<component>
``` ```
4. If not, enable it persistently **and** in the runtime config: 4. If not, enable it persistently **and** in the runtime config:
``` ```
firewall-cmd --permanent --zone=<zone> --add-service=<app>-<component> firewall-cmd --permanent --zone=$zone --add-service=<app>-<component>
firewall-cmd --zone=<zone> --add-service=<app>-<component> firewall-cmd --zone=$zone --add-service=<app>-<component>
``` ```
5. On component removal (future concern), the reverse: `--remove-service` then delete the XML. 5. On component removal (future concern), the reverse: `--remove-service` then delete the XML.
Steps must be idempotent — re-running a deploy is a no-op on the firewall layer if the service is already installed and enabled. Steps must be idempotent — re-running a deploy is a no-op on the firewall layer if the service is already installed and enabled.
### Zone selection ### Zone selection
Most services bind to internal WireGuard interfaces. Put the WireGuard interface in a dedicated `internal` or `wg` zone and open services there. Public-facing services (rare — nginx is usually the only one) go in the default `public`/`FedoraServer` zone. The manifest may optionally specify a `zone:` per component; default to `internal` if unset. The infrastructure uses **only the default zone** created at OS install time — `FedoraServer` on servers, `FedoraWorkstation` on workstations. There are no custom zones (no `internal`, no `wg`), and `deploy.sh` should not create any. Always add services to whatever `firewall-cmd --get-default-zone` reports on the target host.
If a future need arises to segment traffic by interface (e.g., restricting a component to the WireGuard interface only), revisit this section before introducing custom zoning — don't add it silently.
### Port ranges, ICMP, sources ### Port ranges, ICMP, sources
If a service needs port ranges, ICMP types, or source-IP restrictions, put them in the same XML using firewalld's standard elements (`<port port="x-y" />`, `<source address="..."/>`). Don't split these across multiple named services. If a service needs port ranges, ICMP types, or source-IP restrictions, put them in the same XML using firewalld's standard elements (`<port port="x-y" />`, `<source address="..."/>`). Don't split these across multiple named services.
@@ -493,6 +496,13 @@ This is the environment these apps deploy into. Claude Code should assume it.
- Each crate has a `README.md` or top-level module doc explaining its role in the workspace. - Each crate has a `README.md` or top-level module doc explaining its role in the workspace.
- The repo `README.md` covers: what the project does, how to build, how to run locally, how to deploy. Point readers to this document for architectural conventions. - The repo `README.md` covers: what the project does, how to build, how to run locally, how to deploy. Point readers to this document for architectural conventions.
### Commits
- **Use [Conventional Commits](https://www.conventionalcommits.org/) syntax for every commit.** `type(scope): subject`, with types drawn from the standard set (`feat`, `fix`, `docs`, `refactor`, `test`, `chore`, `build`, `ci`, `perf`, `style`). Scope is the crate, component, or area touched. Subject is imperative and under ~70 characters. A body may follow if the *why* isn't self-evident.
- **Agentic contributors may commit without asking**, provided the change is a coherent, complete unit of work — the feature works, the bug is fixed, the refactor is finished. No approval prompt is needed for good commits that end a thread of work.
- **Don't declare victory prematurely.** If there's a realistic chance that follow-up commits on the same topic will be needed to finish the job (because the implementation is speculative, the tests haven't been run, or edge cases haven't been considered), stop and think before committing. A stream of sequential commits all fixing up the same incomplete attempt pollutes history and is more annoying than an approval prompt.
- **When in doubt, consolidate before committing** rather than landing half-done work and patching it afterwards. One commit that resolves the task cleanly beats five commits that thrash around getting there.
- Never `--amend` a pushed commit, never `--no-verify`, and never bypass pre-commit hooks to get a commit in. If a hook fails, fix the underlying issue.
--- ---
## 13. Conventions Summary for Claude Code ## 13. Conventions Summary for Claude Code
@@ -511,4 +521,5 @@ When scaffolding or extending a project:
10. Every listening port gets a named firewalld service per §9. No bare `--add-port` calls. 10. Every listening port gets a named firewalld service per §9. No bare `--add-port` calls.
11. SELinux stays enforcing. Work with the default policy first; ship a custom module only when necessary (§10). Never suggest `setenforce 0`. 11. SELinux stays enforcing. Work with the default policy first; ship a custom module only when necessary (§10). Never suggest `setenforce 0`.
12. Prefer fewer dependencies. Prefer bare-metal systemd over containers unless there's a reason. 12. Prefer fewer dependencies. Prefer bare-metal systemd over containers unless there's a reason.
13. When unsure, ask — these preferences are defaults, not mandates, but deviations should be deliberate. 13. Commit in Conventional Commits syntax. Commit autonomously when the work is done; hold off when follow-ups on the same topic are likely (§12 Commits).
14. When unsure, ask — these preferences are defaults, not mandates, but deviations should be deliberate.