Add a "Managing the OPNsense routers" note to generic.md §11 (Network):
opn-cli talks to a site's OPNsense over its API, credentials in a per-site
~/.opn-cli/<site>.yml (api_key/secret + url + internal-CA ca:), --config is
required. The split-horizon .internal records and public-name host-overrides
live in each router's Unbound, so `unbound host list/create/update/delete` is
how you inspect and fix them:
opn-cli --config ~/.opn-cli/hanzalova.yml unbound host list
opn-cli --config ~/.opn-cli/kosherinata.yml unbound host list
Cross-referenced from reverse-proxies.md §2 as the tool to reach for when a
mesh client resolves a name to the wrong host — exactly the rob.fyi case.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fKZzDpvjiJ9eYbPGgJvUP
Guidance for picking a listening port that won't collide on a shared-host
fleet: use the registered range (1024-49151), avoid the crowded alt-HTTP
cluster (3000/5000/8000/8080/8081/8443/9000...) and never the ephemeral range
(49152+, kernel source ports), derive from the service name into a sparse band,
and — the actual anti-collision mechanism — record every allocation in a fleet
registry. Seeds the registry with the services documented across this repo
(pg, neuron, bench, gongfoo controller/agent, cortex) plus newsfeed-api.
Motivated by newsfeed-api having been put on 8081 (the alt-HTTP port). Linked
from generic.md §9.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fKZzDpvjiJ9eYbPGgJvUP
Empirically verified (run on a fedora-43 runner): the ssh client is present
on every runner image, not just `infra`. The bare fedora/ubuntu container base
ships no ssh and weak deps are disabled, but each image installs `git` for
checkout, and `git-core` hard-requires `openssh-clients` — so ssh is pulled in
regardless. rsync + curl are likewise in every base.
Corrects the earlier claim that CI-driven deploy needs `infra`: deploy jobs
run fine on `fedora-43`. `infra`'s real payload is `stalwart-cli` / infra
service CLIs. Also notes that runner-infra's own Containerfile comment
("the ssh client is not in the base") is misleading.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fKZzDpvjiJ9eYbPGgJvUP
Document the gongfoo-managed runner images (labels, lineage, toolchains,
CPU/MEM), how `runs-on:` label matching selects one, which runner to pick for
each job type, and how to add/extend an image instead of installing packages
at workflow run time.
Captures the traps that cost a run: `fedora-*` has no cargo (use `rust`); the
base fedora images ship rsync but no ssh client (deploy jobs use `infra`);
`corepack` isn't bundled — pnpm is preinstalled via npm, call it directly.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fKZzDpvjiJ9eYbPGgJvUP
§11 still described mistral.rs on :1234 and a "planned" cortex.internal.
Update to current reality: candle-native neuron daemons on :13131 per GPU
host, fronted by the cortex gateway (live at hanzalova.internal:31313 /
:31314, unified OpenAI+Anthropic, routing + eviction across the fleet).
Note no-auth-yet (governance epic pending), discover-via-/v1/models,
cortex.internal:443 still aspirational, and the helexa-bench telemetry
endpoint. Repo link updated to helexa/helexa.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Capture the cert + edge-proxy conventions worked through deploying the
helexa-bench UI:
- external-tls.md — publicly-trusted certs via Let's Encrypt (certbot,
Cloudflare DNS-01, ECDSA, /root/.certbot-internal); the external
counterpart to internal-tls.md. Decision rule: public name → LE,
*.internal → internal CA.
- reverse-proxies.md — names the per-site edge proxies (oolon for
kosherinata, hanzalova.internal for the office) and what sits behind
each, the public-vs-mesh access paths + the "public names don't
hairpin from inside the mesh" gotcha, per-vhost cert choice, nginx
conventions, and the bench (bench.helexa.ai + bench.internal) worked
example.
- readme + generic.md §11 cross-reference both.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add two new guidance documents alongside generic.md:
- deployment-gitea-actions.md: CI-driven deployment via a Gitea Actions
workflow as an alternative to deploy.sh + manifest.yml (§7), with the
workflow as the source of infra truth and a scoped gitea_ci runner user.
- internal-tls.md: provisioning and renewing per-service internal TLS
certs (<service>.internal) for mesh-only nginx vhosts, extending the
PKI conventions in §11.
Cross-reference both from generic.md and list them in readme.md. Also
add a "never suppress errors" rule to the deploy-script conventions.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the three mistral.rs backends (beast, benjy, quadbrat) with their GPU
capacity and the port 1234 / no-auth / no-TLS contract. Note that consumers
must currently discover model availability per-host via /v1/models, and
that cortex (git.lair.cafe/helexa/cortex) will eventually unify them
behind https://cortex.internal:443.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Call out magrathea (primary) / frankie (standby) as the default Postgres
cluster and document the concrete steps to grant an app access: create
roles on the primary, drop a pg_ident.conf.d file on both servers, and
reload postgresql-18. The both-servers detail is easy to miss and costs
the app during a failover.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Expand §11 TLS/PKI with the concrete host cert paths, file modes, and the
ACL-for-service-accounts pattern. Document the 24h cert expiry and the
continuous step.service renewal so implementations don't assume certs are
stable. Add the standard systemd .path/.service reload pair for services
that need to re-read certs without restart.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Carve out the agent-instruction files as exceptions to the lowercase-readme
convention — their all-caps naming is what tooling expects and what makes
them visible in a file listing. Also document that agents can modify these
files on their own judgement; diffs get reviewed so drift is caught
downstream.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add guidance in generic.md §12 that readme files (and other conventional
top-level docs: license, changelog, contributing) should be named in
lowercase, not shouty all-caps. Update all README.md references in
generic.md and rename this repo's own README.md to match.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Migrations are sequentially numbered and frozen once committed. Editing an
already-landed migration causes checksum divergence and migration-runner
failures at deploy time — new changes must go in new files. Call this out
explicitly so contributors don't quietly break a service by "fixing" a
prior migration in place.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Projects with a Postgres dependency typically expose an MCP server scoped
to their database(s). Call this out so agents know to verify schema and
query shapes against the real database rather than guessing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Note that new projects default to the self-hosted Gitea instance at
git.lair.cafe (git.internal on the WireGuard mesh), that legacy projects
on GitHub/GitLab are being migrated as they come up for refactor, and
that relocated repos should carry a prominent pointer to the new URL.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The "web/" folder name in §4 was being read as a required convention, but
projects routinely use ui/, dashboard/, or admin/ instead — and may have
more than one frontend in the same repo. Document the common names, note
that each frontend is an independent Vite app, and add guidance on sharing
types across multiple frontends.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>
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>
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>
Expand generic.md with detailed guidance on service account creation via
systemd-sysusers, named firewalld service definitions, and SELinux policy
management. Update deploy.sh responsibilities, asset layout, and conventions
summary to reflect the new requirements.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>