CtrlK
BlogDocsLog inGet started
Tessl Logo

jbaruch/coding-policy

General-purpose coding policy for Baruch's AI agents

73

Quality

91%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Low

Low-risk findings worth noting

Overview
Quality
Evals
Security
Files

compose-briefs.shskills/herdr-foreman/

#!/usr/bin/env bash
# Compose one round's briefs from the packaged templates.
#
# Substitution is a pure function of (template, values), so it belongs in a
# script rather than in an agent's hands (`rules/script-delegation.md`): a
# placeholder the agent forgets to fill reaches a worker as the literal
# `{{WORKTREE}}`, and a worker with a cleared context has no way to notice.
#
# Contract:
#   argv  : <templates-dir> <values-json-file> <output-dir>
#   values: {"shared": {"KEY": "value", ...},
#            "roles":  {"<role>": {"KEY": "value", ...}, ...}}
#           `shared` fills COMMON.md and every brief; a role's own values win
#           on a collision. Roles map to `brief-<role>.md` in the templates dir;
#           a seat `<role>#<slice>` takes its role's template.
#           advisor/investigator/architect fall back to brief-specialist.md.
#           SPECIALIST_CONTEXT defaults to empty only where the template uses it.
#   stdout: one JSON object —
#           {"common":"<path>","briefs":{"<role>":"<path>", ...}}
#   stderr: diagnostics only.
#   exit  : 0 every file written with no placeholder left,
#           1 precondition unmet (usage, missing dir/file/template, no jq,
#             no python3),
#           2 validation failed — an unfilled placeholder, a supplied key no
#             template uses, a value that is not text, an invalid/reused REPORT
#             path, a REPORT longer than FOREMAN_REPORT_PATH_MAX_COLS, or a reviewer/tester
#             REVIEW_PACKAGE that is not an absolute readable non-empty file,
#             or an unreadable POLICY_INDEX / RELEASE_SKILL / TEAM_OPERATION
#             artifact, an absent TEAM_OPERATION key, or a common template
#             with no {{TEAM_OPERATION}} placeholder.
#             Nothing is written on a
#             validation failure,
#           3 a tool this depends on failed (the placeholder scan, or the
#             renderable-text check in foreman/renderable.py). The answer is
#             unknown, which is never reported as "no placeholders".
#           A REPORT, POLICY_INDEX, RELEASE_SKILL, TEAM_OPERATION or REVIEW_PACKAGE
#           path, or a
#           SLICE_PATHS glob, that foreman/renderable.py refuses is exit 2.
#   env   : FOREMAN_REPORT_PATH_MAX_COLS overrides the REPORT length limit
#           (tests, a fleet whose narrowest pane is wider); a non-integer or
#           zero value is a precondition failure (exit 1).
#
# Validation runs in both directions on purpose. An unfilled placeholder is a
# brief that lies to a worker; a supplied key nothing uses is a value the foreman
# believes it sent and did not.
set -euo pipefail

# A placeholder is upper-case, digits, and underscores between double braces.
PLACEHOLDER_RE='\{\{[A-Z0-9_]+\}\}'
# Longest REPORT value a brief may carry. The worker's final message ends with
# `REPORT: <path>`, and the wait confirms the complete literal on one visible
# row. A TUI wraps that line at its own content width and a wrap cannot be told
# from a newline, so the path must fit one row of the pane it is sent to. This
# cap is a coarse composition-time bound only: no brief knows its pane, so
# `foreman apply` measures the live pane width and refuses a marker that pane
# would wrap (`marker_columns` in foreman/report_delivery.py).
FOREMAN_REPORT_PATH_MAX_COLS="${FOREMAN_REPORT_PATH_MAX_COLS:-100}"

warn() { printf 'compose-briefs: %s\n' "$1" >&2; }

SKILL_DIR="$(CDPATH='' cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# Whether one JSON value (a string or an array of strings) stays intact on a
# rendered line. The character rule is `foreman/renderable.py`, the one check
# the report marker, the GATES block and every brief path share (#578).
# Returns 0 renderable, 1 not, 3 when the check itself could not run. An exit
# code alone is no verdict: python3 also exits 1 on an uncaught exception such
# as a failed import, so a verdict counts only when stdout carries the
# module's JSON object agreeing with the exit code.
renderable_json() { # <json-value> [--code-span]
  local rc=0 out verdict
  out="$(printf '%s' "$1" | PYTHONPATH="${SKILL_DIR}${PYTHONPATH:+:${PYTHONPATH}}" \
    python3 -m foreman.renderable ${2:+"$2"})" || rc=$?
  case "$rc" in
    0) verdict=true ;;
    1) verdict=false ;;
    *) verdict="" ;;
  esac
  if [[ -n "$verdict" ]] \
     && printf '%s' "$out" | jq -e --argjson v "$verdict" \
          'type == "object" and .renderable == $v' >/dev/null; then
    return "$rc"
  fi
  warn "the renderable-text check failed (exit ${rc}, no verdict on stdout) — the value could not be checked; confirm python3 runs and ${SKILL_DIR}/foreman/renderable.py is installed"
  return 3
}

#: The responsibilities a SEAT may fill, mirroring `tiers.SEATABLE_ROLES`.
SEATABLE_ROLES="reviewer tester"

# The slice boundary a seat's brief carries, or empty for a plain role. Derived
# from the seat, so a round cannot dispatch several full-surface verdicts by
# forgetting to write the boundary by hand (skills/herdr-foreman/references/team-operation.md
# Review Before PR).
slice_scope() { # <role-or-seat> <slice-paths-json> <digest>
  # Named paths, not just a slice name: a boundary a worker cannot resolve is
  # not a boundary, and the composer receives no partition document.
  local listed
  case "$1" in
    *"#"*)
      listed="$(printf '%s' "$2" | jq -r 'map("`" + . + "`") | join(", ")')" || return 3
      printf 'Your slice this round is **%s**, and it owns %s. That slice is your whole surface: a full pass covers all of it and nothing beyond it. An observation outside your slice goes in a separate section of your report and forms no part of your verdict. (Partition %s.)' \
        "${1#*#}" "$listed" "$3"
      ;;
    *) printf '' ;;
  esac
}

template_for_role() { # <templates> <role>
  # A seat (`reviewer#api`) takes its ROLE's template: the slice is brief
  # content, never a separate template to author (#434).
  local role="${2%%#*}"
  local path="${1}/brief-${role}.md"
  if [[ ! -r "$path" ]]; then
    case "$role" in
      advisor|investigator|architect) path="${1}/brief-specialist.md" ;;
    esac
  fi
  printf '%s\n' "$path"
}

# Echo every distinct placeholder name in <file>, one per line.
placeholders_in() { # <file>
  local found rc=0
  found="$(grep -oE "$PLACEHOLDER_RE" "$1")" || rc=$?
  if (( rc == 1 )); then return 0; fi
  if (( rc != 0 )); then
    warn "cannot scan placeholders in ${1} — check file permissions and the grep installation"
    return 2
  fi
  if ! printf '%s\n' "$found" | sed -e 's/^{{//' -e 's/}}$//' | sort -u; then
    warn "cannot normalize placeholders in ${1} — check the sed and sort installation"
    return 2
  fi
}

# Echo the placeholders still standing in <text>, space separated and sorted.
#
# Returns 0 when the scan RAN — empty output then means none are left — and 2
# when the scan itself failed. `grep` exits 1 on no-match and 2 on a real error
# (an unreadable input, a bad pattern), and collapsing those two into "nothing
# found" is what would let an unrendered brief pass validation
# (rules/error-handling.md Shell Error Handling).
leftover_placeholders() { # <text>
  local found rc=0 sorted
  found="$(printf '%s' "$1" | grep -oE "$PLACEHOLDER_RE")" || rc=$?
  if (( rc == 1 )); then
    printf ''
    return 0
  fi
  if (( rc != 0 )); then
    warn "the placeholder scan failed (grep exit ${rc}) — the rendered text could not be checked; re-run, and check that grep is a working GNU/BSD grep"
    return 2
  fi
  rc=0
  sorted="$(printf '%s' "$found" | sort -u | tr '\n' ' ')" || rc=$?
  if (( rc != 0 )); then
    warn "the placeholder scan failed while sorting its matches (exit ${rc}) — the rendered text could not be checked; re-run"
    return 2
  fi
  printf '%s' "$sorted"
  return 0
}

# Refuse a value that is not text before it reaches a brief.
#
# `jq -r` prints a JSON null as the four characters `null`, which substitutes
# cleanly and leaves NO placeholder behind — the brief then reads as fully
# rendered while telling a worker its worktree is at `null`. Objects and arrays
# arrive as JSON fragments the same way.
validate_values() { # <values-json> <label>
  local offenders
  offenders="$(printf '%s' "$1" | jq -r '
    to_entries
    | map(select((.value | type) as $t | $t != "string" and $t != "number"))
    | map("\(.key) (\(.value | type))")
    | join(", ")')" || {
    warn "could not inspect the values for ${2} — check that they are a JSON object"
    return 2
  }
  if [[ -n "$offenders" ]]; then
    warn "${2} carries values that are not text: ${offenders} — give each one a string (a JSON null renders as the literal 'null' in a brief)"
    return 2
  fi
  return 0
}

validate_review_package() { # <merged-values-json> <role-or-seat>
  # A seat (`reviewer#api`) owes its ROLE's review-package checks: the slice
  # narrows what it reviews, never what its brief must carry (#434).
  local role="${2%%#*}"
  case "$role" in reviewer|tester) ;; *) return 0 ;; esac
  local package ref key
  for key in REVIEW_BASE REVIEW_HEAD; do
    ref="$(printf '%s' "$1" | jq -r --arg k "$key" '.[$k] // ""')" || return 2
    if [[ ! "$ref" =~ ^([0-9a-f]{40}|[0-9a-f]{64})$ ]]; then
      warn "${key} for role '${2}' must be a full lowercase commit SHA — resolve the recorded range with git rev-parse before composing"
      return 2
    fi
  done
  local package_json check_rc=0
  package_json="$(printf '%s' "$1" | jq -c '.REVIEW_PACKAGE')" || return 2
  renderable_json "$package_json" --code-span || check_rc=$?
  if (( check_rc == 3 )); then return 3; fi
  if (( check_rc != 0 )); then
    warn "REVIEW_PACKAGE for role '${2}' must be a file path without control, format or line-separator characters or backticks (the brief renders it in a code span) — run review-package.sh for the recorded range and pass its output path"
    return 2
  fi
  package="$(printf '%s' "$1" | jq -r '.REVIEW_PACKAGE // ""')" || return 2
  if [[ "$package" != /* \
        || ! -f "$package" || ! -r "$package" || ! -s "$package" ]]; then
    warn "REVIEW_PACKAGE for role '${2}' must name an absolute readable non-empty file — run review-package.sh for the recorded range and pass its output path"
    return 2
  fi
}

# Echo <template> with every KEY=VALUE pair in the given JSON object applied.
substitute() { # <template-file> <values-json>
  local content key value
  content="$(cat "$1")"
  while IFS= read -r key; do
    [[ -n "$key" ]] || continue
    value="$(printf '%s' "$2" | jq -r --arg k "$key" '.[$k]')"
    content="${content//\{\{$key\}\}/$value}"
  done < <(printf '%s' "$2" | jq -r 'keys[]')
  printf '%s\n' "$content"
}

main() {
  if (( $# != 3 )); then
    warn "usage: compose-briefs.sh <templates-dir> <values-json-file> <output-dir>"
    return 1
  fi
  local templates="$1" values_file="$2" outdir="$3"

  case "$FOREMAN_REPORT_PATH_MAX_COLS" in
    ''|*[!0-9]*)
      warn "FOREMAN_REPORT_PATH_MAX_COLS must be a positive integer, got '${FOREMAN_REPORT_PATH_MAX_COLS}' — unset it to use the script's default"
      return 1
      ;;
  esac
  if (( 10#$FOREMAN_REPORT_PATH_MAX_COLS < 1 )); then
    warn "FOREMAN_REPORT_PATH_MAX_COLS must be a positive integer, got '${FOREMAN_REPORT_PATH_MAX_COLS}' — unset it to use the script's default"
    return 1
  fi
  # Normalize to decimal once, so a validated `08` is not reparsed as octal.
  FOREMAN_REPORT_PATH_MAX_COLS=$(( 10#$FOREMAN_REPORT_PATH_MAX_COLS ))

  if ! command -v jq >/dev/null 2>&1; then
    warn "jq not found on PATH — install it (\`brew install jq\`) to compose briefs"
    return 1
  fi
  if ! command -v python3 >/dev/null 2>&1; then
    warn "python3 not found on PATH — install Python 3.11+ (\`brew install python@3.11\`) to compose briefs"
    return 1
  fi
  if [[ ! -d "$templates" ]]; then
    warn "templates dir not found: ${templates} — point at skills/herdr-foreman/templates"
    return 1
  fi
  if [[ ! -r "$values_file" ]]; then
    warn "values file not readable: ${values_file}"
    return 1
  fi

  local values rc=0
  values="$(jq -e '.' < "$values_file" 2>/dev/null)" || rc=$?
  if (( rc != 0 )); then
    warn "values file ${values_file} is not valid JSON — fix it and re-run"
    return 1
  fi
  local roles
  roles="$(printf '%s' "$values" | jq -r '.roles | keys[]' 2>/dev/null)" || {
    warn "values file ${values_file} has no .roles object — see the contract at the top of this script"
    return 1
  }
  if [[ -z "$roles" ]]; then
    warn "values file ${values_file} names no roles — nothing to compose"
    return 1
  fi
  # In jq, before the keys become a newline-delimited list: a key carrying a
  # newline is split into two pseudo-roles by the `while read` below, so a
  # later shell test never sees the offending key at all.
  local bad_key
  bad_key="$(printf '%s' "$values" | jq -r '[.roles | keys[] | select(length == 0 or test("[/=,\u0000-\u001f\u007f]"))] | first // empty')" || return 2
  if [[ -n "$bad_key" ]]; then
    warn "values file ${values_file} has a role key that cannot name the brief it writes — a key carrying a path separator, '=', ',' or a control character does not read back through the output path and the CLI keys"
    return 2
  fi

  local shared
  shared="$(printf '%s' "$values" | jq -c '.shared // {}')"

  # Every source file must exist before anything is written.
  local common_tpl="${templates}/COMMON.md" role role_tpl seatable_base
  if [[ ! -r "$common_tpl" ]]; then
    warn "template not found: ${common_tpl}"
    return 1
  fi
  while IFS= read -r role; do
    # The key names the brief this run WRITES (`brief-<role>.md`), so it is
    # checked before it reaches a path. `template_for_role` resolves a seat to
    # its role, which would otherwise let `reviewer#/../../outside` take the
    # reviewer template and redirect the output outside `outdir` (#434). The
    # CLI's own `require_seatable` is not in the picture when this script runs
    # directly.
    # A denylist, not an allowlist: the planner accepts any custom role name,
    # so rejecting more than what could reach a path would break the plan →
    # compose round-trip for a round the planner happily emits.
    # Exactly what cannot name `brief-<role>.md` inside the output directory or
    # read back through `--brief ROLE=PATH` and `--roles a,b`. The `brief-`
    # prefix makes a leading dot or dash harmless, and `..` without a separator
    # names an ordinary file, so neither is rejected: the planner emits custom
    # roles, and everything it emits has to compose.
    # The jq pass above rejects the whole set before the keys are split into
    # lines; this arm catches what a line-oriented read could still hand us.
    if [[ -z "$role" || "$role" == *"/"* || "$role" == *"="* || "$role" == *","* ]]; then
      warn "role key '${role}' cannot name the brief it writes — a key carrying a path separator, '=', ',' or a control character does not read back through the output path and the CLI keys"
      return 2
    fi
    # Only a responsibility whose verification a slice terminates is seated;
    # `plan`, `apply` and recovery all refuse the rest, so composing a brief
    # for one would write a round nothing downstream accepts (#434).
    if [[ "$role" == *"#"* ]] && ! [[ "${role#*#}" =~ ^[A-Za-z0-9][A-Za-z0-9_.-]*$ ]]; then
      warn "seat '${role}' names the slice '${role#*#}', which cannot address it: name a slice with letters, digits, underscores, dots or hyphens, starting with a letter or digit"
      return 2
    fi
    if [[ "$role" == *"#"* ]]; then
      # An exact arm, never substring membership: `reviewer tester#api` matches
      # inside " reviewer tester " and would pass as a seat.
      case " ${SEATABLE_ROLES} " in
        *" ${role%%#*} "*)
          case "${role%%#*}" in
            *[[:space:]]*) seatable_base="" ;;
            *) seatable_base="${role%%#*}" ;;
          esac ;;
        *) seatable_base="" ;;
      esac
      if [[ -z "$seatable_base" ]]; then
        warn "role key '${role}' seats '${role%%#*}', and only ${SEATABLE_ROLES// /, } are seated — every other responsibility holds a per-task counter one worker owns"
        return 2
      fi
    fi
    role_tpl="$(template_for_role "$templates" "$role")"
    if [[ ! -r "$role_tpl" ]]; then
      warn "template not found: ${role_tpl} — supply the packaged role template"
      return 1
    fi
  done <<< "$roles"

  # Compose into memory first: a validation failure must leave no half-written
  # round behind, and no output directory either (`rules/file-hygiene.md`
  # Idempotency); the directory is created only once every check has passed.
  local -a out_paths=() out_bodies=() report_paths=()
  local merged rendered leftovers supplied known common_known unused key report rendered_scope slice_digest
  local common_body scan_rc=0 check_rc=0
  validate_values "$shared" "the shared values" || return 2
  # Resolver-produced policy paths are explicit brief inputs. Custom templates
  # need not carry POLICY_INDEX or RELEASE_SKILL; any supplied artifact must
  # remain readable at compose. TEAM_OPERATION is different: every worker brief
  # names the team-round contract as a required read (rules/agent-team-operation.md
  # Team Round Contract), so the key is required and COMMON.md must render it,
  # whichever templates the foreman passes.
  local policy_key policy_path policy_present
  if ! printf '%s' "$shared" | jq -e 'has("TEAM_OPERATION")' >/dev/null; then
    warn "TEAM_OPERATION is required in .shared — every worker brief names the team-round contract; run resolve-policy-paths.sh and copy its TEAM_OPERATION path"
    return 2
  fi
  common_known="$(placeholders_in "$common_tpl")" || return 3
  if [[ $'\n'"${common_known}"$'\n' != *$'\nTEAM_OPERATION\n'* ]]; then
    warn "$(basename "$common_tpl") carries no {{TEAM_OPERATION}} placeholder — every worker brief must render the team-round contract path; add it to the common template"
    return 2
  fi
  for policy_key in POLICY_INDEX RELEASE_SKILL TEAM_OPERATION; do
    policy_present="$(printf '%s' "$shared" | jq -r --arg k "$policy_key" 'has($k)')" || return 2
    if [[ "$policy_present" == true ]]; then
      check_rc=0
      renderable_json "$(printf '%s' "$shared" | jq -c --arg k "$policy_key" '.[$k]')" --code-span || check_rc=$?
      if (( check_rc == 3 )); then return 3; fi
      if (( check_rc != 0 )); then
        warn "${policy_key} must be a file path without control, format or line-separator characters or backticks (the brief renders it in a code span) — use resolve-policy-paths.sh output"
        return 2
      fi
      policy_path="$(printf '%s' "$shared" | jq -r --arg k "$policy_key" '.[$k]')" || return 2
      if [[ "$policy_path" != /* || ! -f "$policy_path" || ! -r "$policy_path" || ! -s "$policy_path" ]]; then
        warn "${policy_key} must name an absolute readable non-empty file — run resolve-policy-paths.sh and supply its output before composing"
        return 2
      fi
    fi
  done
  common_body="$(substitute "$common_tpl" "$shared")"
  leftovers="$(leftover_placeholders "$common_body")" || scan_rc=$?
  if (( scan_rc != 0 )); then return 3; fi
  if [[ -n "${leftovers// /}" ]]; then
    warn "COMMON.md still holds unfilled placeholders: ${leftovers}— add them to .shared"
    return 2
  fi
  out_paths+=("${outdir}/COMMON.md")
  out_bodies+=("$common_body")

  while IFS= read -r role; do
    role_tpl="$(template_for_role "$templates" "$role")"
    local policy_override
    policy_override="$(printf '%s' "$values" | jq -r --arg r "$role" '.roles[$r] | has("POLICY_INDEX") or has("RELEASE_SKILL") or has("TEAM_OPERATION")')" || return 2
    if [[ "$policy_override" == true ]]; then
      warn "policy artifact paths for role '${role}' belong only in .shared — remove per-role POLICY_INDEX, RELEASE_SKILL and TEAM_OPERATION keys"
      return 2
    fi
    merged="$(jq -c -n --argjson a "$shared" --argjson b "$(printf '%s' "$values" | jq -c --arg r "$role" '.roles[$r]')" '$a * $b')"
    # SLICE_PATHS is a list, not a placeholder value: it is read here and
    # dropped before the text check, which every rendered value must pass.
    merged="$(printf '%s' "$merged" | jq -c 'del(.SLICE_PATHS, .SLICE_DIGEST)')" || return 2
    validate_values "$merged" "the values for role '${role}'" || return 2
    known="$(placeholders_in "$role_tpl")" || return 3
    if [[ $'\n'"${known}"$'\n' == *$'\nSPECIALIST_CONTEXT\n'* ]]; then
      merged="$(printf '%s' "$merged" | jq -c '{SPECIALIST_CONTEXT:""} * .')" || return 2
    fi
    # `.shared` too: a key merged from there is overwritten below, so leaving it
    # unchecked would accept a supplied boundary by silently discarding it.
    if printf '%s' "$values" | jq -e --arg r "$role" '(.shared // {} | has("SLICE_SCOPE")) or (.roles[$r] | has("SLICE_SCOPE"))' >/dev/null; then
      warn "SLICE_SCOPE for role '${role}' is composed from the seat and its paths, not supplied — remove the key from .shared and .roles"
      return 2
    fi
    if printf '%s' "$values" | jq -e '.shared // {} | has("SLICE_PATHS")' >/dev/null; then
      warn "SLICE_PATHS belongs to one seat, never to .shared — every slice owns different paths"
      return 2
    fi
    if printf '%s' "$values" | jq -e '.shared // {} | has("SLICE_DIGEST")' >/dev/null; then
      warn "SLICE_DIGEST belongs to one seat, never to .shared — apply re-derives each seat's digest from the plan"
      return 2
    fi
    local slice_paths="[]"
    slice_digest=""
    if [[ "$role" == *"#"* ]]; then
      # The globs are rendered verbatim into the worker's brief, so a backtick
      # or a control character could close the code span and append
      # instructions of its own. A path glob needs neither.
      check_rc=0
      if printf '%s' "$values" | jq -e --arg r "$role" '.roles[$r].SLICE_PATHS | type == "array" and length > 0 and all(type == "string" and (. | gsub("\\s";"") | length) > 0)' >/dev/null; then
        renderable_json "$(printf '%s' "$values" | jq -c --arg r "$role" '.roles[$r].SLICE_PATHS')" --code-span || check_rc=$?
        if (( check_rc == 3 )); then return 3; fi
      else
        check_rc=1
      fi
      if (( check_rc != 0 )); then
        warn "seat '${role}' needs SLICE_PATHS: the non-empty list of path globs its slice owns, copied from the partition validate-partition accepted, each a string without backticks or control characters. A slice name alone leaves the worker no boundary to respect"
        return 2
      fi
      slice_paths="$(printf '%s' "$values" | jq -c --arg r "$role" '.roles[$r].SLICE_PATHS')" || return 2
      # Transported, never derived here: the digest is computed in one place
      # (`partition.seat_digest`), and `apply` re-derives it from the plan and
      # compares. A second implementation in shell would drift from the first.
      if ! printf '%s' "$values" | jq -e --arg r "$role" '.roles[$r].SLICE_DIGEST | type == "string" and test("^[0-9a-f]{12}$")' >/dev/null; then
        warn "seat '${role}' needs SLICE_DIGEST: its twelve-character entry from the plan's seat_digests. It travels into the brief, and apply re-derives it from the plan, so a boundary edited after validation is refused at dispatch"
        return 2
      fi
      slice_digest="$(printf '%s' "$values" | jq -r --arg r "$role" '.roles[$r].SLICE_DIGEST')" || return 2
    elif printf '%s' "$values" | jq -e --arg r "$role" '.roles[$r] | has("SLICE_PATHS") or has("SLICE_DIGEST")' >/dev/null; then # unseated
      warn "SLICE_PATHS for role '${role}' names a slice it does not own — an unseated role reviews the whole change"
      return 2
    fi
    if [[ $'\n'"${known}"$'\n' == *$'\nSLICE_SCOPE\n'* ]]; then
      # Assigned and checked on its own line: nested in the outer jq's --arg,
      # a failing slice_scope is discarded and the brief composes with an empty
      # boundary -- the one outcome the placeholder exists to prevent.
      rendered_scope="$(slice_scope "$role" "$slice_paths" "$slice_digest")" || return 3
      merged="$(printf '%s' "$merged" | jq -c --arg s "$rendered_scope" '. + {SLICE_SCOPE:$s}')" || return 2
    elif [[ "$role" == *"#"* ]]; then
      # A custom template without the placeholder would compose a seated brief
      # carrying no boundary, and its worker would return a full-surface
      # verdict over a partitioned change.
      warn "the template for seat '${role}' carries no {{SLICE_SCOPE}} placeholder — a seated brief must render its slice boundary; add it to $(basename "$role_tpl")"
      return 2
    fi
    case "$role" in
      advisor|investigator|architect)
        if ! printf '%s' "$merged" | jq -e --arg role "$role" '.RESPONSIBILITY == $role' >/dev/null; then
          warn "RESPONSIBILITY must match consultation role '${role}' — preserve the assigned responsibility in its brief"
          return 2
        fi
        ;;
    esac
    # Validate in JSON before command substitution can strip trailing newlines
    # or discard a NUL byte from the path. A U+2028 or C1 control splits the
    # worker's `REPORT: <path>` marker across rows as surely as a newline.
    check_rc=0
    renderable_json "$(printf '%s' "$merged" | jq -c '.REPORT')" --code-span || check_rc=$?
    if (( check_rc == 3 )); then return 3; fi
    if (( check_rc != 0 )); then
      warn "REPORT for role '${role}' must be a string without control, format or line-separator characters or backticks (the brief renders it in a code span) — choose a fresh absolute file path on one line"
      return 2
    fi
    report="$(printf '%s' "$merged" | jq -r '.REPORT // ""')"
    if [[ "$report" != /* || "$report" == */ ]]; then
      warn "REPORT for role '${role}' must be an absolute file path on one line — choose a fresh path for this attempt"
      return 2
    fi
    if [[ -e "$report" || -L "$report" ]]; then
      warn "REPORT for role '${role}' already exists at ${report} — preserve it and choose a fresh path for this attempt"
      return 2
    fi
    local prior_report
    for prior_report in ${report_paths[@]+"${report_paths[@]}"}; do
      if [[ "$report" == "$prior_report" ]]; then
        warn "REPORT for role '${role}' duplicates another role's destination — give each assignment a distinct report path"
        return 2
      fi
    done
    report_paths+=("$report")
    if (( ${#report} > FOREMAN_REPORT_PATH_MAX_COLS )); then
      warn "REPORT for role '${role}' is ${#report} characters; the limit is ${FOREMAN_REPORT_PATH_MAX_COLS}, a coarse bound on the worker's \`REPORT: <path>\` line (\`foreman apply\` checks the live pane width before dispatch) — use a shorter reports directory (e.g. one under \$HOME/.local/state) and re-run"
      return 2
    fi
    rendered="$(substitute "$role_tpl" "$merged")"
    scan_rc=0
    leftovers="$(leftover_placeholders "$rendered")" || scan_rc=$?
    if (( scan_rc != 0 )); then return 3; fi
    if [[ -n "${leftovers// /}" ]]; then
      warn "brief-${role}.md still holds unfilled placeholders: ${leftovers}— add them to .roles.${role} or .shared"
      return 2
    fi
    # A supplied key no template uses is a value the foreman believes it sent.
    # The known set is collected ONCE into a string and membership-tested with
    # a glob: piping into `grep -q` under `set -o pipefail` reports failure
    # whenever grep exits early on a match and SIGPIPEs the producer, which
    # reads as "not found" for every key that IS found.
    supplied="$(printf '%s' "$merged" | jq -r 'keys[]')"
    common_known="$(placeholders_in "$common_tpl")" || return 3
    known+=$'\n'"$common_known"
    unused=""
    while IFS= read -r key; do
      [[ -n "$key" ]] || continue
      if [[ $'\n'"${known}"$'\n' != *$'\n'"${key}"$'\n'* ]]; then
        unused+="${key} "
      fi
    done <<< "$supplied"
    if [[ -n "$unused" ]]; then
      warn "values for role '${role}' carry keys no template uses: ${unused}— remove them or fix the name"
      return 2
    fi
    check_rc=0
    validate_review_package "$merged" "$role" || check_rc=$?
    if (( check_rc != 0 )); then return "$check_rc"; fi
    out_paths+=("${outdir}/brief-${role}.md")
    out_bodies+=("$rendered")
  done <<< "$roles"

  local output_path
  for report in "${report_paths[@]}"; do
    for output_path in "${out_paths[@]}"; do
      if [[ "$report" == "$output_path" ]]; then
        warn "REPORT overlaps a generated brief at ${report} — choose a separate report destination"
        return 2
      fi
    done
  done

  if ! mkdir -p "$outdir"; then
    warn "cannot create the output dir ${outdir} — check permissions"
    return 1
  fi
  local i
  for i in "${!out_paths[@]}"; do
    if ! printf '%s\n' "${out_bodies[$i]}" > "${out_paths[$i]}"; then
      warn "cannot write ${out_paths[$i]} — check permissions on ${outdir}"
      return 1
    fi
  done

  local briefs_json="{}"
  while IFS= read -r role; do
    briefs_json="$(printf '%s' "$briefs_json" | jq -c --arg r "$role" --arg p "${outdir}/brief-${role}.md" '. + {($r): $p}')"
  done <<< "$roles"
  jq -n --arg common "${outdir}/COMMON.md" --argjson briefs "$briefs_json" \
    '{common: $common, briefs: $briefs}'
  return 0
}

# Entry-point guard (rules/file-hygiene.md Standalone Scripts).
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
  main "$@"
fi

skills

herdr-foreman

bounded-run.sh

compose-briefs.sh

config.example.json

foreman-tier-check.py

foreman.sh

label-workspaces.sh

provision-worktree.sh

prune-remote-branches.sh

prune-report-caches.py

prune-worktrees.sh

resolve-gates.sh

resolve-policy-paths.sh

review-package.sh

roster.sh

round-preflight.sh

SKILL.md

start-judge-worker.sh

state-schema.md

sweep-worktrees.sh

verify-authority.sh

wait-report.sh

README.md

tile.json