[verified] Document read control responses and script preparation

This commit is contained in:
2026-10-12 13:06:17 +00:00
parent 613a7ae24a
commit b24632d65d
2 changed files with 28 additions and 0 deletions
@@ -97,6 +97,14 @@ JSON probe는 실행 전에 producer와 consumer가 고유 marker와 record 경
Marker 밖의 warning과 exit status, timeout·출력 한도·termination 상태는 안전한 bounded context로 별도 보존·검토한다. 유효 JSON 한 개만으로 실패 exit 또는 미완료 실행을 성공으로 바꾸지 않는다. Parser/framing·환경 오류는 제품 assertion 실패나 TDD RED로 보고하지 않고 필수 근거 부족은 기존 판정 기준으로 처리한다. 모든 capture/artifact에는 기존 credential redaction·유출 fail-closed 규칙을 적용하며 marker가 인증·provenance·secret 안전성을 보장한다고 주장하지 않는다. 새 generic parser나 manifest schema는 추가하지 않는다. Marker 밖의 warning과 exit status, timeout·출력 한도·termination 상태는 안전한 bounded context로 별도 보존·검토한다. 유효 JSON 한 개만으로 실패 exit 또는 미완료 실행을 성공으로 바꾸지 않는다. Parser/framing·환경 오류는 제품 assertion 실패나 TDD RED로 보고하지 않고 필수 근거 부족은 기존 판정 기준으로 처리한다. 모든 capture/artifact에는 기존 credential redaction·유출 fail-closed 규칙을 적용하며 marker가 인증·provenance·secret 안전성을 보장한다고 주장하지 않는다. 새 generic parser나 manifest schema는 추가하지 않는다.
### Programmatic read control response와 script 준비
Programmatic reader는 첫 content-bearing 응답의 실제 내용을 exact 경로, source revision(적용 가능한 경우) 또는 독립 확인한 byte hash, 읽은 범위·완전성과 함께 보존한다. `content` 접근 전에 응답 shape와 content 반환 여부·타입을 확인한다. 본문 없는 `unchanged/dedup` 응답은 control response이지 빈 파일이나 새 source 내용이 아니다. 현재 입력의 identity·revision/hash·필요 범위와 보존된 내용의 binding이 확인된 경우에만 재사용하고, tool의 unchanged 표시만으로 다른 process의 cache나 미보존 내용을 추정하지 않는다. Paginated 일부 내용은 전체 파일 근거로 승격하지 않는다.
보존된 내용이 없거나 binding이 불명확하면 현재 허용된 bounded read-only 조회로 exact 입력을 다시 확인한다. 조회 수단·범위·출처를 검증할 수 없으면 `evidence_gap`으로 중단하며 missing content를 빈 문자열이나 fabricated 내용으로 대체하지 않는다. 지원하지 않는 force-read parameter를 만들거나 전역 dedup을 해제하지 않고 stale cache를 재사용하지 않는다. 이 규칙은 새로운 read wrapper·cache subsystem을 요구하지 않는다.
Script 준비에는 검증된 source 파일과 typed JSON 입력을 우선하고 다중 quoted Python command로 내용을 재조립하지 않는다. 필요한 Python을 준비한 경우 그 exact bytes를 실행·로그 append·외부 action 전에 side-effect 없는 compile로 확인한다. Compile은 문법 검사일 뿐 안전성·인증·실행 성공의 증거가 아니므로 기존 scope·source·deadline·redaction·실행 provenance 검증은 별도로 유지한다. 문법 오류는 준비 실패로 보존하고 제품 assertion 실패나 TDD RED로 분류하지 않는다. Credential 값은 source·입력 artifact·오류·log에 저장하지 않는다. 이 절차는 review role의 commit/push·credential·새 transport 권한을 확장하지 않는다. 기존 reviewer의 source 수정·commit/push 금지는 유지하며, 검증 통과 자체가 외부 write 승인을 의미하지 않는다.
## 판정과 기록 ## 판정과 기록
- `approve`: 전체 diff, 관련 코드·테스트와 필요한 실행 근거를 검토했고 미해결 중요 결함이나 필수 검증 공백이 없다. 승인 전 필수로 분류한 matrix 행은 모두 통과하거나 근거 있는 비적용이어야 한다. 필수 행에 실패·미검증 또는 설명 없는 비적용이 남으면 승인하지 않는다. 전체 파일 열람이나 전체 테스트 통과만으로 이 조건을 충족했다고 간주하지 않는다. 선택적 검증의 미완료는 한계로 보고하며 자동으로 변경 요청하지 않는다. - `approve`: 전체 diff, 관련 코드·테스트와 필요한 실행 근거를 검토했고 미해결 중요 결함이나 필수 검증 공백이 없다. 승인 전 필수로 분류한 matrix 행은 모두 통과하거나 근거 있는 비적용이어야 한다. 필수 행에 실패·미검증 또는 설명 없는 비적용이 남으면 승인하지 않는다. 전체 파일 열람이나 전체 테스트 통과만으로 이 조건을 충족했다고 간주하지 않는다. 선택적 검증의 미완료는 한계로 보고하며 자동으로 변경 요청하지 않는다.
@@ -28,6 +28,26 @@ class ReviewProbeDocumentationTests(unittest.TestCase):
with self.subTest(rule=rule): with self.subTest(rule=rule):
self.assertIn(rule, section) self.assertIn(rule, section)
def test_documentation_contract_requires_bound_content_and_control_response_handling(self):
text = SKILL.read_text()
heading = '### Programmatic read control response와 script 준비'
self.assertIn(heading, text)
section = text.split(heading, 1)[1].split('\n## ', 1)[0]
for rule in ('첫 content-bearing 응답', 'exact 경로', 'source revision',
'hash', '읽은 범위', '응답 shape', 'control response',
'unchanged/dedup', '보존된 내용', 'evidence_gap',
'force-read', '전역 dedup', 'stale cache'):
with self.subTest(rule=rule):
self.assertIn(rule, section)
def test_documentation_contract_requires_compile_before_execution_and_preserves_authority(self):
section = SKILL.read_text().split('### Programmatic read control response와 script 준비', 1)[1].split('\n## ', 1)[0]
for rule in ('typed JSON', '다중 quoted', 'compile', '실행·로그 append·외부 action 전에',
'문법 검사', '안전성·인증·실행 성공', 'credential',
'commit/push', 'review role', '권한을 확장하지 않는다', 'TDD RED'):
with self.subTest(rule=rule):
self.assertIn(rule, section)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()