Commit Graph

25 Commits

Author SHA1 Message Date
f552269cb3 docs: plan the hyprland desktop epic (spec, ADR, tasks)
Add the hyprland-desktop spec, ADR 0003 recording the compositor choice
over Sway/KDE/niri, and the task breakdown (0021-0030) that decomposes
the desktop into granular grouped modules. Record the corrected host GPU
facts (zeus is AMD, raichu the sole Nvidia machine) in CLAUDE.md.
2026-07-22 08:03:01 -04:00
310ff13c77 feat(gitea-axi): install the CLI and wire its agent context
Add gitea-axi as a flake input and a new modules.gitea-axi module that
installs the CLI through its home-manager module. That module also declares
the Claude Code context — the Agent Skill and the SessionStart dashboard hook
— when claude-code is enabled on the host, so neogaia gets both while a host
without the harness would get the CLI alone.

Drop the hand-written SessionStart hook from the claude-code module, which
named a gitea-axi binary nothing installed; the gitea-axi module owns it now.
Remove the vendored skill fork, which had drifted from upstream and would
collide with the copy the module writes.
2026-07-20 21:37:33 -04:00
6b5729b98a refactor(ssh): state the admitted keys directly instead of deriving them
The access policy was a separate fleet declaration mapping each machine to a
role and a client key, which the module looked up by hostname to derive what to
authorize. Authorizing a key needs the key text and nothing else, so the
per-machine names, the hostname lookup and the role existed only to reconstruct
a grouping that two lists already are.

The module now exposes those two lists and the set a machine admits, and a host
declares what it draws from in its own file. The fleet declaration is gone, and
with it a single-file directory at the repository root.

`authorizedKeys` defaults to the workstation keys. An option of a list type is
not mandatory the way a scalar one is: undeclared, it yields the empty list
rather than failing, and a machine admitting no key is unreachable. The default
makes the safe case the silent one.

Verified to produce the same system as the design it replaces, and against the
running machine in both directions.
2026-07-20 13:05:07 -04:00
4ecb86052b docs(git): record the verified deployment (task 0015)
Also note that `git config --global` lists only ~/.gitconfig and is not a
view of what git resolves, which misreads as the module's file being
ignored.
2026-07-20 12:22:36 -04:00
62eb6286b4 feat(git): enable the module per host rather than by default
Defaulting the module on hid it from a host's config, leaving no single
place that lists what a host carries. Each host enables it explicitly
instead, at the cost of a step when adding one.
2026-07-20 12:20:13 -04:00
75c5745cbd feat(git): carry the commit identity on every host
Default the module on rather than restating it per host, so a new host
commits without remembering the line. A host that should not carry a
personal identity sets enable to false.
2026-07-20 11:15:15 -04:00
c9fc17ecf5 feat(git): declare the operator's commit identity (task 0015)
Git identity lived only in one checkout's local configuration on one
machine, so it was invisible to every other checkout and lost on a
reimage. Declare it as a module instead, enabled on neogaia.

It is a module rather than base plumbing so a host that should not carry
a personal commit identity can decline it.
2026-07-20 10:53:47 -04:00
42ff195556 refactor(ssh): extract the host key wiring into a module
The sops secret declarations, the empty `hostKeys`, and the `HostKey`
lines were boilerplate sitting in the host, and every future host
restoring its identity would have repeated them.

`modules.ssh` takes the encrypted file and the key types, deriving the
secret names and the `HostKey` lines from one list, so the daemon and the
secrets cannot disagree about where a key lives. The resulting system
derivation is unchanged.

Also record two gotchas: reading PR review comments needs the Gitea API
rather than tea, and host keys are not user authentication keys.
2026-07-20 07:40:47 -04:00
60738f65c2 docs: correct the forge CLI gotcha, a tea login does exist 2026-07-19 23:54:08 -04:00
ce103a7353 feat(secrets): decrypt the login password from sops (task 0010)
Wire sops-nix into the shared base config as unconditional plumbing, with
a two-tier age identity model: an admin identity held outside the repo, and
a per-host identity generated on the machine and kept on its encrypted root.
Both `sshKeyPaths` defaults are cleared so the SSH host keys stay out of the
decryption path and remain free to become secrets in their own right.

The primary user's password hash moves into a shared secrets file encrypted
to admin plus neogaia, consumed through `hashedPasswordFile` and decrypted
before accounts are created.

This needs `users.mutableUsers = false`: NixOS applies a declared hash to an
already-existing account only when that flag is false, so at the default the
hand-set password would have been kept and the change would have been inert.
Root consequently has no password and is locked; sudo from wheel is the way
in, and generation rollback remains the recovery path.
2026-07-19 23:43:28 -04:00
54c191f801 feat(claude-code): share sudo's credential cache across sessions (task 0018)
Key sudo's credential cache per user rather than per terminal, holding it
for 60 minutes. An authentication made in the operator's own terminal then
covers commands issued by processes holding no terminal of their own, which
previously failed with a bare non-zero exit and no output.

No command is made passwordless. The password remains required; only the
cache holding it is shared, and any process running as the primary user can
spend that credential until it lapses.

A PreToolUse hook refuses a privileged command while the cache is cold,
naming the command that warms it, so the condition announces itself rather
than presenting as a stall. Both states were exercised against the running
system.
2026-07-19 22:18:58 -04:00
d0bfc7b21b docs: correct the gitea-axi gotcha and record home.file's absolute keys 2026-07-19 19:08:54 -04:00
42c602b814 docs: close out task 0016 after reimaging neogaia
The reimage is done and verified on hardware: the boot partition is 2 GiB
and reports it, the hardware profile's kernel parameter and module blacklist
are live, and the encrypted root unlocks to a console login.

The install procedure ran without divergence, which is the reproducibility
evidence the task was after.

The reimage also wiped the hand-written git identity, so the gotcha
describing it is updated to record the failure it now provokes.
2026-07-19 18:53:17 -04:00
431f75aad7 feat(neogaia): declare a 2 GiB EFI system partition (task 0016)
Each generation stores a kernel and an initrd on the EFI system partition,
and this host runs a large third-party kernel, so 512 MiB holds only about
seven. An exhausted partition fails at bootloader installation, after the
build has already succeeded.

The partition cannot grow in place: it sits first on the disk with the
encrypted container immediately behind it, and an encrypted volume's start
offset cannot move without rewriting its whole payload. Only an install
applies this layout, so the change takes effect at the next reimage and
does nothing to the running machine until then.

Record that a flake only sees git-tracked files, which cost an evaluation
earlier, and correct the git identity gotcha that a hand-written gitconfig
had made false.
2026-07-19 17:14:18 -04:00
f94aaba6c1 docs: correct the gotcha claiming the Gitea CLI is installed
No gitea-axi, tea or gh exists on the NixOS build, and there is no tea
login or GITEA_* environment to authenticate with. The flake names
gitea-axi only in the claude-code module's permissions and never packages
it, so pull requests cannot be opened from this machine.

The previous wording described the laptop while it still ran CachyOS with
these tools installed by hand.
2026-07-19 16:41:39 -04:00
7cd9370366 docs: refresh the gotchas for a self-hosting dev machine
The dev host no longer runs CachyOS, so the per-command experimental-features
export and the from-source CachyOS kernel build no longer apply. Records the
missing git identity in their place.
2026-07-19 11:44:08 -04:00
7809e079e3 docs(claude-code): teach the skill-management skills the Nix layout
~/.claude/skills is generated by home-manager: the directories are real
but every leaf file is a read-only symlink into the store. The skills
that author and install skills assumed it was an ordinary writable tree.

- craft-skill: personal skills are authored in modules/claude-code/skills
  and applied by a rebuild, never edited under ~/.claude/skills; writing
  there succeeds silently and strands the skill outside the repo.
- setup-skills, update-skills: copy out of the library with cp -rL and
  chmod -R u+w. A plain cp -r copies the symlinks, committing store paths
  into the project, and dereferenced files keep the store's read-only mode.
- craft-skill also staged through `dot add`, a fish function this repo no
  longer carries; plain git add replaces it.
2026-07-19 08:34:22 -04:00
bdb6f01934 docs: standardise on gitea-axi as the Gitea CLI
The Gotchas entry named `tea` as the CLI for issue and pull-request work.
`gitea-axi` supersedes it; `tea` stays installed only to hold the `axi`
login that `gitea-axi` authenticates from.
2026-07-19 08:28:34 -04:00
064971f601 docs: adopt Conventional Commits for commit messages
Vendor the v1.0.0 specification as docs/conventional-commits.md and record
the convention in CLAUDE.md: type and optional scope, where the scope names
the module or host, and no Gitea-specific references, since this repository
is mirrored to GitHub where issue and pull-request numbers resolve to
unrelated things.
2026-07-19 08:24:54 -04:00
77e853ab49 docs: rewrite the in-file comment convention
Encode the sharpened ruleset: why-over-what, self-containment, the
absence-only cross-file exception, no domain-glossary terms, no
against-alternative or future-state framing, one-line file headers,
placeholder wording, and how option description strings differ.
2026-07-19 07:57:44 -04:00
6f9309d329 feat(nvim): configure Neovim via nixvim with Nix-managed plugins
Add an nvim Module that configures Neovim declaratively through nixvim,
wired as a flake input and consumed as its home-manager module. Options,
globals, keymaps, and plugin settings are typed Nix; the colorscheme
call and two autocmds live in modules/nvim/config.lua via extraConfigLua.
Plugins come from nixpkgs (no plugin manager, no runtime cloning); git,
ripgrep, and fd are provided from Nix; treesitter grammars are built by
Nix so no runtime compiler is needed.

Functionally matches the previous config (plugins, keymaps, options, the
nord colorscheme, markdown conceal, the Neogit blame toggle), verified
headless against the generated init.
2026-07-19 07:57:43 -04:00
194d64dacd docs: require an agent sign-off on Gitea comments
Add a convention: comments posted to Gitea go out under the operator's
account, so sign each with a — Claude sign-off to attribute them to the agent.
2026-07-19 07:57:21 -04:00
8f83c3ca8c refactor(neogaia): drop the zram Module and enable zram inline
modules/zram.nix only wrapped the native zramSwap.enable toggle without
adding anything. Rewrite the touched comments to describe only the current
file content, and record the in-file-comment convention in CLAUDE.md.
2026-07-19 07:57:21 -04:00
053c4de529 feat(neogaia): add the CachyOS kernel and hardware enablement
Select the CachyOS kernel per-Host via boot.kernelPackages, enable Intel
microcode and redistributable firmware (ath10k for the QCA6174 wifi), and
move zram behind a toggle Module. Declare the chaotic binary cache in the
base Nix settings (extra-substituters/keys) so the built system fetches the
kernel from nyx-cache rather than compiling it.
2026-07-19 07:57:21 -04:00
9b36cfadd6 feat: build the Skeleton and a minimal neogaia Host
Stand up the walking skeleton the rest of the laptop MVI extends and
re-verifies against: the whole neogaia Host evaluates and its system
toplevel builds (nix flake check green).

- flake.nix: hand-rolled flake (no flake-parts). Base nixos-unstable, plus
  nixpkgs-unstable and nixos-25.05 for the per-package unstable/stable
  overlays, home-manager (nixpkgs followed), and chaotic-nyx (deliberately
  not following our nixpkgs, to keep its binary cache usable). checks build
  each Host toplevel.
- lib/: trimmed helper lib — the Auto-loader (recursive .nix discovery, no
  null-placeholder hack), the host-builder, and the script-from-file helper.
  Deps inherited explicitly; no with lib.my, no nixosModules output.
- system/: shared base config — the unstable/stable overlays, the user
  option (defaults to alexion, in wheel, drives system + home-manager user
  in lockstep), flakes, git, and home-manager as a NixOS module.
- modules/example.nix: Auto-loader / Enable-convention reference Module,
  inert until enabled.
- hosts/neogaia/: minimal laptop Host — placeholder filesystems, bootloader,
  and hardware profile.
- CLAUDE.md: project agent instructions with a Gotchas section (nix on the
  CachyOS dev host, the chaotic overlay/cache behaviour, the Gitea CLI).
2026-07-19 07:57:21 -04:00