Commit Graph

99 Commits

Author SHA1 Message Date
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
8c85c02a7d docs: close out task 0013 after confirming it on hardware
The rebooted laptop selects deep sleep, runs thermal and power management,
and no longer loads the PS/2 mouse driver. Booted, running and freshly
built toplevels are the same store path, so the readings come from this
configuration rather than a surviving generation.
2026-07-19 16:51:03 -04:00
25049c8aef feat(neogaia): adopt the upstream hardware profile (task 0013)
The laptop's hardware facts were guessed before it ran NixOS. Hand them to
the upstream nixos-hardware profile for this exact model, which fixes four
things that are wrong on the running machine: the laptop suspends into
s2idle rather than deep S3, the PS/2 mouse driver loads over an i2c
touchpad, no thermal management runs, and firmware updates are impossible.

The profile is taken wholesale, including the Intel graphics support it
carries. Those packages are inert without a display server, and trimming
them would mean diverging from upstream for no present benefit.

Drop the host's own Intel microcode setting, which the profile now defaults
from the redistributable firmware already enabled here.

The input follows the base nixpkgs: only its NixOS modules are consumed, so
its own pin would be evaluated by nothing while drifting silently.

The two acceptance criteria needing a reboot are left open; the sleep mode
and module blacklist only take effect on a fresh boot.
2026-07-19 16:41:34 -04:00
4c0d36324c docs: unblock the reimage from the non-boot-affecting tasks
Only the hardware profile needs to precede the reimage, because it is the
one change that touches boot: a kernel parameter and a module blacklist.
Validating it while a known-good generation still exists means the reimage
installs a configuration already proven on this hardware, where a freshly
imaged machine has no rollback target.

The housekeeping and commit-identity changes carry no boot risk and apply
equally well after the wipe, so they no longer gate it. The case for
reimaging soon rests on the machine holding almost nothing, and that
weakens with every day of use.
2026-07-19 16:20:21 -04:00
f80ea948ea docs: plan the post-boot hygiene tasks
neogaia was installed from a configuration written before the hardware
existed, so several things are now knowably wrong rather than guessed.

Adopt the upstream hardware profile for this laptop, which fixes deep
sleep, thermal management and the touchpad driver. Bound the store, the
retained generations and the boot menu, none of which have a limit today.
Declare the commit identity, which currently lives only in one checkout.

Grow the EFI system partition, which holds around seven generations at
its present size and cannot be enlarged in place, since the encrypted
container immediately behind it would have to be relocated. That makes a
reimage the only practical route, and the cheapest moment for one is now.
It doubles as the reproducibility test of the install documentation.
2026-07-19 16:11:52 -04:00
5e254857b9 docs: plan sops secrets with two-tier age identities
Supersede ADR 0001's SSH-derived key mechanism with an admin identity held
outside the repo plus a per-host identity on each encrypted root. Decoupling
the two is what lets the SSH host keys become secrets themselves rather than
the root of trust they were.

Add the spec, the three implementing tasks, and the glossary terms the
breakdown speaks in.
2026-07-19 14:57:41 -04:00
41709bb977 chore!: remove the pre-NixOS dotfiles tree
The flake and its modules now own every config these files provided;
they remain in history for reference while the migration finishes.

BREAKING CHANGE: `.config/`, `.gitconfig`, and `.github/` no longer exist
at the repository root. A checkout that deploys this tree into `$HOME`
will delete the live configs it previously installed.
2026-07-19 08:01:49 -04:00
7810425849 docs(neogaia): document the one-shot install flow
Add docs/install.md, the operator runbook that turns the completed
neogaia Host into a running encrypted laptop from the NixOS live ISO:
push the flake to its remote, join wifi, clone the repo locally,
disko-install against neogaia with the chaotic substituter handed to the
install-time daemon, set the bootstrap login password by hand via
nixos-enter, and reboot.
2026-07-19 07:57:43 -04:00
b7363ed7e1 feat(claude-code): manage the user's global config in the Module
Bring the declarative half of ~/.claude into modules/claude-code and apply
it when the Module is enabled: the global agent instructions (context =
./CLAUDE.md), the skills tree (skills = ./skills), the attention-bell hook,
and settings.json (model = opus plus the Stop/Notification/SessionStart
hook wiring).

Runtime state (projects, plugins, cache, history, sessions) and the
.credentials.json secret are left out, so login survives rebuilds and no
secret enters the repo. Verified against the built home-files that
~/.claude/{CLAUDE.md,settings.json,skills,hooks/attention-bell.sh} are
generated, the hook executable.
2026-07-19 07:57:43 -04:00
505002bb2b feat(claude-code): add a Module and enable it on neogaia
Install Claude Code through home-manager's native programs.claude-code
module, matching how the tmux and fish Modules use their home-manager
options rather than a raw home.packages entry. The feature Module at
modules/claude-code/claude-code.nix stays thin — just the enable option
and the delegation — and writes no settings, so login and first-run
configuration remain interactive and no auth material enters the repo.

Signing in without a browser (needed over the console or SSH) is
documented in modules/claude-code/authentication.md: the paste-code OAuth
flow, where the printed URL is opened on another device and the code
pasted back, and the ANTHROPIC_API_KEY path for non-interactive use.

The neogaia toplevel builds with claude-code-2.1.209 included.
2026-07-19 07:57:43 -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
80d1587189 feat(tmux): add a native Module and enable it on neogaia
Configure tmux through home-manager's programs.tmux: the settings it exposes
as options (prefix, keyMode, mouse, baseIndex, clock24, escapeTime,
historyLimit, terminal) are set as options, and every setting it has no option
for is read verbatim from modules/tmux/extra.conf. No tmux plugin manager is
used. The generated config is behaviourally identical to the reference, verified
by parsing it with a live tmux binary.
2026-07-19 07:57:21 -04:00
2d6eb929d7 refactor(fish): merge the config fragments back into one config.fish
The interactive init is small; four fragment files was over-splitting it.
Keep the mechanic (a real fish file inlined by Nix into config.fish) but
merge the fragments into a single modules/fish/config.fish read with
builtins.readFile. Rendered config is unchanged.
2026-07-19 07:57:21 -04:00
f54d0460ad refactor(fish): split config.fish into fragments concatenated by Nix
Break the interactive init into concern-scoped fish files under
modules/fish/config/ (bindings, env, done, path) and assemble them with
lib.concatMapStringsSep + readFile into a single interactiveShellInit, so
home-manager still writes one ~/.config/fish/config.fish. The pieces stay
editable as separate fish files; the rendered file is unchanged.
2026-07-19 07:57:21 -04:00
95869fb11f refactor(fish): assemble the interactive init in Nix, not at runtime
Fold the done plugin tuning back into config.fish and drop the conf.d
fragment: config.fish is read whole into interactiveShellInit, so Nix
assembles the interactive init at build time instead of fish autoloading
a separate conf.d file. functions/copy.fish stays a function file, the
idiomatic home for a lazily-autoloaded function.
2026-07-19 07:57:21 -04:00
5a89d4addb refactor(fish): lay the Module out like ~/.config/fish
Move the Module to modules/fish/fish.nix and mirror a real fish config
directory beside it: config.fish (interactive init), conf.d/done.fish
(the done plugin tuning, now a real conf.d file), and functions/copy.fish.
completions/ and themes/ are omitted as they have no content and git
cannot track empty directories.
2026-07-19 07:57:21 -04:00
b91e434c87 docs(fish): record the file-extraction in the project notes 2026-07-19 07:57:21 -04:00
9eb0fe797a feat(fish): gate the default shell and prefer abbreviations
Move the login-shell switch behind a new modules.fish.defaultShell
option (default false; neogaia opts in). Convert every non-eza alias to
an abbreviation, set preferAbbrs and pin generateCompletions, and switch
the command line to vi-style editing. Cap navigation at four dots and
drop psmem/psmem10/dir/vdir/please. Comment the installed packages.
2026-07-19 07:57:21 -04:00
8346d63e64 feat(fish): add a native Module and set it as neogaia's login shell
Translate the CachyOS fish snapshot into a home-manager Module: the
fastfetch greeting, the bat-backed manpager, the done and bang-bang
plugins (from nixpkgs, not a plugin manager), the history/backup/copy
helper functions, and the eza and navigation aliases. Pacman-specific
aliases are dropped or replaced with NixOS equivalents (update ->
nixos-rebuild switch, cleanup -> nix-collect-garbage). Enabling the
Module also makes fish the user's default login shell.
2026-07-19 07:57:21 -04:00
20f5b33e00 feat(neogaia): enable networking and set the base locale
Turn the booted laptop into a usable, remotely reachable console: enable
NetworkManager so wifi can be joined from the console and an SSH daemon so
the rest of the setup can be driven over the network. Set the base locale to
timezone America/New_York, locale en_GB.UTF-8, and console keymap us.

These live inline in the neogaia Host rather than behind enable Modules,
matching the single-Host MVI precedent; a shared locale/networking Module can
be extracted once a second Host needs the same settings. SSH keeps default
password auth on, as first-boot access relies on the hand-set bootstrap
password until key/sops-based auth lands post-install.
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
da30375413 feat(neogaia): declare the encrypted disk with disko
Add disko as a flake input (following nixpkgs) and wire its NixOS module
into the host-builder, so any Host can declare a disk layout while the
layout itself stays a per-Host concern.

neogaia's layout (hosts/neogaia/disk.nix): one GPT NVMe disk with a
systemd-boot EFI system partition and a LUKS container holding btrfs with
@root/@home/@nix subvolumes. The initrd prompts for the passphrase on a
normal boot. Swap is RAM-backed zram, so there is no on-disk swap
partition; zramSwap is enabled directly for now. The placeholder
fileSystems are removed since disko now derives them.
2026-07-19 07:57:21 -04:00
25e12f79de build(deps): pin the stable overlay and stateVersion to 26.05
26.05 is the latest stable NixOS release as of now (26.11 is still the
in-development branch that nixos-unstable reports); the previous 25.05 pin
was a release behind.

- flake.nix / flake.lock: stable overlay tracks nixos-26.05.
- neogaia system.stateVersion and the base home.stateVersion set to 26.05
  (fresh install, so aligning to the current stable release).
- Refresh the "latest stable release" references in the project docs to
  match.

Other inputs are rolling branches (nixos-unstable, nixpkgs-unstable,
chaotic nyxpkgs-unstable) or master (home-manager, per spec), so they carry
no version to bump.
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
d5b67947f9 docs: establish domain model, MVI spec, and environment reference
Capture the design work for the NixOS migration before any implementation:

- .claude/CONTEXT.md: domain glossary (Host, Module, Skeleton, Auto-loader,
  Enable convention, unstable/stable overlay)
- .claude/adr/0001-sops-nix-for-secrets.md: secrets tooling decision
- .claude/spec/laptop-mvi.md: frozen minimum-viable-install spec for neogaia

- reference/: read-only snapshot of the current CachyOS configs (secrets and
  state excluded), plus ENVIRONMENT.md profiling the live environment to guide
  replication
2026-07-19 07:57:21 -04:00
b4650c03b8 Remove the gitea skill
Superseded by the gitea-axi skill.
2026-07-14 19:42:44 -04:00
8d3915ad0e Enforce TDD in the implement flow
Add a PreToolUse hook that reminds the main agent not to author test
files directly, and change the implement skill to always use
test-driven-development rather than only where possible.
2026-07-14 19:42:39 -04:00
0046a87130 skill: Add skill to use tea-cli. 2026-07-13 18:54:23 -04:00
1ca5033bc8 claude: forbid PR attribution trailers, default to opus 2026-07-11 20:05:49 -04:00
aced50f67f skills: implement branches off main and opens a PR; TDD tests come from a sub-agent
implement: sync main and cut task-<NNNN>-<slug> before work, with
stop-and-ask guards for a dirty tree, a diverged main, and an unmerged
blocker. Replaces the no-commit rule with one commit, a push, and a PR
carrying the review's Risk block plus any unaddressed findings.

test-driven-development: every test is written by a general-purpose
sub-agent that never reads the implementation; the main agent writes the
code and never edits a test.
2026-07-11 20:05:44 -04:00
eee7c8190d claude: Add attention-bell hook so tmux flags Claude sessions needing input
Wire Stop and Notification hooks in ~/.claude/settings.json to a new
~/.claude/hooks/attention-bell.sh, which rings the terminal bell in the
session pane so tmux monitor-bell flags the background window.

The hook runs detached (no controlling tty), so it walks its process
ancestry to the claude process and writes the BEL to that pane tty.

Also replaces the dead settings.json symlink (pointed at a now-missing
~/wrk/claude path) with a real tracked file.
2026-07-10 22:48:28 -04:00
14f8618c0a skills: add instructions to prevent unsolicited implementations. 2026-07-09 08:53:05 -04:00
3732ccd4d8 chore: Change task numbering to decimal.
Hex doesn't sort nicely in the file system.
2026-07-06 16:50:24 -04:00
b233fe41e7 skills: Add project-specific skill library. 2026-07-05 15:16:53 -04:00
47241b8421 skills: Add /improve-codebase 2026-07-05 14:47:06 -04:00
6f6f4204ee skills: Add a "change risk" axis to /review-uncommitted. 2026-07-05 14:29:16 -04:00
e606a09d2c skills: Add /review-uncommitted skill. 2026-07-05 14:18:44 -04:00
720eba8afb skills: Add /implement and dependencies.
This includes /test-driven-development and /codebase-design
2026-07-05 13:52:44 -04:00
28734f9777 skills: Add /to-tasks skill. 2026-07-05 13:01:26 -04:00
8aa3e8d62f skills: Add /to-spec skill. 2026-07-05 12:05:02 -04:00
d36b3340ca skills: Add /grill and /domain-modeling 2026-07-04 23:34:28 -04:00
42095c06e1 tmux: highlight window when a bell is received. 2026-07-04 23:13:51 -04:00
c112bb174a claude: append corrections to a project's CLAUDE.md 2026-07-04 19:00:50 -04:00
6db7bb188f skill: added craft-skill
This is a meta skill to help create other skills.
Loosely based on Anthropic's create-skill.
2026-07-04 18:43:59 -04:00
9a4263ce8b claude: General guidelines 2026-07-04 17:23:22 -04:00
d5aacad86e docs: refactor dotfiles skill into CLAUDE.md
The skill wasn't firing reliably, so instead of polluting the global
config with a skill that only helped *sometimes*, convert it into
project-specific instructions in .config/dot

Future work on this project (dotfiles) should always start from this
directory, even if changes are made outside. This helps Claude keep
the scope narrow.
2026-07-04 10:54:45 -04:00
80581f5029 dotcli: fix help falling through to git. 2026-07-04 01:17:04 -04:00
6ad0f109df dotcli: Initial config
dotcli is my utility script for everything dotfiles.

A bootstrap command is included in the README.
A test suite and the necessary scaffolding for extending
dotcli is also included.
2026-07-04 00:47:49 -04:00