All checks were successful
CI / test (22) (pull_request) Successful in 48s
CI / test (true, 24) (pull_request) Successful in 1m4s
CI / flake (pull_request) Successful in 3s
CI / test (22) (push) Successful in 55s
CI / test (true, 24) (push) Successful in 1m5s
CI / flake (push) Successful in 2s
Grilling task 0042's mitigation found its framing too narrow. Recording an absolute entrypoint path is one defect; the deeper one is that `setup` is write-only, and an operator whose agent configuration is generated declaratively cannot let it write at all. On such a machine both halves fail — `setup hooks` against a read-only settings file, and `setup` on an unhandled filesystem error — and the Agent Skill gets hand-copied into the operator's own configuration, where it silently drifts from the package that ships it. Three tasks follow: - 0043 records the bare binary name, resolved through PATH, so the hook survives an upgrade on any wrapper-based install. Fixes the marker-substring coupling with it and drops the derivation's build-tree rename. - 0044 reports an unwritable target as a structured error naming no cause, rather than crashing. - 0045 adds the declarative install path: a stable Skill location, the Skill and hook specification exposed as Nix-consumable attributes, one committed hook specification read by both the expression and the test suite, and a home-manager module wiring them. Blocked by 0043, whose bare name the specification declares. CONTEXT.md gains the four terms this settled and amends `setup` and `SessionStart hook`, which described the imperative path as the only one. Entries for unbuilt work name the task that lands them, so the glossary does not assert behaviour the code lacks. The re-run-after-upgrade help text this branch added stays as it is: accurate until 0043 removes it, which that task carries as a criterion.
46 lines
4.3 KiB
Markdown
46 lines
4.3 KiB
Markdown
---
|
|
spec: nix-flake-packaging
|
|
blocked-by: 0043-hook-records-bare-binary-name
|
|
---
|
|
|
|
## What to build
|
|
|
|
Let a Nix configuration declare gitea-axi's ambient context, instead of running a command that writes it.
|
|
|
|
`setup` and `setup hooks` are write-only.
|
|
They install the Agent Skill and the SessionStart hook by writing into the user's agent configuration directory, which works only when the user owns those files imperatively.
|
|
An operator whose agent configuration is generated declaratively cannot use either: the targets are read-only, and the operator is left hand-copying the Skill into their own configuration, where it silently drifts from the package that ships it.
|
|
|
|
The spec currently lists a home-manager module under Out of Scope, deferring it until there was usage evidence that the trade-off was worth making.
|
|
That evidence now exists, and the deferral's stated reasoning does not survive it: the concern was the automatism that ADR 0009 rejected when it chose an explicit `setup` command over a postinstall script, and a module the operator explicitly imports and enables is the opposite of an implicit install.
|
|
Revising that Out of Scope entry, and recording the decision as an ADR, is part of this task.
|
|
|
|
Two layers, the second built on the first.
|
|
|
|
The package gains a stable, documented location for the bundled Agent Skill, and exposes both the Skill and the hook's specification as attributes a Nix expression can consume.
|
|
Today the Skill's only address is a path inside the installed node modules tree, which is an implementation detail no consumer should depend on.
|
|
|
|
On top of that, the flake exposes a home-manager module: a thin wiring layer that declares the Skill and the hook from those attributes.
|
|
It follows the conventions the home-manager module tree overwhelmingly uses — an enable option so that importing the module does nothing until it is switched on, an overridable package option, and installation of that package by default with a null value as the documented opt-out for an operator who supplies the binary another way.
|
|
Each managed piece has its own toggle, defaulting on, so an operator can take the Skill declaratively while continuing to write the hook by hand.
|
|
|
|
The hook's specification is declared once, in a committed file that both the Nix expression and the test suite read.
|
|
Declaring it in the Nix expression alone would create a second source of truth alongside the behaviour of the imperative install path, with nothing to keep them agreed; a test that hardcoded the same values a third time would verify nothing.
|
|
The test drives the imperative install against a temporary home directory and asserts that what it writes matches what the file declares, so a divergence — including one introduced by the SDK changing the envelope it writes — fails a test rather than passing silently into a release.
|
|
|
|
The two installation paths remain independent and both supported: the command for operators who own their configuration, the module for operators whose configuration owns them.
|
|
|
|
## Acceptance criteria
|
|
|
|
- [ ] The bundled Agent Skill is installed to a stable location in the package output that is not an internal implementation path.
|
|
- [ ] The package exposes the Skill and the hook specification as attributes consumable from a Nix expression without building or running anything.
|
|
- [ ] The hook specification is declared in a single committed file, read by both the Nix expression and the test suite.
|
|
- [ ] A test drives the imperative hook install and asserts that what it writes matches the declared specification, failing if either side drifts.
|
|
- [ ] The flake exposes a home-manager module that declares the Skill and the hook.
|
|
- [ ] Importing the module without enabling it changes nothing about the resulting configuration.
|
|
- [ ] The module installs the package by default, and accepts a null package as the documented way to declare the configuration without installing the binary.
|
|
- [ ] The Skill and the hook each have their own toggle, both defaulting to on.
|
|
- [ ] The module composes with an existing configuration that already declares its own SessionStart hooks and skills, rather than conflicting with it.
|
|
- [ ] The spec's Out of Scope entry excluding a home-manager module is revised, and the decision to reverse it is recorded as an ADR.
|
|
- [ ] The user-facing documentation describes both installation paths and when each applies.
|