feat(nix): install the CLI unconditionally, gate context per harness (task 0046) #55

Merged
alexion merged 1 commits from task-0046-reshape-hm-module-per-harness-toggle into main 2026-07-20 19:55:57 -04:00
Owner

Implements .claude/tasks/0046-reshape-hm-module-per-harness-toggle.md.

Summary

Reshapes the home-manager module so that enabling gitea-axi means "install the CLI, always", and the Claude Code agent context follows the harness.

  • programs.gitea-axi.enable now installs the binary unconditionally.
  • The two per-artefact toggles (skill.enable, sessionStartHook.enable) and their assertion are replaced by one per-harness toggle, enableClaudeCodeIntegration (default literal true). Its artefacts land only when programs.claude-code.enable is also on, and are silently absent otherwise — no assertion.
  • The Agent Skill is written through home.file into Claude Code's skills directory (reading configDir from the sibling module), rather than contributed to programs.claude-code.skills. This composes with both the attribute-set and whole-directory forms of an operator's own skills option, fixing the path-form collision at its root.
  • The Skill write is gated on programs.claude-code.enable explicitly (which also keeps package realisation lazy); the hook keeps its sibling-module gate for free. The asymmetry is commented in the module.
  • package = null fallback unchanged.
  • INSTALL.md updated to the new option surface; the path-form skills limitation paragraph removed. ADR 0021 and the parent spec are included.

Supersedes three decisions of ADR 0020, per ADR 0021.

Verified by evaluating the real module through home-manager.lib.homeManagerConfiguration under four configurations (both-on, Claude Code off, integration off, package = null); all matched the intended behaviour. The automated nix flake check proof of this composition is the follow-up task 0047, whose task file is included here but implemented separately.

No deviations from the plan.

Review

Risk

Overall: Medium

  • Blast radius — Low. One home-manager-module.nix plus its docs/ADR/spec/task files; no source code, no callers, self-contained flake output.
  • Reversibility — Low. The module is unreleased with no consumers, so the option renames break nothing and revert trivially.
  • Test coverage — Medium. The diff itself adds no check; the composition proof is deferred to task 0047. Task 0046 claims manual verification across four configs, but there is no automated test in this diff.
  • Sensitive domain — Medium. Touches the SessionStart hook and Skill installation (agent context) and lazy package realisation via gating; not auth/payments, but the explicit claude-code.enable gate is a correctness-and-realisation-cost concern.
  • Size & complexity — Medium. Module logic is small and readable, but the nested mkIf/mkMerge gating asymmetry is subtle.
  • Runtime criticality — Low. Declarative dev-time install path; the imperative setup path is unchanged and still available.

Standards — unaddressed

  • Duplicated Code (judgement call): the asymmetric-gating rationale and the recursive path-form-install coupling each appear in ADR 0021, the spec, the task file, and the module comments. Left as-is: this intentional redundancy across decision records is the repo's ADR/spec/task convention, not a defect to collapse.

The one documented-standard finding (multi-sentence Markdown lines in the task file's Implementation Notes) was fixed in this diff.

Spec

No findings — the diff faithfully implements task 0046, with no missing requirements, no scope creep, and no implemented-but-wrong behaviour.

Implements `.claude/tasks/0046-reshape-hm-module-per-harness-toggle.md`. ## Summary Reshapes the home-manager module so that enabling gitea-axi means "install the CLI, always", and the Claude Code agent context follows the harness. - `programs.gitea-axi.enable` now installs the binary unconditionally. - The two per-artefact toggles (`skill.enable`, `sessionStartHook.enable`) and their assertion are replaced by one per-harness toggle, `enableClaudeCodeIntegration` (default literal `true`). Its artefacts land only when `programs.claude-code.enable` is also on, and are silently absent otherwise — no assertion. - The Agent Skill is written through `home.file` into Claude Code's skills directory (reading `configDir` from the sibling module), rather than contributed to `programs.claude-code.skills`. This composes with both the attribute-set and whole-directory forms of an operator's own skills option, fixing the path-form collision at its root. - The Skill write is gated on `programs.claude-code.enable` explicitly (which also keeps package realisation lazy); the hook keeps its sibling-module gate for free. The asymmetry is commented in the module. - `package = null` fallback unchanged. - INSTALL.md updated to the new option surface; the path-form skills limitation paragraph removed. ADR 0021 and the parent spec are included. Supersedes three decisions of ADR 0020, per ADR 0021. Verified by evaluating the real module through `home-manager.lib.homeManagerConfiguration` under four configurations (both-on, Claude Code off, integration off, `package = null`); all matched the intended behaviour. The automated `nix flake check` proof of this composition is the follow-up task 0047, whose task file is included here but implemented separately. No deviations from the plan. ## Review ### Risk **Overall: Medium** - Blast radius — Low. One `home-manager-module.nix` plus its docs/ADR/spec/task files; no source code, no callers, self-contained flake output. - Reversibility — Low. The module is unreleased with no consumers, so the option renames break nothing and revert trivially. - Test coverage — Medium. The diff itself adds no check; the composition proof is deferred to task 0047. Task 0046 claims manual verification across four configs, but there is no automated test in this diff. - Sensitive domain — Medium. Touches the SessionStart hook and Skill installation (agent context) and lazy package realisation via gating; not auth/payments, but the explicit `claude-code.enable` gate is a correctness-and-realisation-cost concern. - Size & complexity — Medium. Module logic is small and readable, but the nested `mkIf`/`mkMerge` gating asymmetry is subtle. - Runtime criticality — Low. Declarative dev-time install path; the imperative `setup` path is unchanged and still available. ### Standards — unaddressed - **Duplicated Code (judgement call)**: the asymmetric-gating rationale and the recursive path-form-install coupling each appear in ADR 0021, the spec, the task file, and the module comments. Left as-is: this intentional redundancy across decision records is the repo's ADR/spec/task convention, not a defect to collapse. The one documented-standard finding (multi-sentence Markdown lines in the task file's Implementation Notes) was fixed in this diff. ### Spec No findings — the diff faithfully implements task 0046, with no missing requirements, no scope creep, and no implemented-but-wrong behaviour.
alexion added 1 commit 2026-07-20 19:51:28 -04:00
feat(nix): install the CLI unconditionally, gate context per harness (task 0046)
All checks were successful
CI / test (22) (pull_request) Successful in 52s
CI / test (true, 24) (pull_request) Successful in 1m4s
CI / flake (pull_request) Successful in 3s
CI / test (22) (push) Successful in 48s
CI / test (true, 24) (push) Successful in 1m2s
CI / flake (push) Successful in 3s
534097121d
Reshape the home-manager module so `programs.gitea-axi.enable` installs the
binary always, and the Claude Code context follows the harness. The two
per-artefact toggles and their assertion are replaced by one per-harness
toggle, `enableClaudeCodeIntegration` (default true); its artefacts land only
when `programs.claude-code.enable` is also on, silently absent otherwise.

The Agent Skill is now written through home.file into Claude Code's skills
directory, rather than contributed to `programs.claude-code.skills`, so it
composes with both the attribute-set and whole-directory forms of an operator's
own skills option. The Skill write is gated on `claude-code.enable` explicitly
(keeping package realisation lazy); the hook keeps its sibling-module gate for
free, and the asymmetry is commented. Supersedes three decisions of ADR 0020;
recorded in ADR 0021.

INSTALL.md is updated to the new option surface and the path-form limitation
paragraph removed. Adds the parent spec and the follow-up task 0047 (the flake
check proving composition, implemented separately).
alexion merged commit 534097121d into main 2026-07-20 19:55:57 -04:00
alexion deleted branch task-0046-reshape-hm-module-per-harness-toggle 2026-07-20 19:55:57 -04:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: alexion/gitea-axi#55