Files
infrastructure/AGENTS.md
T
spektr 88b063a234 Encoding/CT-101: PVE-Host-NFS konvergiert, Berechtigungsmodell entschieden, Verifikation dokumentiert.
- pve_nfs_export: NFSv4-only via /etc/nfs.conf ([nfsd] vers2/vers3=n; Debian-13-Unit
  startet nfsd ohne EnvironmentFile, RPCNFSDARGS wirkungslos), Restart-Handler,
  selbstheilende nfsd-Versionspruefung; verify-production um Export-Root- und
  Versions-Assertions erweitert
- Autorisierte Konvergenz auf dem PVE-Host: Export-Root 100000:970 2775,
  /proc/fs/nfsd/versions -3 +4 +4.1 +4.2, verify ok=17 changed=0, Idempotenz changed=0
- Berechtigungsmodell (Betreiberentscheidung 30.10.2026): Mode 2777 auf input/- und
  output/-Baum der Pipeline (LXC-idmap-Diskrepanz guest-root vs. UID 982/983:970)
- GNENC-000/001/002, GNAI-017/018/019 auf NFS-auf-PVE-Host-Stand gebracht;
  CT-101-Verifikation ok=47 changed=0 dokumentiert; AGENTS.md-Seccomp-Hinweis korrigiert

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-10-30 19:54:42 +01:00

101 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Ghostnet.AI project context
Before infrastructure work, read `.codex/LOCAL_MEMORY.md` if it exists. It contains dated local observations and access hints; verify live state before making system changes. Keep secrets and private key material out of that file.
For read-only access to the KI server, use the tested SSH profile `ghostnet-ai-agent`, which logs in as the unprivileged account `ghost-agent` on `10.0.0.90`. On this workstation, invoke it as `ssh -F ~/.ssh/config ghostnet-ai-agent` because the system-wide SSH client configuration currently has an ownership/permissions error. Do not assume sudo access or make server changes without an explicit user request.
The KI server at `10.0.0.90` is deliberately a fresh base system. The operator plans to install the LLM application stack in a later Ansible sprint. Do not install applications or change server configuration as part of documentation review or access checks unless the operator explicitly requests that work.
## Agent access convention: `ghost-agent`
`ghost-agent` is the standard unprivileged account for the AI agent on the
Proxmox LXCs and the KI server (operator-confirmed 2026-10-28: "on the KI
server and many other Proxmox LXCs"). It is a convention, not a per-host
exception.
- Login is key-based with a **passphrase-less** Ed25519 key kept in the
operator's `~/.ssh` (`id_ed25519_ghostnet_<host>_agent`); `~/.ssh/config`
carries the matching `ghostnet-<host>-agent` aliases, which also work with
`ssh -o BatchMode=yes`. Private keys never enter the repository.
- `ghost-agent` has **no sudo** (verified on CT 100, CT 101, CT 103 and
ghostnet-ki): treat every agent session as read-only unless the operator
explicitly authorizes a change.
- Known aliases (verify live state before use; the WireGuard LXC has no
`ghost-agent` alias and uses the legacy `admin` account via alias `lxc`):
| Alias | System | IP |
| --- | --- | --- |
| `ghostnet-ct100-agent` | CT 100, Pi-hole/Split-DNS `dns` | 10.0.0.14 |
| `ghostnet-ct101-agent` | CT 101, Samba file server | 10.0.0.9 |
| `ghostnet-ct102-agent` | CT 102, Keycloak | 10.0.0.4 |
| `ghostnet-ct103-agent` | CT 103, reverse proxy (NPM) | 10.0.0.10 |
| `ghostnet-ct104-agent` | CT 104, Keycloak | 10.0.0.16 |
| `ghostnet-ai-agent` | ghostnet-ki, LLM/AI server | 10.0.0.90 |
- Invoke ssh as `ssh -F ~/.ssh/config <alias>`: a bare `ssh` currently rejects
`/etc/ssh/ssh_config.d/20-systemd-ssh-proxy.conf` because of its
ownership/permissions; `-F` deliberately uses the local profile without
loading that broken system configuration.
- Dated per-host observations (host-key fingerprints, verified identities,
account details) live in `.codex/LOCAL_MEMORY.md`, not here.
## Account landscape and Ansible inventory paths
| Account | Role | Key (operator `~/.ssh`) | sudo |
| --- | --- | --- | --- |
| `ghost-agent` | AI agent, read-only | `id_ed25519_ghostnet_<host>_agent` (no passphrase) | no |
| `ghost` | human operator/admin | `id_ed25519_ghostnet_<host>_ghost` (passphrase-protected) | yes, password-gated |
| `ansible-deploy` | Ansible deployment; created by the project's access role during adoption | `id_ed25519_ghostnet_<host>_ansible_deploy` (no passphrase) | `NOPASSWD: ALL` (treat the key as root-equivalent) |
Each Ansible LXC project (`proxmox/lxc/<ct>/ansible/`) maps these accounts to
three inventories: `agent` (`ghost-agent`, read-only preflight), `bootstrap`
(`ghost`, `--ask-become-pass`), `production` (`ansible-deploy`, NOPASSWD).
Legacy exceptions exist (CT 103 is root-only and bootstrapped via the Proxmox
console; the WireGuard LXC uses `admin`) — see `.codex/LOCAL_MEMORY.md`.
## Operator-run steps
- The workstation has **no Proxmox host access** (no `pct`): PVE-side commands
(`pct exec`, `pct reboot`, `vzdump`, editing `/etc/pve/lxc/*.conf`) are run by
the operator as root@pve. The agent prepares exact commands and reviews the
pasted output.
- Interactive secret steps are operator-run: `passwd`, `smbpasswd -a`, playbook
runs with `--ask-become-pass`, and key passphrase prompts. The agent hands
over copy-paste commands; the operator executes them.
- Secrets never enter the repository, inventories, playbooks or logs: SMB
passwords, the Samba passdb, the `ghost` password, private SSH keys, Podman
secrets. Only public keys belong in the repo (`ansible/files/ssh/`).
## LXC / Proxmox conventions
- Reboot caveat (GNAI-016 section 7): in LXC, `/proc/sys/kernel/random/boot_id`
belongs to the PVE host and does **not** change on a guest reboot — never use
boot_id-based waiters; reboot via PVE and verify independently over SSH.
- Unprivileged LXCs: mask `sys-kernel-config.mount` (configfs is unavailable)
and expect `uid_map 0 100000 65536` — host UIDs outside 100000–165535
appear as 65534 (nobody) inside the guest, so guest root cannot write to
files owned by such UIDs without world-write bits. (The former empty
`lxc.seccomp.profile:` line was a Ganesha-era exception and was removed on
2026-10-30 when the NFS export moved to the PVE host; GNAI-019 decision 2.)
- In-place dist-upgrades: take a `vzdump` safety net first and use
`--force-confold` so productive configuration files survive.
## Repository conventions
- Documentation: `docs/platform/proxmox-server/lxc/<ct>/GNAI-*.md` (German;
decisions carry operator/date stamps, findings are lettered a), b), …).
Ansible project READMEs are English. The central index is
`docs/GNAI-000-DOC_Index.md`.
- Ansible projects are self-contained under `proxmox/lxc/<ct>/ansible/`
(`ansible.cfg`, `inventories/{agent,bootstrap,production}`, `playbooks/`,
`roles/`, `files/ssh/`), use the repository-wide control venv (`.venv`, built
from `shared/ansible/requirements-control.txt`) and the shared roles in
`shared/ansible/roles/`.
- Change discipline: productive changes only with explicit operator go; preview
with `--check --diff` first; convergence must be idempotent (a second run
reports `changed=0`); commit only when the operator asks.
- Communicate with the operator in German.
- Verify account/identity assumptions with the operator before declaring them
(CT 101 example: `dark2devil` turned out to be the same person as
`debugofen`; GNAI-019 decision 11 was revised accordingly).