Skip to content
Back to skills

Control Loop

ASecurity

Multi-session control discipline for delegating work to worker sessions — investigate, decide, dispatch, verify, and merge. Use when a session is coordinating separate worker sessions or worktrees and needs to know when to delegate versus decide, and how to verify before merging.

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 19, 2026
ai-agentsrustbashgit

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned October 19, 2026

npx -y skills add This-HW/hiway-kit --skill control-loop --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Control Loop?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Control Loop
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/this-hw-control-loop-hiway-kit/badge)](https://www.skillsdirectory.com/skills/this-hw-control-loop-hiway-kit)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: control-loop
description: Multi-session control discipline for delegating work to worker sessions — investigate, decide, dispatch, verify, and merge. Use when a session is coordinating separate worker sessions or worktrees and needs to know when to delegate versus decide, and how to verify before merging.
---

# Control Loop 스킬

축은 *기획 대 컨트롤*이 아니라 **결정 대 조사**다. 판별식: 브리프를 전제·범위/계약·
금지사항·보고형식 4블록으로 쓸 수 있으면 그 작업은 워커에게 위임 가능한 **조사**다.
4블록을 **쓰는 행위 자체**는 위임 불가능한 **결정**이다. 이 스킬은 기획용·컨트롤용으로
나뉘지 않는다 — 같은 세션 안에서 조사와 결정을 섞지 않고 3페이즈로 가른다.

## 언제 쓰는가

컨트롤 세션이 자신이 아닌 별도의 워커(다른 세션, 격리된 워크트리, 그 밖에 호스트가
제공하는 어떤 위임 수단이든)에게 작업을 맡기고, 그 결과를 검증한 뒤 통합 브랜치로
되돌릴 때. 구체적 위임 수단은 이 스킬의 관심사가 아니다 — 아래 "운송" 참고.

---

## P1 — 조사·설계 (위임 가능)

- 목적은 결정에 필요한 **사실**을 모으는 것이다. 결정은 여기서 하지 않는다.
- **"없다 / 신설한다" 같은 존재 판정은 실측 뒤에만 쓴다.** `grep`, `git log --all`,
  대상 파일 직접 열람으로 확인하지 않은 존재 판정은 그 자체가 결함이다 — 이 판정을
  틀린 채로 다음 페이즈에 넘기면 컨트롤이 잘못된 전제로 브리프를 쓰게 된다.
- P1을 워커에게 위임할 때도 4블록 브리프(P2 참조)로 위임한다 — 조사 자체는 위임 가능,
  결정만 위임 불가라는 뜻이다.
- P1 산출물은 사실 목록이지 결정이 아니다. "이렇게 해야 한다"가 섞여 있다면 그것은
  이미 P2로 넘어간 것이므로, 컨트롤이 그 부분만 따로 검증하고 결정으로 승격한다.

### 조사를 위임하지 않는 쪽으로 끌리는 힘이 있다 — 알고 저항한다

P2 의 브리프는 **실측된 전제**로 시작해야 한다(아래 "되돌림 규칙"). 그런데 그 전제를
쓰려면 **누군가 먼저 조사해야** 하고, 가장 손쉬운 답은 "컨트롤이 직접 본다"다. 그래서
**비싼 조사는 컨트롤이 하고 값싼 타이핑만 위임**하는 쪽으로 기운다.

**브리프가 정밀할수록 이 편향이 커진다** — 자기강화 고리다. 컨트롤은 병목이므로,
조사를 컨트롤이 떠안으면 전체가 컨트롤 속도로 수렴한다.

> 실측(외부 컨트롤 세션, 2026-09-08): 하루 조사 3건(판정기 추적·레지스트리 조사·기본값
> 추적)을 **전부 컨트롤이 직접 했다.** 위임 가능한 작업이었고, 규칙도 이미 있었다.

**틀린 교정: 브리프에 가설을 쓴다.** 검증 안 된 전제를 구현 브리프에 섞으면 워커가
**틀린 설계 위에서 구현을 시작한다** — 반려보다 비싸다.

**옳은 형태: 위임이 둘이다.**

| | 산출물 | 금지 |
| --- | --- | --- |
| **① 조사 위임** | 근거(파일:줄·명령 출력) 붙은 **사실 보고** | **구현 금지** |
| ② 컨트롤이 설계 | 결정 (위임 불가) | — |
| **③ 구현 위임** | 확정된 설계의 구현 | 설계 변경 금지 |

> **조사와 구현을 한 브리프에 담지 마라. 조사 결과가 설계를 바꿀 수 있으면 그것은
> 두 개의 위임이다.** 세션은 같아도 된다 — **브리프가 둘이어야 한다.**

### 모델·티어는 위험과 검증 비용으로 고른다

짧고 검증 가능한 조사는 지연을, 복잡한 구현·분석은 정확도를 우선한다. 조사도 보안·핵심
로직이면 난도가 높다. 역할만으로 능력을 단정하지 말고 위험·난도·실측에 따라 조정한다.
모델 이름과 기본값은 사용자/호스트 설정의 몫이다. 요청값과 실제 실행 설정을 구분하고, 실제
실행 설정(모델 ID·effort)은 요청값의 되울림이 아니라 워커 세션 기록에서 확인한다 — 못 찾으면 미확인으로 적는다.

## P2 — 결정·브리프 (컨트롤 전용, 위임 불가)

P1 산출물을 놓고 채택·금지를 결정하고, 그 결정을 4블록 브리프로 쓴다.

- 4블록 스키마·보고 첫 줄 고정 형식·형식 검사 정규식은 `rules/delegation-contract.md`가
  SSOT다. 이 스킬은 그 계약을 **참조만** 한다 — 여기서 다시 정의하면 두 곳이 어긋날 때
  아무것도 그것을 강제하지 않는 결함 클래스(동기화 안 되는 이중 선언)가 재현된다.
- **되돌림 규칙**: 4블록(전제 / 범위·계약 / 금지사항 / 보고형식) 중 하나라도 채울 수
  없으면 — 전제가 실측되지 않았거나 완료 기준을 문장으로 확정할 수 없으면 — **P1으로
  되돌린다.** 4블록을 못 쓰는 채로 디스패치하지 않는다.
- 브리프의 전제 서술은 P1의 실측을 **그대로 인용**한다. 컨트롤이 전제를 추측해서 쓰면
  워커가 반려하게 된다(관측된 실패 지점 — 전제를 추측한 브리프가 하루 여러 건 반려됐다).

### 기준 커밋을 못박는다

디스패치 전 컨트롤은 기준 ref의 **실제 커밋 해시**를 확인하고(`git rev-parse <ref>`)
그 해시를 브리프에 적는다. **브랜치 이름(`main` 등)은 기준으로 쓰지 않는다** — 다른
체크아웃이 그 브랜치를 물고 있으면 로컬 이름이 원격보다 여러 커밋 뒤처져 있을 수 있고,
그 상태로 워커 워크트리를 생성하면 낡은 기준점에서 작업이 시작된다(실측 사고: 워크트리
5개가 로컬 `main` 기준으로 생성됐는데 그 `main` 자체가 원격보다 11커밋 뒤처져 있었다).

워커는 착수 시 **자기 워크트리 HEAD**(`git rev-parse HEAD`)가 브리프의 해시와 같은지
확인한다. 다르면 구현을 시작하지 않고 **즉시 에스컬레이션**한다.

### 자식 생성 절차 — 인자 4개

호스트가 제공하는 위임 수단으로 워커를 만들 때, 다음 4개를 함께 전달한다:

1. **부모 세션 이름/식별자** — 워커가 완료·에스컬레이션을 보고할 대상
2. **역할 + 워크트리 경로** — 무엇을 맡았고 어디서 작업하는지
3. **4블록 브리프** — 이 페이즈의 산출물 그대로
4. **금지사항 기본값** — 최소 다음을 포함한다: push 금지, 통합 브랜치(`main` 등) 직접
   쓰기 금지, 파괴적 git 명령(bare `stash`/`reset --hard`/`clean -fd`) 금지, 병합 전
   공유 상태 파일(진행 원장 등) 쓰기 금지

4개 중 하나라도 못 채운 채로 디스패치하려 한다면 P2가 아직 끝나지 않은 것이다 — P2로
남아 있는다. 워커 자신이 로드해 따르는 규율(전제 검증·보고 형식 등)은 별도 스킬이
정의한다 — 이 스킬은 그 규율을 여기서 다시 쓰지 않고 참조만 한다.

---

## P3 — 디스패치·수신·통합 (컨트롤 전용, 위임 불가)

### 디스패치

호스트가 제공하는 수단으로 위임한다. 구체적 명령·플래그는 이 스킬 본문의 관심사가
아니다 — 아래 "운송" 참고. 워커는 **자기 워크트리/브랜치에만** 커밋한다. **통합
브랜치는 컨트롤만 쓴다.**

### 수신

워커 보고 원문·diff·검증 출력을 확인한다. 보고는 검증의 입력이지 결론이 아니다. 테스트
통과 주장에 종료코드 근거가 없으면(파이프로 종료코드가 삼켜진 로그만 있는 경우 등)
재요청한다 — 조건의 정의는 계약(`rules/delegation-contract.md`)에 있다.

### 게이트 — 병합 전에 컨트롤이 직접 실행한다

병합하기 전에 컨트롤이 완료 게이트(정의된 검증 스크립트·관련 테스트)를 **직접
실행**한다. 워커의 "green" 보고를 게이트 실행의 대체물로 쓰지 않는다.

- fail이면 워커에게 결함을 반려한다 — 브리프를 P2로 되돌리지 않는다(브리프는 유효한
  채로 구현만 틀렸을 수 있다).
- pass이면 컨트롤만 통합 브랜치로 병합한다.

#### 그리고 **통합 후 통합 브랜치에서 한 번 더** 전량을 돌린다

병합 **전** 게이트만으로는 부족하다. 격리된 곳에서 도는 검증은 두 이유로 빈틈이 있다:

1. **격리 환경에는 런타임 산출물이 없다.** 그 부재가 "안전한 기본값"으로 흡수되면
   그 단언은 **공허하게 참**이 된다 — 한 번도 실제로 평가되지 않은 채 초록이다.
2. **워커는 다른 워커의 변경을 보지 못한다.** A가 만든 코드를 B가 강화한 검사가
   잡는 상황은 **양쪽 워크트리 어디에서도** 드러나지 않는다.

실측 `[confirmed: n=2, 서로 다른 프로젝트, 2026-09-10]`. 한쪽은 병합 게이트 10회가
전부 초록이었는데 통합 브랜치에서 전량을 돌리자 **안전 게이트 3건이 빨갛게** 나왔다
(위 1번 — 그 단언들은 한 번도 평가된 적이 없었다). 다른 쪽은 워커 3인이 각자
워크트리에서 초록이었는데 병합 후 **게이트 2건이 red** 였다(위 2번 — 어느 워커도
혼자서는 볼 수 없는 결함이었다).

**기전은 다르지만 처방은 같다: 통합 브랜치에서 최소 1회 전량을 돌린다.**
그 실행이 red 면 병합을 되돌리는 것이 아니라 **그 자리에서 고친다** — 통합 지점이
그 결함이 처음으로 보이는 유일한 자리다.

#### 검증 호출과 병합 호출을 물리적으로 분리한다

**게이트 실행과 병합·푸시를 같은 도구 호출에 잇지 마라.** 출력을 읽는 시점엔 이미
병합된 뒤이므로, 그건 게이트가 아니라 로그다. 호출을 나눠 **사이에 출력을 읽는 턴**을
반드시 넣는다.

`&&` 로 묶는 것도 일반해가 아니다. 세 이유다.

1. **판정이 stdout 에 있는 검증**은 종료코드가 "조회 성공"만 뜻한다 — `gh pr view`·
   `gh pr checks` 는 CI 가 빨개도 exit 0 이다. `&&` 로 이어도 게이트가 되지 않는다.
2. 검증이 여러 축이면 `&&` 한 줄이 그 축들을 **조건식으로 압축**한다. 각 축이 어떤
   종류의 거짓 초록을 잡으려고 있었는지가 사라지고, 몇 개를 빠뜨렸는지 아무도 안 본다.
3. **출력을 보려고 파이프에 물리는 순간 종료코드가 바뀐다.** 파이프라인의 rc 는
   **마지막 명령의 rc** 다 — `gate | tail -25` 의 rc 는 `tail` 것이고, `tail` 은 거의
   항상 0 이다. 게이트를 읽기 좋게 만들려던 습관이 게이트를 로그로 바꾼다.

   ```bash
   sh -c 'exit 7'            ; echo $?   # 7
   sh -c 'exit 7' | tail -1  ; echo $?   # 0  ← 삼켜졌다
   bash -c 'set -o pipefail; sh -c "exit 7" | tail -1'; echo $?   # 7
   ```

   실측 `[confirmed: 2026-09-10, 두 세션]`: 한 세션이 병합 게이트를 `--dry-run 2>&1 |
   tail -25` 로 돌려 **rc 0 을 통과 신호로 읽었다.**

   **규칙**: 게이트의 rc 를 쓸 거면 파이프에 물리지 마라. 출력이 보고 싶으면 **파일로
   받고 rc 를 따로 잡아라**(`cmd > out 2>&1; rc=$?`). `set -o pipefail` 도 답이지만,
   그건 그 셸에서만 참이라 **호출자가 잊으면 조용히 되돌아간다.**

`pytest && git push` 처럼 판정이 **종료코드에** 있고 축이 하나면 `&&` 는 진짜 게이트다.
그 경우까지 금지하지는 않는다.

> 실측 n=2 (서로 독립, 같은 날 다른 두 세션): PR 4축 검증이 `FAILURE` 를 출력했는데
> 같은 블록의 `gh pr merge` 가 조건 없이 실행돼 CI 실패 상태로 main 머지 · `pytest`
> 뒤에 `commit`·`push` 를 `;` 로 체인해 린트 오류가 main 에 올라감. n=2 면 개인
> 부주의가 아니라 도구가 유도하는 형태다.

기계적 보강은 opt-in 훅 `hooks/examples/verify-mutate-split.py` 에 있다(기본 OFF).
훅은 **한 번의 도구 호출만** 본다 — "직전 턴에 CI 결과를 읽었는가"는 판정하지 않는다.

### 응답 직전 — 자식 목록을 실제로 조회한다

**컨트롤이 사용자에게 응답하기 직전, 자기 자식 목록을 호스트에 조회해 브리프로 만든
자식과 대조한다.** 안 붙은 자식이 있으면 그 사실을 응답에 적는다.

규칙만 있고 **점검 시점이 없으면 반복된다.** 계보가 끊긴 것은 조회하기 전까지
아무 증상도 내지 않는다 — 세션은 멀쩡히 돌고 보고도 온다. 끊긴 것은 *"이 자식이 누구
밑에 있는가"* 뿐이고, 그건 물어봐야만 보인다.

> 실측(외부 컨트롤 세션): 워크트리 생성과 세션 기동을 **다른 도구로 나눠** 해서 계보가
> 안 붙었다. **3회차 재발**이었고 규칙은 이미 메모리에 있었다 — 어긴 것은 규칙이 아니라
> **자기점검**이었다(응답 직전 조회를 한 번도 하지 않았다).

**계보는 자식을 만드는 그 명령에 붙는다.** 워크트리 생성과 세션 기동을 다른 도구로
나누면 조용히 끊긴다.

#### 이 킷이 집행할 수 없는 것 — 명시한다

**"생성 도구를 섞었다"를 킷은 탐지할 수 없다.** 킷의 자식 마커
(`rules/child-marker.md`)는 **자식 세션 스킬이 로드될 때만** 생기는데, 도구를 섞는다는
것이 곧 그 경로를 우회한다는 뜻이다. 마커가 없으면 훅은 **fail-open** 이라 아무 경고도
내지 않는다 — 자기 참조적으로 판정 불가다.

킷이 집행하는 것은 **마커가 있을 때 그 내용이 옳은가**까지다: `parent`·`role`·
`base_commit` 이 비어 있으면 "자식 아님"으로 판정하고, `base_commit` 이 현재 HEAD 의
조상이 아니면 경고한다(`hooks/examples/child-git-guard.py`, opt-in).

**계보 자체는 호스트·오케스트레이터의 상태이지 킷의 상태가 아니다.**
위 "응답 직전 조회"가 이 경계에서 할 수 있는 전부다. 없는 보호를 있다고 믿지 마라.

### 통합·정리

- 통합 브랜치는 컨트롤만 쓴다. 통지는 워커의 SHA가 아닌 **통합 브랜치의 최종 SHA**로 한다.
- 완료/실패 보고를 접수·검증한 뒤 소유 세션을 즉시 재사용하거나, 사용자 요청으로 보존하거나,
  해제한다. 보고 수신·처리·승인은 구분하며 호스트의 수명주기 계약을 따른다.
- **세션 해제와 작업 트리 삭제는 별개다.** 삭제 전 미병합 커밋·수정 파일·미추적/ignored
  보고서의 통합 또는 복구 가능한 보존을 확인한다. 커밋 백업만으로 미커밋 파일은 보존되지 않는다.
  실패/미채택 산출물도 보존 근거가 있으면 정리 가능하다. 다른 작업자의 자원은 건드리지 않는다.
- 재사용 시 이전 작업 마커는 해당 호스트 계약에 따라 정리한다. 살아 있는 작업의 권한을 지우지 않는다.
- **응답 직전 실제 자원 목록을 조회**해 각 자원의 재사용·사용자 요청 보존·해제 결과를 대조한다.
  미처리/미확인은 차단 사유와 다음 담당자를 보고한다. 해제 요청의 성공 코드만으로 종료를 단정하지 않는다.
- 빈 응답·타임아웃·연결 단절은 종료 증거가 아니다. 상태 불명은 보존하고 호스트의 복구 절차로
  확인한다. 종료/정산 권한 없이 정지·재시도·삭제하지 않는다. hooks trust·보안 게이트를 우회하지 않는다.

이 절은 실행자의 확인 의무다. 자동 삭제나 호스트 상태의 기계적 강제를 구현하지 않는다.

---

## P0 에스컬레이션

전제가 실측과 어긋나거나, 이 스킬의 범위 밖 결정이 필요하거나, 파괴적 작업이
필요하면 멈춘다. 사용자에게 선택지를 제시하고 답을 받는다 — 호스트가 제공하는
수단으로. 특정 툴 이름을 전제하지 않는다(헤드리스·비대화형 호스트에는 그 툴이 없을
수 있다).

## 운송

이 스킬의 규범 본문은 위임에 실제로 쓰는 수단을 모른다 — **"호스트가 제공하는
수단으로 위임한다"**로 자급한다. 운송별 실행 레시피(감지 명령 + 최소 레시피)는 레포
문서를 참조하라. 그 문서가 없거나 낡아도 이 스킬은 계속 동작한다 — 감지 가능한
수단이 없으면 단일 세션 순차 실행을 검토한다. 단, 사용자가 특정 운송/계보를 요구했거나
그 수단이 권한을 소유하면 묵시적으로 대체하지 말고 차단 사유를 보고한다.

## 관련

경로는 플러그인 루트 기준이다(소비자 프로젝트 cwd 가 아니다).

| 문서 | 위치 |
| --- | --- |
| 브리프 4블록·보고 형식 계약 | `rules/delegation-contract.md` |
| 워커 세션이 로드하는 규율 | `skills/child-session/SKILL.md` |
| 워크트리 격리·병합 규율(네이티브 서브에이전트) | `rules/parallel-worktree.md` |
| 루프 종료 가드 | `rules/loop-engineering.md` |

Files in this skill

  • SKILL.md16.9 KB
  • agents/openai.yaml372 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.