feat: add Gas Town daemon systemd service (df-dr5) - #1422
Conversation
|
You do not have enough credits to review this pull request. Please purchase more credits to continue. |
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 27 minutes and 37 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughThis change introduces a new Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Suggested labels
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Mesa DescriptionTL;DRAdds a new What changed?
Description generated by Mesa. Update settings |
There was a problem hiding this comment.
Code Review
This pull request introduces a new systemd user service called gt-daemon for Gas Town orchestration, including its Nix configuration and a startup script. The review feedback highlights critical issues regarding environment variable expansion in systemd, where literal $HOME will not work and should be replaced with Nix interpolation. Additionally, the service requires the config object to be passed through for home directory access, and pkgs.grep should be added to the service's PATH to support the logic in the startup script.
| docker = import ./docker { inherit lib pkgs; }; | ||
| dockerPostgres = import ./docker-postgres { inherit pkgs; }; | ||
| dotfilesUpdater = import ./dotfiles-updater { inherit pkgs; }; | ||
| gtDaemon = import ./gt-daemon { inherit pkgs; }; |
| @@ -0,0 +1,31 @@ | |||
| { pkgs, ... }: | |||
| "PATH=${ | ||
| lib.makeBinPath [ | ||
| pkgs.bash | ||
| pkgs.coreutils | ||
| pkgs.git | ||
| pkgs.tmux | ||
| ] | ||
| }:$HOME/.local/bin:$HOME/go/bin:/usr/local/bin" |
There was a problem hiding this comment.
Systemd Environment variables do not perform shell expansion, so literal $HOME will not work as intended. Use ${config.home.homeDirectory} for interpolation. Additionally, grep is used in start.sh and should be explicitly included in the PATH via pkgs.grep to ensure the service is hermetic and works correctly across different environments.
"PATH=${\n lib.makeBinPath [\n pkgs.bash\n pkgs.coreutils\n pkgs.git\n pkgs.grep\n pkgs.tmux\n ]\n }:${config.home.homeDirectory}/.local/bin:${config.home.homeDirectory}/go/bin:/usr/local/bin"
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a Home Manager–managed systemd user service to run the Gas Town daemon and a bootstrap script to initialize/configure Gas Town before launching it.
Changes:
- Introduce
gt-daemonsystemd user service definition (Linux-only) and wire it into the services module list - Add
start.shbootstrap script that initializes Gas Town, ensures the dotfiles rig exists, and runsgt up - Remove obsolete
.beads/metadata.json
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| home-manager/services/gt-daemon/start.sh | New bootstrap entrypoint that initializes and then launches gt up. |
| home-manager/services/gt-daemon/default.nix | New systemd user service definition for gt-daemon, including PATH setup and restart policy. |
| home-manager/services/default.nix | Registers the new gt-daemon module in the services set. |
| .beads/metadata.json | Removes obsolete metadata file. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| pkgs.git | ||
| pkgs.tmux | ||
| ] | ||
| }:$HOME/.local/bin:$HOME/go/bin:/usr/local/bin" |
There was a problem hiding this comment.
In systemd unit files, Environment= values are not shell-expanded, so $HOME will typically remain literal. This can break PATH resolution for user-installed binaries (including gt). Use systemd specifiers like %h for the home directory (e.g., :%h/.local/bin:%h/go/bin) or set WorkingDirectory/ExecStart in a way that doesn't rely on $HOME expansion.
| }:$HOME/.local/bin:$HOME/go/bin:/usr/local/bin" | |
| }:%h/.local/bin:%h/go/bin:/usr/local/bin" |
| After = [ "network.target" ]; | ||
| }; | ||
| Service = { | ||
| Type = "simple"; |
There was a problem hiding this comment.
The service does not set WorkingDirectory. systemd services default to working directory / unless configured, which can cause gt status/init/rig to run in an unexpected directory (or fail due to permissions). Set WorkingDirectory = \"%h\"; (user unit) or cd to the desired directory at the top of start.sh to make service behavior deterministic.
| Type = "simple"; | |
| Type = "simple"; | |
| WorkingDirectory = "%h"; |
| ExecStart = "${pkgs.bash}/bin/bash ${./start.sh}"; | ||
| Restart = "always"; | ||
| RestartSec = 30; | ||
| }; |
There was a problem hiding this comment.
The service does not set WorkingDirectory. systemd services default to working directory / unless configured, which can cause gt status/init/rig to run in an unexpected directory (or fail due to permissions). Set WorkingDirectory = \"%h\"; (user unit) or cd to the desired directory at the top of start.sh to make service behavior deterministic.
| fi | ||
|
|
||
| # Add dotfiles rig if not already present | ||
| if ! gt rig list 2>/dev/null | grep -q dotfiles; then |
There was a problem hiding this comment.
grep -q dotfiles can produce false positives (e.g., matching my-dotfiles), which could prevent the rig from being added when required. Prefer an exact match (e.g., anchoring with grep -qx) or a more structured check based on gt rig list output format.
| if ! gt rig list 2>/dev/null | grep -q dotfiles; then | |
| if ! gt rig list 2>/dev/null | grep -qx 'dotfiles'; then |
| systemd.user.services.gt-daemon = lib.mkIf pkgs.stdenv.isLinux { | ||
| Unit = { | ||
| Description = "Gas Town daemon (dolt + tmux + worker orchestration)"; | ||
| After = [ "network.target" ]; |
There was a problem hiding this comment.
After=network.target does not guarantee usable network connectivity and is often a no-op in user units. If gt up requires network availability, consider switching to After=network-online.target plus Wants=network-online.target, or omit the dependency entirely if not needed.
| After = [ "network.target" ]; | |
| Wants = [ "network-online.target" ]; | |
| After = [ "network-online.target" ]; |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
spec/gt_daemon_spec.sh (1)
19-48: Add at least one behavior test (not only string checks).These tests only verify text presence; they won’t catch control-flow regressions (for example,
gt initrunning unconditionally). Consider adding a mocked-gtexecution test to assert call order and conditional behavior.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@spec/gt_daemon_spec.sh` around lines 19 - 48, The current tests only grep for text and should include at least one behavioral test that actually exercises the script with a mocked gt to assert call order and conditional behavior; add a new It block that sets up a temporary directory with a fake gt shim (executable script that logs its args to a file), prepend that temp dir to PATH, run the daemon script ($SCRIPT), then assert the shim log contains the expected sequence (e.g., "status" before "init") and that "init" is only invoked under the appropriate condition, using the existing spec harness assertions to check the log file contents and exit status; reference the existing test names like 'checks gt status before init' and 'runs gt init if not set up' to replace or augment those grep-only checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@home-manager/services/gt-daemon/default.nix`:
- Around line 13-23: The PATH in the Environment block for the service omits the
package that provides the gt binary, making start.sh (invoked by ExecStart)
non-deterministic; update the PATH construction inside lib.makeBinPath to
include the gt provider (e.g., pkgs.gas-town) so gt is available at runtime (or
alternatively add a comment/documentation that gt must be installed into
$HOME/.local/bin or $HOME/go/bin), ensuring start.sh can reliably find the gt
command.
In `@home-manager/services/gt-daemon/start.sh`:
- Around line 10-12: The current check using "gt rig list ... | grep -q
dotfiles" can match substrings like "dotfiles-old"; change the matching to
require an exact line match so the presence of the "dotfiles" rig is detected
correctly (e.g., replace the grep invocation in the condition with a strict
match such as grep -qx 'dotfiles' or an equivalent exact-line check), leaving
the "gt rig add dotfiles --adopt" call unchanged.
---
Nitpick comments:
In `@spec/gt_daemon_spec.sh`:
- Around line 19-48: The current tests only grep for text and should include at
least one behavioral test that actually exercises the script with a mocked gt to
assert call order and conditional behavior; add a new It block that sets up a
temporary directory with a fake gt shim (executable script that logs its args to
a file), prepend that temp dir to PATH, run the daemon script ($SCRIPT), then
assert the shim log contains the expected sequence (e.g., "status" before
"init") and that "init" is only invoked under the appropriate condition, using
the existing spec harness assertions to check the log file contents and exit
status; reference the existing test names like 'checks gt status before init'
and 'runs gt init if not set up' to replace or augment those grep-only checks.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d52f8dc9-bcea-4699-90f2-3f90d24eb5f2
📒 Files selected for processing (6)
.beads/metadata.jsonhome-manager/services/default.nixhome-manager/services/gt-daemon/default.nixhome-manager/services/gt-daemon/start.shspec/coverage_spec.shspec/gt_daemon_spec.sh
💤 Files with no reviewable changes (1)
- .beads/metadata.json
| Environment = [ | ||
| "PATH=${ | ||
| lib.makeBinPath [ | ||
| pkgs.bash | ||
| pkgs.coreutils | ||
| pkgs.git | ||
| pkgs.tmux | ||
| ] | ||
| }:$HOME/.local/bin:$HOME/go/bin:/usr/local/bin" | ||
| ]; | ||
| ExecStart = "${pkgs.bash}/bin/bash ${./start.sh}"; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify whether `gt` is provisioned declaratively anywhere in repo-managed Nix modules.
# Expected: find an explicit package or module that installs/provides `gt` for this user service.
echo "== References to gt-daemon and PATH construction =="
rg -n --no-heading -C2 'gt-daemon|makeBinPath|PATH='
echo
echo "== References that may provision gt in Nix config =="
fd -e nix | xargs rg -n --no-heading '\b(gt|gas[Tt]own|gas-town)\b' | head -200Repository: shunkakinoki/dotfiles
Length of output: 43432
🏁 Script executed:
cat -n home-manager/services/gt-daemon/start.sh | head -50Repository: shunkakinoki/dotfiles
Length of output: 496
🏁 Script executed:
# Search for any references to installing or providing `gt` in the repo
rg -n 'pkgs\.gt|pkgs\.gas.*town|\"gt\"' --type nixRepository: shunkakinoki/dotfiles
Length of output: 187
🏁 Script executed:
# Check if gt is mentioned in home-manager configuration
rg -n '\bgt\b' home-manager/services/gt-daemon/ -A2 -B2Repository: shunkakinoki/dotfiles
Length of output: 1312
🏁 Script executed:
# Search for gas-town package or gt provisioning in nix files (corrected)
rg -n 'gas.*town|gastown' --type nixRepository: shunkakinoki/dotfiles
Length of output: 47
🏁 Script executed:
# Check if there's a go package that installs gt
rg -n 'pkgs\.go' home-manager/services/gt-daemon/Repository: shunkakinoki/dotfiles
Length of output: 47
🏁 Script executed:
# Look for any installation or provisioning of gt in home-manager modules
rg -n 'install.*gt|provision.*gt' --type nixRepository: shunkakinoki/dotfiles
Length of output: 47
🏁 Script executed:
# Check what packages are available in the nix flake or configuration
fd -e "nix" -x grep -l "gas.*town\|gastown" {} \;Repository: shunkakinoki/dotfiles
Length of output: 47
Add gt package to PATH declaration.
The start.sh script requires the gt command (lines 5, 6, 10, 11, 15), but it is not included in the explicit makeBinPath list. The service will only work if gt is already installed in $HOME/.local/bin, $HOME/go/bin, or /usr/local/bin, making startup nondeterministic and potentially causing restart loops. Include pkgs.gas-town (or equivalent) in the PATH if available, or document how gt must be provisioned.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@home-manager/services/gt-daemon/default.nix` around lines 13 - 23, The PATH
in the Environment block for the service omits the package that provides the gt
binary, making start.sh (invoked by ExecStart) non-deterministic; update the
PATH construction inside lib.makeBinPath to include the gt provider (e.g.,
pkgs.gas-town) so gt is available at runtime (or alternatively add a
comment/documentation that gt must be installed into $HOME/.local/bin or
$HOME/go/bin), ensuring start.sh can reliably find the gt command.
| if ! gt rig list 2>/dev/null | grep -q dotfiles; then | ||
| gt rig add dotfiles --adopt | ||
| fi |
There was a problem hiding this comment.
Use stricter rig-name matching to avoid false positives.
Line 10’s grep -q dotfiles can match partial names (for example, dotfiles-old), which may skip gt rig add when the exact rig is absent.
Suggested fix
-if ! gt rig list 2>/dev/null | grep -q dotfiles; then
+if ! gt rig list 2>/dev/null | grep -Eq '(^|[[:space:]])dotfiles([[:space:]]|$)'; then
gt rig add dotfiles --adopt
fi📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if ! gt rig list 2>/dev/null | grep -q dotfiles; then | |
| gt rig add dotfiles --adopt | |
| fi | |
| if ! gt rig list 2>/dev/null | grep -Eq '(^|[[:space:]])dotfiles([[:space:]]|$)'; then | |
| gt rig add dotfiles --adopt | |
| fi |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@home-manager/services/gt-daemon/start.sh` around lines 10 - 12, The current
check using "gt rig list ... | grep -q dotfiles" can match substrings like
"dotfiles-old"; change the matching to require an exact line match so the
presence of the "dotfiles" rig is detected correctly (e.g., replace the grep
invocation in the condition with a strict match such as grep -qx 'dotfiles' or
an equivalent exact-line check), leaving the "gt rig add dotfiles --adopt" call
unchanged.
There was a problem hiding this comment.
♻️ Duplicate comments (1)
home-manager/services/gas-town/default.nix (1)
13-23:⚠️ Potential issue | 🟠 MajorMake
gtavailability deterministic in the service runtime PATH.Line 13-23 builds PATH without a declarative
gtprovider, whilehome-manager/services/gas-town/start.shusesgtcommands. Relying on$HOME/.local/bin,$HOME/go/bin, or/usr/local/binmakes startup host-dependent and can cause restart loops on fresh setups.#!/bin/bash set -euo pipefail echo "== PATH definition in gas-town service ==" sed -n '13,24p' home-manager/services/gas-town/default.nix echo echo "== gt usage in start script ==" rg -n '\bgt\b' home-manager/services/gas-town/start.sh echo echo "== Candidate declarative providers in nix files ==" rg -n --type nix 'pkgs\.(gt|gasTown)|pkgs\."gas-town"|gas-town|gastown'🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@home-manager/services/gas-town/default.nix` around lines 13 - 23, The service PATH is non-deterministic and may not include the gt binary used by start.sh; update the Nix service to declare a deterministic provider (e.g., add pkgs.gt or the appropriate pkgs.<gasTown> package) and include its bin directory in the Environment PATH expression so gt is always available at runtime, or change ExecStart/start.sh to call the explicit package path (${pkgs.gt}/bin/gt) referenced from the service. Modify the Environment array (the PATH definition) to include the package's bin and/or change ExecStart in default.nix and any gt invocations in start.sh to use the declared package's bin path (referencing Environment, ExecStart, start.sh, and the gt package symbol).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@home-manager/services/gas-town/default.nix`:
- Around line 13-23: The service PATH is non-deterministic and may not include
the gt binary used by start.sh; update the Nix service to declare a
deterministic provider (e.g., add pkgs.gt or the appropriate pkgs.<gasTown>
package) and include its bin directory in the Environment PATH expression so gt
is always available at runtime, or change ExecStart/start.sh to call the
explicit package path (${pkgs.gt}/bin/gt) referenced from the service. Modify
the Environment array (the PATH definition) to include the package's bin and/or
change ExecStart in default.nix and any gt invocations in start.sh to use the
declared package's bin path (referencing Environment, ExecStart, start.sh, and
the gt package symbol).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: a5520e66-762d-4c5b-9ea9-c9a7523f91f6
📒 Files selected for processing (5)
home-manager/services/default.nixhome-manager/services/gas-town/default.nixhome-manager/services/gas-town/start.shspec/coverage_spec.shspec/gas_town_spec.sh
✅ Files skipped from review due to trivial changes (1)
- home-manager/services/gas-town/start.sh
🚧 Files skipped from review as they are similar to previous changes (2)
- spec/coverage_spec.sh
- home-manager/services/default.nix
1fea9fa to
8e376cd
Compare
Summary
gt-daemonsystemd user service for Gas Town (dolt + tmux + worker orchestration)start.shbootstrap script (init, add dotfiles rig, exec gt up).beads/metadata.jsonIssue: df-dr5
Polecat: slit
Branch: polecat/slit-mnthp3aq
Tests: Passed (verified by refinery)
Created by Gas Town Refinery
Summary by cubic
Adds a user-scoped
systemdservice (gas-town) and a bootstrap script to run the Gas Town daemon viahome-manager. Fulfills Linear df-dr5 by supervisingdolt+tmux+ workers with auto-start and restart; unit renamed fromgt-daemontogas-townand exposed asgasTown.New Features
gas-townuser service with network dependency, PATH forgt, and 30s auto-restart.start.shinitializesgt, adoptsdotfilesrig, thenexec gt up.home-managerasgasTown; added shell test coverage.Migration
systemctl --user enable --now gas-townpkgs.stdenv.isLinux).Written for commit 8e376cd. Summary will update on new commits.