문제는 이것이었다. 하네스(harness, AI가 "다 했다"고 넘어가지 못하도록 증거를 강제하는 감시 장치 모음)에 새 요구사항 장치 두 개를 넣었는데, 그 지시가 일을 지휘하는 리드(총괄 AI)의 지시문에만 적혀 있고, 실제 일이 벌어지는 하류에는 전달되지 않았다. 배선(wiring, 규칙을 실제 실행 경로에 연결하는 일)이 리드에서 끊겨 있었던 셈이다. 그래서 하류 7지점의 빈 곳을 수리했다. 독립 검증이 잡아낸 실행 체인 끊김 2건도 닫았다. 하나는 심어 둔 시드(seed, 뒤 단계가 읽도록 미리 심어 두는 출발값)를 아무도 읽지 않는 허공 시드였다. 다른 하나는 새 규칙이 기존 검문과 부딪히는 게이트(gate, 코드를 서버에 올리기 전 자동으로 막아서는 검문소) 충돌이었다. 이 페이지는 그 수리 기록과 기대효과다.
결론부터 말한다. 규칙을 문서에 적는 것과 실행 경로에 연결하는 것은 다른 일이다. 새로 채택한 장치가 리드의 지시문에만 있으면 어떻게 될까. 계획을 세우는 담당, QA(품질 검사)를 도는 담당, 코드를 막아서는 검문 장치는 그 장치를 모른 채 예전처럼 움직인다. 아래 세 장이 이번 작업의 전체 맥락이다.
ouroboros(우로보로스, 자기 꼬리를 무는 뱀)는 오픈소스 AI 에이전트(스스로 도구를 쓰며 일하는 AI) 프레임워크다. 2026-08-06 검토 때 여기서 장치 두 개를 가져왔다. 하나는 요구사항을 목표·제약·용어 세 축으로 적어 두는 "spec 3축"이다(spec은 요구사항 명세). 다른 하나는 대화 도중 요구가 바뀌었는지 매번 확인하는 "의도 전환 체크"다.
두 장치가 /team 스킬(여러 AI 담당을 지휘해 프로젝트를 완성하는 작업 절차서)의 리드 문구에만 적혀 있었다. 계획을 세우는 담당, QA를 도는 담당, 코드를 올리기 전 막아서는 검문 장치처럼 실제 실행이 벌어지는 지점에는 아무것도 전달되지 않았다.
team(실행 단계 스킬) 쪽 5지점과 init-project(프로젝트 준비 단계 스킬) 쪽 2지점, 합쳐 갭(비어 있던 곳) 7건을 수리했다. 그리고 독립 검증자가 합의된 수용 기준 밖에서 찾아낸 실행 체인 끊김 2건(허공 시드와 게이트 충돌)까지 닫았다. 게이트가 오작동하지 않는다는 것은 grep(문서 전체에서 문구를 찾는 패턴 검색) 3건으로 실증했다.
읽는 법: 위에서 아래로 흐른다. init(프로젝트 준비 단계)이 심은 요구사항 시드가 team(실행 단계)으로 넘어가 계획 문서(plan)에 적혀 남고, QA를 거쳐, 마지막 push 게이트(코드를 서버에 올리기 전 자동 검문)까지 이어진다. 붉은 점선 두 곳이 문구만 보면 멀쩡한데 실행이 끊겨 있던 지점이다.
표에 자주 나오는 용어 셋을 미리 풀어둔다. plan은 이번 작업의 계획을 적어 두는 문서다. compaction(컴팩션)은 AI의 긴 대화가 압축되면서 오래된 내용이 지워지는 일이다. fan-out(팬아웃)은 QA 검사를 여러 하위 AI에게 동시에 뿌려 돌리는 일이다. 일곱 지점 각각에서 무엇이 비어 있었는지는 실제 절차서를 검색해(실측) 확인했다.
| 지점 | 없었던 것 (실측) | 수리 |
|---|---|---|
team 경로 A의 planner(계획 담당) |
AC(acceptance criteria, 완료로 인정할 수용 기준)와 계획만 돌려주는 반환 계약이었다. spec 3축이 반환 항목에 없어서, planner가 3축을 정리해도 넘어오는 길에 소실됐다 |
반환 계약에 "spec 3축(목표·제약·용어)"을 돌려주라고 명시했다 |
team Phase 1의 plan 정본(원본 문서) |
§4(절차서의 4번 항목) 산출물이 "메모리 컨텍스트(AI가 지금 기억하는 대화 내용)만"이었다. 그래서 기준선이 compaction에 소실되는 구조였다 | plan에 ## Spec (목표/제약/용어) 섹션을 반드시 넣게 했다. 디스크에 남는 영속 기준선이다 |
team Step 1 |
전환 체크가 Step 2.5(fan-out 이후)에만 있었다. 그래서 전환을 감지했을 때는 이미 QA 한 라운드를 낭비한 뒤였다 | fan-out 전에 §0 주 지점을 새로 만들었다. 기존 delta spawn(바뀐 부분만 다시 뽑으려고 띄우는 하위 AI)에 얹었으니 spawn(하위 AI를 새로 띄우는 일) 추가는 0이다 |
team Step 2.5 |
재도출(요구가 바뀐 뒤 수용 기준과 검사 항목을 다시 뽑는 일)의 실행 주체와 방법이 적혀 있지 않았다 | TC(test case, 요구사항에서 뽑아낸 검사 항목 한 건)를 다시 돌리는 방법을 정했다. Step 2.5는 백스톱(앞 단계가 놓친 전환을 뒤에서 받아내는 안전망)으로 다시 정의했다. delta로 재스폰해 영향을 받는 검사 항목만 다시 실행하도록 구체화했다 |
qa-scenario-gen delta(바뀐 부분만 다시 뽑는) 모드 |
"요구가 안 바뀌면 수용 기준도 그대로"라는 규칙만 있었다. 전환 케이스는 지원하지 않았다(append-only, 덧붙이기만 하고 지우지는 못하는 방식뿐) | 의도 전환 예외를 새로 만들었다. 폐기된 수용 기준의 매핑은 지우고, 딸린 검사 항목에는 폐기(obsolete) 표기를 하며, 전환 근거가 없으면 발동하지 않는다 |
init intake(요구 접수 단계)의 goal 스키마(목표 객체의 틀) |
execution_constraints(실행 제약을 적는 칸)은 이미 있었다. 용어(ontology) 축만 없었다 |
ontology(용어 정의) 선택 필드를 추가했다. handoff(단계 사이에 넘겨주는 인계 문서)를 통해 /team에 상속된다 |
init 요구사항 잠금 파일 .requirements-lock.md |
LOCK 행(기능 하나의 서명을 한 줄로 잠가 두는 행)만 있었다. 프로젝트 수준의 3축 시드는 없었다 |
## Spec 헤더 섹션을 넣으라고 지시했다. 이 파일을 지키는 가드(검사기)가 ^LOCK|로 시작하는 행만 읽는다는 것을 실측한 뒤, 충돌 없이 배치했다 |
문서에 문구가 있는지 확인하는 검사(문구 검증)와, 그 문구대로 따라가면 실제로 일이 흘러가는지 확인하는 검사(실행 체인 검증)는 다른 검사다. 독립 검증자는 합의된 수용 기준 7개를 전부 통과시켰다. 그러고도 기준 밖에서 배선을 따라가 두 곳의 끊김을 찾았다.
"상속되어 출발점으로 삼는다"는 주장만 있었다. 시드를 읽으라는 소비 지시는 0건이었다
init 쪽에는 ontology 필드와 ## Spec 시드 섹션을 만들라는 지시가 있었다 ✓goal.ontology와 잠금 파일(lock)의 ## Spec 섹션을 읽으라는 지시는 grep으로 찾아도 0건이었다"폐기한 검사 항목을 plan에 남겨라"는 새 지시가, 게이트가 세는 분모(있어야 할 검사 항목 수)에 그대로 계수됐다
^#### TC-E2E-PASS(검사 항목이 통과했다는 판정 표시)를 놓고 이지선다가 됐다. push를 차단하든지 or 실행하지도 않은 검사 항목에 통과 표시를 붙여 거짓 증거를 만들든지OBSOLETE-문구 검증과 실행 체인 검증은 다른 검사다. 독립 검증자는 수용 기준 7개를 전부 통과시켰다. 그러면서도 기준 밖에서 "이 배선을 따라가면 실제로 무슨 일이 일어나는가"를 추적해 끊김 2건을 찾았다. 하나는 만드는 쪽(생산자)만 있고 읽는 쪽(소비자)이 없는 허공 배선이었다. 다른 하나는 새 계약이 기존 HARD(사람 판단 없이 exit 2로 실제 차단하는 강제 등급) 게이트와 충돌해 push가 차단되는 미래였다. 배선을 더할 때는 항상 생산자와 소비자를 쌍으로 넣어야 한다. 그리고 그 산출물이 통과할 게이트의 파서(문서를 읽어 수를 세는 부분)까지 대조해야 끝난 것이다.
| 전파 전 실패모드 | 전파 후 | 근거 |
|---|---|---|
| 3축이 리드의 메모리에만 있었다. compaction 한 번이면 기준선이 사라지고 전환 판정은 감으로 돌아간다 | plan의 ## Spec 섹션이 디스크에 남는 기준선이 된다. 세션이 끊겨도 대조할 수 있다 |
compaction-governance-decay 규칙(산문으로 적힌 제약은 대화 압축이 지운다는 규칙)이 근거다. 제약이 살아남으면 위반 0% vs 지워지면 38%였다 |
| 의도 전환 감지가 Step 2.5에만 있었다. 이미 낡은 검사 항목으로 QA 한 라운드를 다 쓴 뒤에야 다시 도출했다 | Step 1의 §0에서 fan-out 전에 감지한다. 첫 실행부터 갱신된 검사 항목으로 돈다 | QA fan-out 한 라운드는 하위 AI 3~5기를 돌리는 비용이다. 주 지점을 앞으로 옮기는 데 spawn 추가는 0이었다 |
| 의도 전환 뒤 폐기 검사 항목이 게이트 분모에 계수됐다. 결과는 push 차단 또는 거짓 통과 계수 강요, 둘 중 하나였다 | 세지 않는 표기 계약 덕에 전환이 있던 런(한 번의 실행)도 게이트를 정상 통과한다. 실행하지 않은 검사 항목을 통과로 꾸미는 거짓 증거 없이 그렇다 | 게이트가 세는 패턴 4개 전부에서 변형 표기가 세어지지 않음을 grep으로 실증했다. 심각도 세 등급(치명·높음·중간)의 토큰과 엔드투엔드 검사 헤딩이 그 패턴이다: CRITICAL/HIGH/MEDIUM TC-E2E |
| init이 시드를 심어도 team이 읽지 않았다. 프로젝트의 제약과 용어가 런마다 다시 만들어지고 서로 어긋날 위험이 있었다 | handoff와 lock 파일의 시드가 team의 3축으로 상속되는 체인이 완성됐다. 프로젝트 수준의 일관성이 생긴다 | team SKILL:60(team 스킬 절차서의 60번째 줄)이 이미 handoff를 실행 전제로 읽던 구조였다. 거기에 소비 지시 한 줄만 더했으니 비용은 0이다 |
soft-to-hard(사람 판단에 맡기던 규칙을 사용 실적을 본 뒤 자동 검사로 올리는 승격 절차)로 올리기에는 아직 이르다. 여기까지는 문서 계약 + 게이트 grep 실증이다. 실제 /team 런에서 시드 로드, 전환 체크, 폐기 항목 비계수가 발동하는 행동 실증은 아직 없다. 다음 /team 런들이 그 관측 지점이다. plan에 ## Spec 섹션이 실제로 있는지를 자동 차단 게이트로 강제할지도 그 승격 절차로 판단한다. 효과가 없으면 archive(보관함으로 치워 두기)가 정답이라는 원칙은 이 배선에도 똑같이 적용된다.