shep-deploy 0.2.2

A deploy dog for shep: watches a git branch, builds a release, swaps to it, and rolls back if it does not come up
# yaml-language-server: $schema=https://storage.googleapis.com/coderabbit_public_assets/schema.v2.json
#
# CodeRabbit review settings, adapted from shep's own .coderabbit.yaml. Rules
# that only make sense in a workspace with a documentation site and five crates
# are not here; what is left is the part that applies to a single-crate dog.
#
# Everything here is a deviation from a default, so a key that is absent is
# deliberate: it means the default is right.

language: en-US

# 250 characters, which is the cap. Spent on the two habits that produce
# comments nobody here will act on: rewriting prose that is deliberate, and
# repeating a lint CI already fails on.
tone_instructions: >-
  Be direct and specific. Prose in this repo is hand-written in a deliberate
  voice: flag factual drift, never style or wording. Do not repeat lints that
  CI already enforces as a required check.

reviews:
  # Assertive rather than the `chill` default. The label on this setting is
  # "may feel nitpicky", which is the trade: this dog runs a build command
  # taken from the repository it deploys, and swaps a live app onto the
  # result. A false positive costs a dismissed comment. A missed one costs an
  # operator their service, or runs someone else's code as root.
  profile: assertive

  auto_review:
    # release-plz opens these and merging one IS the release. The diff is a
    # version bump plus a changelog section generated from commits that were
    # each reviewed on their own pull request, so there is nothing here a
    # human will act on.
    #
    # Matched on a LABEL, which release-plz attaches through `pr_labels` in
    # release-plz.toml. `!release` means "review everything except a pull
    # request carrying this label".
    #
    # Two mechanisms that look right and are not, both learned in shep:
    # `ignore_usernames` fails because release-plz posts under the
    # maintainer's PAT, the same account as every other pull request here. And
    # `ignore_title_keywords` was tried there and did not hold: release-plz
    # force-pushes its branch on every push to main, each force-push starts an
    # incremental review, and the title gate is not re-evaluated on those. A
    # label is checked per review, so it survives the force-push.
    #
    # The label has to EXIST in the repository or release-plz opens the pull
    # request unlabelled. Created here on 2026-08-28. Renaming or deleting it
    # silently un-skips every release pull request, because this file matches
    # the name and nothing checks the two still agree.
    labels:
      - "!release"

  path_filters:
    - "!Cargo.lock"
    # Half generated by release-plz, half hand-written. Neither half wants a
    # review comment.
    - "!**/CHANGELOG.md"

  path_instructions:
    - path: "src/**/*.rs"
      instructions: >-
        This crate follows shep's written Rust style, docs/idiomatic-rust.md in
        the shep repository, rules IR-1 through IR-46. That file is NOT in this
        repository, so the load-bearing rules are restated here rather than
        cited: no panicking constructor; `core::error::Error`, never
        `std::error::Error`; every fallible public function carries a `# Errors`
        section; a `# Panics` section requires `#[track_caller]`; every new
        public item needs documentation and a deliberate `Debug` decision,
        redacted for anything carrying environment or secrets and proven by an
        exact-string test.

        `#![forbid(unsafe_code)]` holds at src/main.rs. That is why users are
        resolved by shelling out to `id` rather than calling `getpwnam`, and why
        `O_NOFOLLOW` is spelled as a numeric constant per platform.

        Do not suggest widening an input grammar past what the code refuses. A
        refusal here is usually deliberate and says so in its own error: a
        top-level `[build]` block, an artifact path that leaves the release, a
        `retention` below 2.

    - path: "src/build.rs"
      instructions: >-
        This file is the security surface of the crate and has had seven review
        rounds. A build command comes from the repository being deployed, so
        whoever can land a commit on the tracked branch chooses code that runs
        on the operator's host, at the dog's own uid unless the app sets `user`.

        Three bounds exist and each has a precise edge: the uid/gid drop bounds
        the CHILD only, so anything the parent does afterwards on paths the
        child chose is outside it; the cleared environment bounds what a build
        inherits from this process; and `user` is the only one that also covers
        what a build can READ.

        `copy_artifact` runs in the parent at the dog's own uid. Treat any
        change to its containment checks, its `O_NOFOLLOW` open, or the order
        of check and use as security-critical. Past escapes were a `..` in an
        artifact path, a committed `target` symlink, a `CARGO_TARGET_DIR`
        pointing outside, and a symlinked parent directory.

    - path: "**/*.md"
      instructions: >-
        Prose here is hand-written and hand-wrapped in a deliberate voice. Do
        not suggest rewording, tightening, or rewrapping. Flag only factual
        drift: a claim about behaviour the diff makes false, a command that no
        longer exists, a sample that will not parse. A copy-pasteable sample in
        README.md that has gone stale is a real finding.

        Terminology is fixed by shep's docs/terminology.md, which is not in this
        repository. A `sheep` is one managed process and the word is singular
        only; the plural is `flock`, never "sheeps" and never bare "sheep".
        `dogs` are plugin processes, this crate being one, and the daemon is
        only ever "the shepherd".

    - path: ".github/workflows/**"
      instructions: >-
        Every job needs `timeout-minutes`; GitHub's default is 360.

        The two release-plz workflows hold RELEASE_PLZ_TOKEN and
        CARGO_REGISTRY_TOKEN, and every action in them is pinned by commit SHA
        on purpose. test.yml holds no secrets and uses moving tags. Flag a
        moving tag introduced into either release workflow; do not flag the
        tags in test.yml.

  tools:
    # CI runs clippy with `-D warnings` as a required check on every push and
    # pull request. A second clippy here reports the same findings later.
    clippy:
      enabled: false
    # No JavaScript or CSS in this repository at all.
    eslint:
      enabled: false
    biome:
      enabled: false
    oxc:
      enabled: false
    stylelint:
      enabled: false
    # Unlike shep, this repository runs no `typos` check, so disabling
    # LanguageTool does leave spelling unchecked by any tool. Disabled anyway:
    # what it actually produces on this prose is style opinions about wording
    # that is deliberate, which is the one thing tone_instructions above asks
    # for less of. A misspelling here is cheaper than that noise.
    languagetool:
      enabled: false
    markdownlint:
      enabled: false

  # No issue has ever been opened on this repository and the label set is
  # GitHub's untouched default, so each of these spends a section of the
  # walkthrough on a question with no answer.
  assess_linked_issues: false
  related_issues: false
  suggested_labels: false
  # One maintainer.
  suggested_reviewers: false

knowledge_base:
  code_guidelines:
    # An explicit list replaces the defaults rather than adding to them, so the
    # default pattern this repository actually uses is restated.
    filePatterns:
      - "**/CLAUDE.md"
      - "**/AGENTS.md"