This prompt created the setup script ecosystem, including CI setup, dev setup, and end-user installation and configuration. It was provided to Claude Opus 4.5 via VSCode Agent mode.

The first draft was written by ChatGPT after some back-and-forth [in this conversation](https://chatgpt.com/share/6955f5ee-46f4-800b-87bc-db0e3df16541).

The output was committed as fc0c1ce51d739aafcdce66f6958f008ef056a76a.

-----

# Task: Implement unified script system for dev, build, install, and user hardening

## Objective

Implement a **single, composable script system** that:

* Avoids duplication between CI, developer, and runtime workflows
* Exposes clear, reversible primitives for build, install, and user hardening
* Uses one authoritative entrypoint with subcommands
* Allows CI, developers, and administrators to invoke the *same logic* with different scopes

The system must support:

* CI build-only environments
* Runtime-only systems
* Developer systems (union of build + runtime deps)
* Production installation and kiosk-style user hardening

---

## High-level design constraints

* **One CLI entrypoint** (script-based), with subcommands
* **Shared logic lives in libraries**, not duplicated scripts
* **All tasks must be independently callable**
* **All destructive actions must be reversible**
* **Dependency sets must be defined once and derived programmatically**
* Shell scripts are acceptable and preferred for system integration

---

## Required repository layout

```
scripts/
  shepherd              # main CLI dispatcher
  dev                   # thin wrapper → shepherd dev run
  admin                 # optional wrapper → shepherd admin ...

  lib/
    common.sh            # logging, error handling, sudo helpers
    deps.sh              # dependency set logic
    build.sh             # cargo build logic
    sway.sh              # nested sway execution helpers
    install.sh           # binary + config installation
    harden.sh            # harden / unharden user logic

  deps/
    build.pkgs           # build-only system packages
    run.pkgs             # runtime-only system packages
    dev.pkgs             # optional dev-only extras
```

No business logic should live in `Makefile` (if present).

---

## CLI interface (must be implemented)

### Dependency management

```
shepherd deps print build|run|dev
shepherd deps install build|run|dev
```

Behavior:

* `build` = build.pkgs
* `run` = run.pkgs
* `dev` = union(build, run, dev.pkgs)
* No duplicated lists anywhere

The build packages are currently listed in the CI definition (./.github/workflows/ci.yml). The CI definition should be updated to use this script for package management.
You may leave a stub for the runtime packages that only includes `sway`.

You may assume Ubuntu 25.10 or higher. Warn but do not fail if the environment indicates otherwise.

---

### Build

```
shepherd build            # debug build
shepherd build --release  # production build
```

Internals:

* Wrap `cargo build`
* Centralize binary names and target paths
* No logic duplication in dev/run/install paths

---

### Development run

```
shepherd dev run
```

This should be functionally equivalent to what is currently in `./run-dev` and will serve as its replacement.

Behavior:

* Builds (debug)
* Launches **nested sway**
* Executes built binaries with correct environment

This should reuse shared sway helpers (not inline logic).

---

### Installation (composable steps)

Each step must be callable independently.

```
shepherd install bins [--prefix PREFIX]
shepherd install config --user USER [--source CONFIG]
shepherd install all --user USER [--prefix PREFIX]
```

Requirements:

* Install release binaries to standard paths
* Install our global Sway configuration to a standard path
* Install desktop entry that tells the display manager to run shepherd-launcher via the Sway configuration (you will need to write this)
* Support PREFIX and DESTDIR
* Deploy example config to a specified user
* Do not assume hardening is enabled

---

### User hardening (reversible)

```
shepherd harden apply  --user USER
shepherd harden revert --user USER
```

Requirements:

* Harden a user so it can only run shepherd-launcher
* Support reverting to original system state
* Persist rollback state under:

  ```
  /var/lib/shepherdd/hardening/<user>/
  ```
* Hardening and unharden must be idempotent

No assumptions about display manager; logic should be isolated.

---

## Shared library responsibilities

### `lib/common.sh`

* Logging (`info`, `warn`, `error`)
* `require_root`, `maybe_sudo`
* Safe command execution helpers

### `lib/deps.sh`

* Read package lists
* Compute unions
* Install or print packages

### `lib/build.sh`

* Cargo build abstraction
* Debug vs release handling
* Binary discovery

### `lib/sway.sh`

* Nested sway environment setup
* Command execution inside sway
* Shared by dev and production paths

### `lib/install.sh`

* Binary install logic
* Config deployment logic

### `lib/harden.sh`

* Apply hardening
* Revert hardening
* Track system state changes

---

## Wrapper scripts

* `./run-dev` → `exec ./scripts/shepherd dev run`
* Optional `Makefile` targets may call `shepherd`, but must contain no logic

---

## Non-goals

* No Docker/Nix/devcontainer required
* No GUI tooling
* No distro-specific packaging beyond apt-style package lists
* No Rust rewrite of scripts unless strictly necessary

---

## Acceptance criteria

* CI can install **only build deps** and run `shepherd build`
* Runtime system can install **only run deps**
* Developer can install **dev deps** and run `./run-dev`
* Admin can:

  * install binaries
  * deploy config
  * harden and unharden a user safely
* No duplicated dependency lists
* No duplicated build or sway logic
