# Design-Control-Loop Dampener: When to Use Regression Gates and How to Implement PR Checks

> Learn when to use a design-control-loop dampener to prevent external disturbances from worsening metrics. Implement regression gates as PR checks against sensor baselines.

- Repository: [HumanLayer/skills](https://github.com/humanlayer/skills)
- Tags: how-to-guide
- Published: 2026-09-13

---

**Design-control-loop recommends a dampener (regression gate) whenever external disturbances—such as concurrent team merges, dependency updates, or high-risk metric changes—could worsen the measured problem between scheduled loop runs, implementing it as a PR check that compares sensor output against a stored baseline and fails on new violations.**

The **design-control-loop** skill from the `humanlayer/skills` repository provides a structured approach to autonomous code improvement through sensor-controller-actuator patterns. Understanding when and how to deploy the optional **dampener** mechanism prevents regression drift while the scheduled loop iterates on technical debt.

## When Design-Control-Loop Recommends a Dampener

The skill surfaces the dampener recommendation during **Phase B** (the interview/design phase) of implementation. According to [`plugins/design-control-loop/skills/design-control-loop/SKILL.md`](https://github.com/humanlayer/skills/blob/main/plugins/design-control-loop/skills/design-control-loop/SKILL.md), you should offer a dampener whenever disturbances threaten to destabilize the control loop’s target metric between runs.

### Concurrent Team Work and External Disturbances

When teammates merge PRs while the loop is running, the sensor may report regressions unrelated to the loop’s own changes. The dampener acts as a **regression gate** that isolates the loop’s impact from external code changes, ensuring that only deliberate modifications affect the measured problem.

### Dependency Updates and Generated Code

Automated dependency bumps or generated code introduce new violations unpredictably. Without a dampener, these external changes accumulate as noise in the sensor baseline. The regression gate catches these deviations immediately upon PR creation, preventing technical debt from compounding between scheduled runs.

### High-Risk Metrics and Zero-Tolerance Policies

Security warnings or lint rules that must never regress require strict enforcement. Even tiny increases in these metrics are unacceptable. The dampener blocks PRs that introduce new violations, maintaining hard boundaries while the loop gradually reduces existing issues.

## How the Dampener Is Expressed as a PR Check

The implementation follows a three-stage pattern documented in [`plugins/design-control-loop/skills/design-control-loop/references/example-control-loop.md`](https://github.com/humanlayer/skills/blob/main/plugins/design-control-loop/skills/design-control-loop/references/example-control-loop.md). This structure turns the abstract concept of a regression gate into a concrete GitHub Actions workflow.

### Baseline Capture Strategy

The sensor runs against the main branch (or last known-good commit) to generate [`sensor-baseline.json`](https://github.com/humanlayer/skills/blob/main/sensor-baseline.json). This artifact represents the authoritative state against which all future PRs are compared. The baseline must persist across workflow runs, typically stored as a build artifact or committed to the repository.

```yaml

# Extract from the baseline capture step

- name: Generate baseline
  run: |
    git fetch origin main:main
    git checkout main
    bunx react-doctor --project '@codelayer/riptide-ui' --json > sensor-baseline.json

```

### PR-Triggered Workflow Implementation

Every pull request triggers a secondary workflow that re-executes the identical sensor command, diffs the new output against the stored baseline, and fails the check upon detecting new issues. The workflow defined in the example control loop demonstrates this pattern using `jq` to compute differences and `exit 1` to block merges.

```yaml

# From plugins/design-control-loop/.../references/example-control-loop.md

name: react-doctor
on:
  pull_request:
    branches: [ main ]
jobs:
  dampener:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run sensor
        run: bunx react-doctor --project '@codelayer/riptide-ui' --diff true --json > pr-sensor.json
      - name: Compare to baseline
        run: |
          jq -s '.[0] - .[1]' sensor-baseline.json pr-sensor.json > diff.json
          if jq '.issues | length > 0' diff.json; then
            echo "::error ::Regression detected – new issues introduced"
            exit 1
          fi

```

### Advisory to Blocking Promotion

The dampener supports a maturity progression from advisory to enforcing mode. Initially, the check surfaces regressions as PR comments without blocking merges. Once confidence in the sensor stability is established, promote the check to blocking status by removing the conditional logic that suppresses the `exit 1` failure state.

```yaml

# Advisory mode (non-blocking)

- name: Report regression (advisory)
  if: env.DAMPENER_MODE == 'advisory'
  run: |
    echo "🔔 New issues detected – review needed"
    # Does not exit 1; allows merge

# Blocking mode (enforcing)

- name: Block on regression (enforcing)
  if: env.DAMPENER_MODE == 'blocking'
  run: |
    if jq '.issues | length > 0' diff.json; then
      exit 1
    fi

```

## Complete Implementation Examples

### Minimal Generic Dampener Workflow

For repositories not using the React Doctor example, implement a generic dampener using shell scripts and `jq` comparisons:

```yaml

# .github/workflows/dampener.yml

name: Dampener – regression gate
on:
  pull_request:
    branches: [ main ]
jobs:
  sensor-baseline:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Run sensor on PR
        run: ./scripts/run-sensor.sh > pr-sensor.json
      - name: Load baseline from main
        run: |
          git fetch origin main:main
          git checkout main
          ./scripts/run-sensor.sh > baseline.json
          git checkout -
      - name: Compare and gate
        run: |
          diff=$(jq -s '.[0] - .[1]' baseline.json pr-sensor.json)
          if jq '.issues | length > 0' <<<"$diff"; then
            echo "::error ::Regression detected – new issues introduced"
            exit 1
          fi

```

### Integrating with the Main Control Loop

Wire the dampener into the recurring loop workflow using the template provided in [`plugins/design-control-loop/skills/design-control-loop/references/workflow-template.yml`](https://github.com/humanlayer/skills/blob/main/plugins/design-control-loop/skills/design-control-loop/references/workflow-template.yml). The dampener runs optionally based on environment configuration:

```yaml

# .github/workflows/agent-loop.yml

steps:
  - name: Sensor
    run: ./scripts/run-sensor.sh > sensor.json
  - name: Controller
    run: ./scripts/run-controller.sh sensor.json > target.json
  - name: Actuator
    run: ./scripts/run-actuator.sh target.json
  - name: Dampener (optional)
    if: ${{ env.ENABLE_DAMPENER == 'true' }}
    uses: ./.github/workflows/dampener.yml

```

## Summary

- **Offer a dampener** whenever external disturbances (concurrent merges, dependencies, or high-risk metrics) could destabilize the sensor baseline between scheduled loop runs.
- **Implement as a PR check** by capturing a baseline from main, diffing PR sensor output against that baseline using `jq`, and failing the job on new violations.
- **Progress from advisory to blocking** by starting with non-failing comments, then promoting to `exit 1` enforcement once sensor stability is validated.
- **Reference implementation** lives in [`plugins/design-control-loop/skills/design-control-loop/references/example-control-loop.md`](https://github.com/humanlayer/skills/blob/main/plugins/design-control-loop/skills/design-control-loop/references/example-control-loop.md), with workflow templates available in [`workflow-template.yml`](https://github.com/humanlayer/skills/blob/main/workflow-template.yml) and iteration helpers in [`agent-iteration.ts`](https://github.com/humanlayer/skills/blob/main/agent-iteration.ts).

## Frequently Asked Questions

### What triggers the recommendation for a dampener in design-control-loop?

The skill recommends a dampener during **Phase B** of the design interview when the loop’s **disturbances**—such as concurrent team work, dependency updates, or generated code—could cause the measured problem to regress between scheduled runs. This appears in [`SKILL.md`](https://github.com/humanlayer/skills/blob/main/SKILL.md) as an optional offer to "keep the measured problem from getting worse while the scheduled loop chips away at it."

### How does the dampener PR check technically prevent regressions?

The check runs as a GitHub Actions workflow triggered by `pull_request` events. It executes the same sensor command used by the main loop, compares the JSON output against a stored [`sensor-baseline.json`](https://github.com/humanlayer/skills/blob/main/sensor-baseline.json) using `jq -s '.[0] - .[1]'`, and calls `exit 1` if the diff contains new issues. This failure state blocks PR merging until the regression is addressed.

### Can the dampener start as non-blocking while we test the sensor calibration?

Yes. Configure the dampener workflow to run in **advisory mode** by omitting the `exit 1` failure condition and emitting only PR comments. Once confidence in the sensor’s stability is established, switch to **blocking mode** by enforcing the exit failure on detected regressions.

### Where are the canonical reference files for implementing a dampener?

The primary documentation resides in [`plugins/design-control-loop/skills/design-control-loop/SKILL.md`](https://github.com/humanlayer/skills/blob/main/plugins/design-control-loop/skills/design-control-loop/SKILL.md). Concrete implementation examples appear in [`plugins/design-control-loop/skills/design-control-loop/references/example-control-loop.md`](https://github.com/humanlayer/skills/blob/main/plugins/design-control-loop/skills/design-control-loop/references/example-control-loop.md), while the workflow structure template is located at [`plugins/design-control-loop/skills/design-control-loop/references/workflow-template.yml`](https://github.com/humanlayer/skills/blob/main/plugins/design-control-loop/skills/design-control-loop/references/workflow-template.yml). The TypeScript helper for PR comment iteration (often paired with dampeners) is found in [`plugins/design-control-loop/skills/design-control-loop/references/agent-iteration.ts`](https://github.com/humanlayer/skills/blob/main/plugins/design-control-loop/skills/design-control-loop/references/agent-iteration.ts).