From 28a46d9990f0b5539461ea4c46fa1708439db236 Mon Sep 17 00:00:00 2001 From: moons Date: Tue, 4 Aug 2026 14:42:31 +0900 Subject: [PATCH] skill --- .gitignore | 1 + AGENTS.md | 5 + skills/add-application-or-service/SKILL.md | 137 +++++++++++++++++ .../agents/openai.yaml | 4 + .../references/review-checklist.md | 139 ++++++++++++++++++ 5 files changed, 286 insertions(+) create mode 100644 skills/add-application-or-service/SKILL.md create mode 100644 skills/add-application-or-service/agents/openai.yaml create mode 100644 skills/add-application-or-service/references/review-checklist.md diff --git a/.gitignore b/.gitignore index e9a367b..e539c3d 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ !/modules/ !/tests/ +!/skills/ diff --git a/AGENTS.md b/AGENTS.md index d0980ae..ae57b3d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -24,6 +24,11 @@ makes any statement here stale, update `AGENTS.md` in the same change. | `overlays/` | Package replacements and additions | | `shells/` | Development shells | | `flake/` | Supporting flake outputs such as formatters, checks, and Git hooks | +| `skills/` | Repository-specific Codex workflows that enforce this contract for recurring changes | + +Before adding or materially extending an application or service, read and +follow `skills/add-application-or-service/SKILL.md`. `AGENTS.md` remains the +authoritative contract when the skill and repository ever disagree. Use **unit** as the generic internal term for a Registry-managed component and **profile** for a unit that composes multiple units. Do not introduce a diff --git a/skills/add-application-or-service/SKILL.md b/skills/add-application-or-service/SKILL.md new file mode 100644 index 0000000..2c04310 --- /dev/null +++ b/skills/add-application-or-service/SKILL.md @@ -0,0 +1,137 @@ +--- +name: add-application-or-service +description: Add, install, configure, or enable an application or long-running service in this NixOS, nix-darwin, and Home Manager flake while preserving its Registry architecture and quality bar. Use for new GUI or CLI applications, packages, daemons, background services, application-service pairs, cross-platform installations, profile adoption, or substantial extensions to an existing application or service unit. +--- + +# Add Application or Service + +Add the smallest complete Registry unit change that has a clear owner, an +explicit dependency path, and evidence that every affected host class +evaluates. Treat `AGENTS.md` as the authoritative repository contract; never +replace it with generic Nix conventions. + +## Follow the workflow + +### 1. Establish the baseline + +1. Read `AGENTS.md` completely before editing. +2. Run `git status --short`. Preserve all pre-existing user changes and identify + which later diffs belong to this task. +3. Translate the request into observable outcomes: package or program, desired + configuration, supported host classes, required daemon or permissions, and + the profile or user intent that should select it. +4. Inspect the nearest existing units, relevant profiles, `hosts/default.nix`, + and Registry implementation. Prefer repository evidence over memory. +5. Verify current package names, module options, external module exports, and + Homebrew cask names from the locked inputs or authoritative upstream + documentation. Do not guess an option path. +6. Read [references/review-checklist.md](references/review-checklist.md) before + choosing files or dependencies. + +### 2. Choose ownership before code + +Classify each concern independently: + +- Put the user-facing program and its settings in + `modules/applications//`. +- Put a daemon, long-running process, firewall rule, permission, or user/group + membership in `modules/services//`. +- Split an application and independently meaningful daemon into two units. + Let the application include the service only when the service is a technical + requirement of that application. +- Put adoption of otherwise independent units in the narrowest coherent + `modules/profiles/` composition. +- Use another documented owner when the request is actually a system, + hardware, user, overlay, or host concern. Do not force it into an application + or service directory merely because this skill was invoked. + +Choose only the reserved fragments that contain real configuration. Use +`common.nix`, `nixos.nix`, and `darwin.nix` for system-side configuration; use +`home.nix` or `home/{common,nixos,darwin}.nix` for Home Manager. Use `meta.nix` +only for description, fully qualified `includes`, and external module imports. + +Before editing, formulate a short implementation contract containing: + +- the unit ID and owner; +- each file to create or change and why; +- technical dependencies versus profile-level choices; +- supported and affected host classes; +- the evaluations or builds that will prove the change. + +Rework the design if an ordinary addition appears to require Registry changes, +new global `specialArgs`, `_module.args`, direct host selection, or an overlay. +Use those mechanisms only with concrete evidence that the documented extension +points cannot express the requirement. + +### 3. Implement the minimum complete change + +1. Return configuration directly from every reserved fragment. Do not add + top-level `imports`, `options`, or `config`, and do not reproduce Registry + `mkEnableOption`, `cfg`, or `mkIf` boilerplate. +2. Put upstream NixOS, nix-darwin, or Home Manager modules in + `meta.imports.`. Import ordinary helper files explicitly from the + fragment that uses them. +3. Declare unit-to-unit technical dependencies only through fully qualified + `meta.includes`. Never enable another unit by assigning its + `my..enable` option inside a fragment. +4. Add an independent application or service to an existing coherent profile, + or create a justified profile when no existing one expresses the user + intent. Do not use `hosts/default.nix` application or unit escape hatches for + normal composition. +5. Keep cross-platform purpose shared and installation differences in the + owning unit. Do not create thin `*-linux` profiles. +6. Use existing module arguments and standard options. Do not inject a + dependency through global arguments, Registry internals, import ordering, or + `lib.mkForce`. Use explicit module priorities only when a real ownership + boundary requires them and make that reason visible in the code or handoff. +7. Avoid speculative abstraction. Create a helper only when it separates + meaningful configuration or prevents real duplication. Do not add empty + fragments, compatibility aliases, unused options, redundant comments, or + copied boilerplate. +8. Update `modules/profiles/README.md`, `AGENTS.md`, profile selections, or + other contract documentation whenever the change makes an existing + statement stale. Do not edit them performatively when their meaning remains + accurate. + +### 4. Prove the change + +Run the validation matrix in +[references/review-checklist.md](references/review-checklist.md). At minimum: + +1. Format the task-owned files with the repository formatter and run + `git diff --check`. +2. Inspect the complete task diff for accidental files, duplication, leaked + secrets, forced values, direct enable assignments, and unrelated rewrites. +3. Run `nix flake check`. +4. Run `pre-commit run --all-files`. +5. Evaluate every affected real host without switching it. For a + cross-platform unit or profile, evaluate both NixOS and nix-darwin even if + only one class changed. Build an affected configuration with `--no-link` + when the current platform can build it. +6. Verify selection as well as syntax: confirm that the expected package, + program, service, group, cask, or external module appears in the resulting + configuration. + +If a command is unavailable, blocked by the environment, or fails for a +pre-existing reason, diagnose it and report the exact gap. Never silently skip +a required check or weaken the implementation to make a check pass. + +### 5. Audit before completion + +Reject the change until all of the following are true: + +- Every line has one clear owner and is required by the requested behavior. +- Every dependency is either technical and declared in `meta.includes`, or a + user choice owned by a profile. +- The unit is reachable from the intended profile or has an explicit reason to + remain independently selectable. +- No host, Registry, flake root, global argument, or overlay was changed as a + shortcut. +- Reserved fragments, metadata, and profile documentation satisfy the current + repository contract. +- Validation covers every affected host class and all failures are resolved or + explicitly reported. + +Conclude with the owner and selection rationale, affected hosts or profiles, +validation commands and results, and any manual activation or runtime check +that remains. Do not claim runtime behavior that was only evaluated. diff --git a/skills/add-application-or-service/agents/openai.yaml b/skills/add-application-or-service/agents/openai.yaml new file mode 100644 index 0000000..e10c06b --- /dev/null +++ b/skills/add-application-or-service/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Add Application or Service" + short_description: "Add clean, validated Registry units" + default_prompt: "Use $add-application-or-service to add an application or service cleanly and verify every affected host class." diff --git a/skills/add-application-or-service/references/review-checklist.md b/skills/add-application-or-service/references/review-checklist.md new file mode 100644 index 0000000..e82cfae --- /dev/null +++ b/skills/add-application-or-service/references/review-checklist.md @@ -0,0 +1,139 @@ +# Application and Service Review Checklist + +Use this reference during design and again during final review. + +## Ownership and fragment matrix + +| Concern | Owner | Typical fragment | +| -------------------------------------------------------- | ----------------------------------- | ----------------------------------------- | +| User-facing GUI, CLI, editor, or compositor | `modules/applications//` | `home*.nix`, `nixos.nix`, or `darwin.nix` | +| User-scoped package and program settings | Application unit | `home.nix` or `home/.nix` | +| macOS Homebrew package or cask | Owning application or service | `darwin.nix` | +| Daemon or long-running service | `modules/services//` | `nixos.nix` or `darwin.nix` | +| Firewall, group, permission, or service account | Owning service | `nixos.nix` or `darwin.nix` | +| Upstream module defining options | Owning unit metadata | `meta.nix` under `imports.` | +| Technical prerequisite unit | Owning unit metadata | Fully qualified `meta.includes` | +| A set of independent tools chosen for one purpose | Narrowest coherent profile | Profile `meta.includes` | +| Machine fact such as UUID, monitor ID, or static address | `hosts//` | Normal host module | +| Missing or replaced package | `overlays/` only after proving need | Overlay definition | + +Use `home/common.nix` when Home Manager configuration is truly shared between +NixOS and Darwin. Use `home/nixos.nix` or `home/darwin.nix` for class-specific +Home Manager behavior. Root `common.nix` is system-side and never Home Manager. +Do not create an unused counterpart for symmetry. + +## Dependency review + +For every edge from unit A to unit B, answer these questions: + +1. Does A fail to work without B? If yes, put the fully qualified ID of B in + A's `meta.includes`. +2. Are A and B merely useful together for a particular workflow? If yes, let a + profile include both. +3. Does the dependency exist only on one host? Keep the machine fact in the + host, but keep reusable behavior in its unit or profile. +4. Is a new `specialArgs`, `_module.args`, Registry field, or direct + `my.*.enable` assignment being proposed? Reject it unless the repository's + normal module and `meta.includes` mechanisms provably cannot model the + requirement. +5. Would adding the dependency make the depended-on application select a + compositor, desktop, personal workload, or unrelated tool? Reverse or remove + the edge; application metadata contains technical requirements, not taste. + +Accept no circular dependency, shortened unit ID, duplicate include, stale +unit ID, or ordering-dependent override. + +## Minimality and code-quality review + +Reject any of these patterns: + +- Empty or placeholder reserved fragments. +- Hand-written enable options or guards already generated by the Registry. +- Top-level `imports`, `options`, or `config` in a configuration fragment. +- External module imports hidden in a guarded configuration fragment. +- Helper files assumed to be auto-imported. +- A helper abstraction used once without reducing meaningful complexity. +- Configuration duplicated across fragments when a shared fragment can express + it cleanly. +- Direct host application or unit selection where a profile expresses the + concern. +- A new flake input or overlay when the locked package set already provides the + package and required module. +- Global argument injection for a value owned by one unit. +- `lib.mkForce` used to win an ordering fight instead of resolving ownership. +- Secret material, generated state, machine IDs, or mutable user preferences + committed as reusable configuration. +- Comments that repeat the code, compatibility aliases, dead options, or + opportunistic unrelated cleanup. + +Prefer standard upstream module options over hand-written service definitions. +Prefer existing repository arguments and helpers over new plumbing. Preserve +user-owned mutable state unless the requested policy explicitly owns it. + +## Validation matrix + +Run checks from the repository root and keep the exact results for the handoff. +Do not switch or activate a live system merely to validate a change. + +### Always + +1. Format task-owned files. If the worktree contains unrelated user changes, + pass only task-owned paths to the configured formatter when supported. +2. Run `git diff --check`. +3. Review `git status --short`, `git diff --stat`, and the complete `git diff`. +4. Run `nix flake check`. +5. Run `pre-commit run --all-files`. + +### NixOS or Home Manager on NixOS + +- Evaluate each affected host's system toplevel derivation. +- Build at least one affected NixOS configuration with `--no-link` when the + current system supports it. +- Inspect the resulting option that proves selection: for example + `environment.systemPackages`, the user's `home.packages`, + `systemd.services`, `users.users..extraGroups`, or the upstream + `programs`/`services` option. + +Typical build shape: + +```sh +nix build .#nixosConfigurations..config.system.build.toplevel --no-link +``` + +### nix-darwin or Home Manager on Darwin + +- Evaluate every affected Darwin host even when running on Linux. +- Inspect `homebrew.casks` or `homebrew.brews` for Homebrew-backed additions. +- Evaluate the relevant Home Manager program or package option. +- Build a Darwin configuration only on a compatible Darwin builder; otherwise + report that build as an explicit runtime-validation gap. + +Typical evaluation shapes: + +```sh +nix eval --raw .#darwinConfigurations..system.drvPath +nix eval --json .#darwinConfigurations..config.homebrew.casks +``` + +Confirm the exact output attribute against the current flake before using a +command; do not paste these shapes blindly. + +### Profiles and cross-platform changes + +- Determine transitive selection through `meta.includes`, not only direct + mentions. +- Evaluate every real host selecting the changed profile. +- Evaluate both host classes for a cross-platform profile, even if only one + current fragment changed. +- Re-read `modules/profiles/README.md` and `hosts/default.nix` for stale meaning, + compatibility, or role statements. +- If no real host selects the new unit, construct a non-persistent evaluation + that enables it or explain why the unit is intentionally dormant. Do not add + a fake host or permanent direct selection as a test harness. + +### Runtime-dependent behavior + +Evaluation and builds cannot prove GUI appearance, credentials, network access, +hardware behavior, or successful daemon interaction. State the precise manual +post-activation check needed for those behaviors. Never describe evaluation as +a runtime test.