W22 · CI·AWS 최소 배포

22주차 코드 뒤풀이: 외부 CI·OIDC 증거부터 disposable restore·비용 teardown까지

유일한 정본 packaged source인 run-w22-restore.ps1과 외부 GitHub/AWS contract·template을 출처 등급별로 분리해 읽습니다. 외부 미실행은 NOT_RUN_EXTERNAL, 사람 검토 전 상태는 MANUAL_REVIEW_REQUIRED로 남기고, 로컬 restore만 3·120·0과 cleanup을 자동 검증합니다. D7 worksheet의 checked_at 누락 충돌과 prompt-only Q35·Q36의 비정본 가정도 그대로 드러냅니다.

원문 정본 · 완전한 packaged PowerShell source 1개학습용 예시 · PDF contract/template · 정본 답안 아님 3개학습용 예시 · PDF YAML template · 정본 답안 아님 · 그대로 실행 금지 1개학습용 예시 · PDF JSON schema/worksheet · 정본 답안 아님 · 비실행 2개학습용 예시 · PDF shell 학습 골격 · 정본 답안 아님 · 그대로 실행 금지 1개학습용 예시 · 정본 답안 아님 2개항목마다 13단계연결 292줄번역 292줄원문 PDF 720쪽 W22 제목–750쪽
01

외부 CI 계약 — clean runner와 실패 artifact는 공식 run으로만 증명

illustrative/text/W22-D1-external-ci-contract.txt

학습용 예시 · PDF contract/template · 정본 답안 아님 · 학습용 예시 · 정본 답안 아님 · W22-F01
11줄 연결11줄 번역2 chunks
01

STEP 01 / 13

오늘 이 코드에서 해결할 문제

무엇을 이해해야 하는지 질문부터 잡습니다.

오늘의 한 문장

GitHub Actions의 공식 run URL·commit·실패 report artifact를 사람 검토에 묶고 로컬 Green을 금지하는 외부 실행 계약이다.

  1. `FUTURE_TRIGGER`은 어느 줄에서 생길까?
  2. 입력→guard→관찰→cleanup 순서는 무엇인가?
  3. local owner와 external human review는 누구인가?
  4. 직접 관찰하지 않은 Green은 무엇인가?
  5. 반례는 `실제 GitHub run이 아니다`이라는 경계와 어떻게 연결되는가?
이 파일에서 끝까지 다시 쓰는 값FUTURE_TRIGGERNOT_RUN_EXTERNALofficial_run_urlartifact_urllocal_green_owner=none
02

STEP 02 / 13

아주 짧게: 이 코드는 왜 필요할까?

웹소설 대신 이 코드가 필요한 이유만 두 문단으로 쉽게 봅니다.

STARRY가 GitHub run표·AWS 출입증·DB 복구 영수증·SQL 결과표를 서로 다른 칸에 놓는다.

외부 CI 계약 — clean runner와 실패 artifact는 공식 run으로만 증명 ― 증거 흐름으로 바꾸기

GitHub Actions의 공식 run URL·commit·실패 report artifact를 사람 검토에 묶고 로컬 Green을 금지하는 외부 실행 계약이다.

핵심값 FUTURE_TRIGGER, NOT_RUN_EXTERNAL, official_run_url, artifact_url, local_green_owner=none을 원본 줄로 따라가되, `실제 GitHub run이 아니다`까지 함께 표시해 Green 범위를 부풀리지 않는다.

딱 여기까지만 비유는 owner와 순서를 기억하게 할 뿐 외부 실행·AWS 계정 상태·PostgreSQL restore·SQL 결과를 자동 증명하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

생활 비유와 실제 코드의 경계를 함께 확인합니다.

원문 1–10줄

1~10줄을 한 덩어리로 읽어 1번째 움직임을 본다. GitHub Actions의 공식 run URL·commit·실패 report artifact를 사람 검토에 묶고 로컬 Green을 금지하는 외부 실행 계약이다.

코드 연결
1~10줄
비유
심판이 연습장 사진이 아니라 공식 경기 기록의 URL·선수 번호·영상 hash를 함께 대조하는 증거 봉투
비유의 끝
실제 GitHub run이 아니다

원문 11–11줄

11~11줄을 한 덩어리로 읽어 2번째 움직임을 본다. GitHub Actions의 공식 run URL·commit·실패 report artifact를 사람 검토에 묶고 로컬 Green을 금지하는 외부 실행 계약이다.

코드 연결
11~11줄
비유
심판이 연습장 사진이 아니라 공식 경기 기록의 URL·선수 번호·영상 hash를 함께 대조하는 증거 봉투
비유의 끝
로컬 파일·문자열 검사는 외부 성공을 증명하지 않는다
문제의 첫 장면
  1. 첫 고정값은 `FUTURE_TRIGGER` 맞아?

  2. GitHub Actions의 공식 run URL·commit·실패 report artifact를 사람 검토에 묶고 로컬 Green을 금지하는 외부 실행 계약이다.

  3. 원문에서 `FUTURE_TRIGGER`이 생기는 위치를 찾자.

  4. 그리고 `실제 GitHub run이 아니다`도 같이 적어.

입력에서 결과까지
  1. `NOT_RUN_EXTERNAL`은 언제 생겨?

  2. clean workflow를 작성한다. → push/PR로 공식 run을 만든다.

  3. commit과 test summary·artifact를 묶는다. → 사람이 required check와 실패 artifact를 대조한다.

  4. 관찰값과 `로컬 파일·문자열 검사는 외부 성공을 증명하지 않는다`을 분리하면 돼.

04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

감사 규칙상 연결 대상인 원본 11줄을 빠짐없이 연결합니다.

단어 몇 개만 뽑은 표가 아닙니다.학습용 예시 · PDF contract/template · 정본 답안 아님에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.11 / 11 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F01-L01 학습용 예시 · PDF 외부 실행 계약 · 정본 답안 아님 심판이 연습장 사진이 아니라 공식 경기 기록의 URL·선수 번호·영상 hash를 함께 대조하는 증거 봉투 외부 GitHub Actions evidence 계약의 1번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
official GitHub run URL·commit·test report artifact
결과·효과
이 줄 뒤에는 항목 전체의 `FUTURE_TRIGGER` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
실제 GitHub run이 아니다
2줄F01-L02 status: FUTURE_TRIGGER 심판이 연습장 사진이 아니라 공식 경기 기록의 URL·선수 번호·영상 hash를 함께 대조하는 증거 봉투 외부 GitHub Actions evidence 계약에서 `status: FUTURE_TRIGGER` field·값 또는 assignment를 다음 단계에 전달한다.
입력
official GitHub run URL·commit·test report artifact
결과·효과
이 줄 뒤에는 항목 전체의 `NOT_RUN_EXTERNAL` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
로컬 파일·문자열 검사는 외부 성공을 증명하지 않는다
3줄F01-L03 execution: NOT_RUN_EXTERNAL 심판이 연습장 사진이 아니라 공식 경기 기록의 URL·선수 번호·영상 hash를 함께 대조하는 증거 봉투 실제 외부 실행을 아직 수행·증명하지 않았다는 상태를 명시한다.
입력
official GitHub run URL·commit·test report artifact
결과·효과
이 줄 뒤에는 항목 전체의 `official_run_url` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
required check 설정은 사람이 확인한다
4줄F01-L04 required_fields: official_run_url, run_id, commit_sha, workflow_name, conclusion, screenshot_path, screenshot_sha256, artifact_url 심판이 연습장 사진이 아니라 공식 경기 기록의 URL·선수 번호·영상 hash를 함께 대조하는 증거 봉투 공식 GitHub Actions run을 가리키는 URL field를 선언한다.
입력
official GitHub run URL·commit·test report artifact
결과·효과
이 줄 뒤에는 항목 전체의 `artifact_url` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
장기 credential 부재도 실제 workflow를 검사해야 한다
5줄F01-L05 url_rule: official HTTPS GitHub Actions run URL 심판이 연습장 사진이 아니라 공식 경기 기록의 URL·선수 번호·영상 hash를 함께 대조하는 증거 봉투 외부 GitHub Actions evidence 계약에서 `url_rule: official HTTPS GitHub Actions run URL` field·값 또는 assignment를 다음 단계에 전달한다.
입력
official GitHub run URL·commit·test report artifact
결과·효과
이 줄 뒤에는 항목 전체의 `local_green_owner=none` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
실제 GitHub run이 아니다
6줄F01-L06 hash_rule: screenshot_sha256 is exact 64-hex hash of screenshot_path 심판이 연습장 사진이 아니라 공식 경기 기록의 URL·선수 번호·영상 hash를 함께 대조하는 증거 봉투 현재 file bytes를 64-hex SHA-256 값과 결박하는 field 또는 검사를 다룬다.
입력
official GitHub run URL·commit·test report artifact
결과·효과
이 줄 뒤에는 항목 전체의 `FUTURE_TRIGGER` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
로컬 파일·문자열 검사는 외부 성공을 증명하지 않는다
7줄F01-L07 local_green_owner: none 심판이 연습장 사진이 아니라 공식 경기 기록의 URL·선수 번호·영상 hash를 함께 대조하는 증거 봉투 외부 GitHub Actions evidence 계약에서 `local_green_owner: none` field·값 또는 assignment를 다음 단계에 전달한다.
입력
official GitHub run URL·commit·test report artifact
결과·효과
이 줄 뒤에는 항목 전체의 `NOT_RUN_EXTERNAL` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
required check 설정은 사람이 확인한다
8줄F01-L08 local_restore_owner: scripts/run-w22-restore.ps1 (Saturday) 심판이 연습장 사진이 아니라 공식 경기 기록의 URL·선수 번호·영상 hash를 함께 대조하는 증거 봉투 외부 GitHub Actions evidence 계약에서 `local_restore_owner: scripts/run-w22-restore.ps1` field·값 또는 assignment를 다음 단계에 전달한다.
입력
official GitHub run URL·commit·test report artifact
결과·효과
이 줄 뒤에는 항목 전체의 `official_run_url` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
장기 credential 부재도 실제 workflow를 검사해야 한다
9줄F01-L09 manual_rule: 승인된 repository의 실제 push/PR 뒤 공식 run URL과 commit SHA를 사람이 대조한다. 심판이 연습장 사진이 아니라 공식 경기 기록의 URL·선수 번호·영상 hash를 함께 대조하는 증거 봉투 외부 GitHub Actions evidence 계약에서 `manual_rule: 승인된 repository의 실제 push/PR 뒤 공식 run` field·값 또는 assignment를 다음 단계에 전달한다.
입력
official GitHub run URL·commit·test report artifact
결과·효과
이 줄 뒤에는 항목 전체의 `artifact_url` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
실제 GitHub run이 아니다
10줄F01-L10 failure_artifact_rule: 고의 실패 run에서도 test report artifact가 남아야 한다. 심판이 연습장 사진이 아니라 공식 경기 기록의 URL·선수 번호·영상 hash를 함께 대조하는 증거 봉투 외부 GitHub Actions evidence 계약에서 `failure_artifact_rule: 고의 실패 run에서도 test report ` field·값 또는 assignment를 다음 단계에 전달한다.
입력
official GitHub run URL·commit·test report artifact
결과·효과
이 줄 뒤에는 항목 전체의 `local_green_owner=none` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
로컬 파일·문자열 검사는 외부 성공을 증명하지 않는다
11줄F01-L11 boundary: 로컬 파일 존재·문자열 검사·self-declared PASS는 외부 CI Green이 아니다. 심판이 연습장 사진이 아니라 공식 경기 기록의 URL·선수 번호·영상 hash를 함께 대조하는 증거 봉투 외부 GitHub Actions evidence 계약에서 `boundary: 로컬 파일 존재·문자열 검사·self-declared PASS는 외부` field·값 또는 assignment를 다음 단계에 전달한다.
입력
official GitHub run URL·commit·test report artifact
결과·효과
이 줄 뒤에는 항목 전체의 `FUTURE_TRIGGER` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
required check 설정은 사람이 확인한다
Green 범위
  1. marker나 파일이 보이면 전부 성공이야?

  2. 아니. source가 직접 검증한 범위만 말해야 해.

  3. 직접 연결되는 대표 값은 `local_green_owner=none`이야.

  4. `required check 설정은 사람이 확인한다`는 별도 증거가 필요해.

05

STEP 05 / 13

원본 코드 조각

원본을 2개 의미 조각으로 나누어 그대로 확인합니다.

파일을 한꺼번에 외우지 않고 실행 의미가 이어지는 작은 조각으로 봅니다. 아래 코드는 prompt·fixture·가정을 밝힌 학습용 예시 source이며, 제공 정본 답안이 아닙니다.

F01-C01 · 원문 1–10줄1–10줄
1–10줄 원본
학습용 예시 · PDF 외부 실행 계약 · 정본 답안 아님
status: FUTURE_TRIGGER
execution: NOT_RUN_EXTERNAL
required_fields: official_run_url, run_id, commit_sha, workflow_name, conclusion, screenshot_path, screenshot_sha256, artifact_url
url_rule: official HTTPS GitHub Actions run URL
hash_rule: screenshot_sha256 is exact 64-hex hash of screenshot_path
local_green_owner: none
local_restore_owner: scripts/run-w22-restore.ps1 (Saturday)
manual_rule: 승인된 repository의 실제 push/PR 뒤 공식 run URL과 commit SHA를 사람이 대조한다.
failure_artifact_rule: 고의 실패 run에서도 test report artifact가 남아야 한다.
F01-C02 · 원문 11–11줄11–11줄
11–11줄 원본
boundary: 로컬 파일 존재·문자열 검사·self-declared PASS는 외부 CI Green이 아니다.
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

비어 있지 않은 11줄을 모두 한국어로 옮깁니다.

전체 번역 11 / 11

비어 있지 않은 원본 줄은 하나도 생략하지 않습니다.

원본한국어 번역
1학습용 예시 · PDF 외부 실행 계약 · 정본 답안 아님외부 GitHub Actions evidence 계약의 1번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
2status: FUTURE_TRIGGER외부 GitHub Actions evidence 계약에서 `status: FUTURE_TRIGGER` field·값 또는 assignment를 다음 단계에 전달한다.
3execution: NOT_RUN_EXTERNAL실제 외부 실행을 아직 수행·증명하지 않았다는 상태를 명시한다.
4required_fields: official_run_url, run_id, commit_sha, workflow_name, conclusion, screenshot_path, screenshot_sha256, artifact_url공식 GitHub Actions run을 가리키는 URL field를 선언한다.
5url_rule: official HTTPS GitHub Actions run URL외부 GitHub Actions evidence 계약에서 `url_rule: official HTTPS GitHub Actions run URL` field·값 또는 assignment를 다음 단계에 전달한다.
6hash_rule: screenshot_sha256 is exact 64-hex hash of screenshot_path현재 file bytes를 64-hex SHA-256 값과 결박하는 field 또는 검사를 다룬다.
7local_green_owner: none외부 GitHub Actions evidence 계약에서 `local_green_owner: none` field·값 또는 assignment를 다음 단계에 전달한다.
8local_restore_owner: scripts/run-w22-restore.ps1 (Saturday)외부 GitHub Actions evidence 계약에서 `local_restore_owner: scripts/run-w22-restore.ps1` field·값 또는 assignment를 다음 단계에 전달한다.
9manual_rule: 승인된 repository의 실제 push/PR 뒤 공식 run URL과 commit SHA를 사람이 대조한다.외부 GitHub Actions evidence 계약에서 `manual_rule: 승인된 repository의 실제 push/PR 뒤 공식 run` field·값 또는 assignment를 다음 단계에 전달한다.
10failure_artifact_rule: 고의 실패 run에서도 test report artifact가 남아야 한다.외부 GitHub Actions evidence 계약에서 `failure_artifact_rule: 고의 실패 run에서도 test report ` field·값 또는 assignment를 다음 단계에 전달한다.
11boundary: 로컬 파일 존재·문자열 검사·self-declared PASS는 외부 CI Green이 아니다.외부 GitHub Actions evidence 계약에서 `boundary: 로컬 파일 존재·문자열 검사·self-declared PASS는 외부` field·값 또는 assignment를 다음 단계에 전달한다.
07

STEP 07 / 13

기존 수준의 한 줄 읽기·문법 해부

쉬운 설명 다음에 문법과 실행 순서를 정밀하게 읽습니다.

한 줄로 읽기

GitHub Actions의 공식 run URL·commit·실패 report artifact를 사람 검토에 묶고 로컬 Green을 금지하는 외부 실행 계약이다. 다만 실제 GitHub run이 아니다

문법 해부

  • `key: value` 줄은 외부 증거의 필수 field와 상태를 고정한다.
  • `NOT_RUN_EXTERNAL`은 실패가 아니라 실제 외부 실행을 아직 주장하지 않는 정확한 상태다.

실행 순서

  1. clean workflow를 작성한다.
  2. push/PR로 공식 run을 만든다.
  3. commit과 test summary·artifact를 묶는다.
  4. 사람이 required check와 실패 artifact를 대조한다.

W22 조각별 정밀 해설

F01-C01 · 원문 1–10줄
문법 해부
1~10줄의 `원문 1–10줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `FUTURE_TRIGGER`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `FUTURE_TRIGGER`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: 실제 GitHub run이 아니다.
착각 방지
`원문 1–10줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: 실제 GitHub run이 아니다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F01-C02 · 원문 11–11줄
문법 해부
11~11줄의 `원문 11–11줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `NOT_RUN_EXTERNAL`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `NOT_RUN_EXTERNAL`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: 로컬 파일·문자열 검사는 외부 성공을 증명하지 않는다.
착각 방지
`원문 11–11줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: 로컬 파일·문자열 검사는 외부 성공을 증명하지 않는다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
반례
  1. 겉보기에는 맞지만 깨지는 예는?

  2. 로컬 test 0을 외부 CI Green으로 부른다

  3. 그 상태는 owner·입력·관찰 중 한 칸이 비어 있어.

  4. 수정한 뒤 같은 source와 hash로 다시 대조해.

08

STEP 08 / 13

실제 값 따라가기

같은 입력값이 어느 줄을 지나 어떤 결과가 되는지 추적합니다.

순서들어온 값코드가 하는 일나온 값·상태경계
F01-T01 미실행local templatestate 선언NOT_RUN_EXTERNALlocal Green 없음
F01-T02 정상 runofficial URL+commit사람 대조MANUAL_REVIEW_REQUIRED 해소 가능required check 별도
F01-T03 고의 실패failing commitalways uploadreport artifact 유지failure가 success로 바뀌는 것은 아님
책임 경계
  1. 이 항목의 마지막 책임선은?

  2. 직접 역할은 `외부 GitHub Actions evidence 계약`이야.

  3. 대표 경계는 `장기 credential 부재도 실제 workflow를 검사해야 한다`이야.

  4. 정본/비정본 label과 evidence owner까지 확인하면 끝이야.

09

STEP 09 / 13

GitHub·AWS·PowerShell·PostgreSQL 내부에서 벌어지는 일

GitHub·AWS·PowerShell·PostgreSQL에서 실제로 일어나는 일과 증명 범위를 구분합니다.

GitHub runner

checkout commit만으로 clean test를 실행한다.

로컬 cache를 증거로 쓰지 않는다.
artifact store

실패 뒤에도 report를 보존한다.

artifact 존재만으로 test 성공은 아니다.
repository rule

required check가 merge 경계를 만든다.

workflow 파일만으로 정책 적용을 증명하지 못한다.
10

STEP 10 / 13

흔한 착각과 틀린 예

그럴듯하지만 틀린 해석을 반례로 고칩니다.

❌ 로컬 test 0을 외부 CI Green으로 부른다

왜 틀리나 외부 GitHub Actions evidence 계약의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 clean workflow를 작성한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `실제 GitHub run이 아니다` 상태인데도 Green을 주장하게 된다.

❌ 성공 캡처만 남기고 URL·commit을 빼먹는다

왜 틀리나 외부 GitHub Actions evidence 계약의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 push/PR로 공식 run을 만든다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `로컬 파일·문자열 검사는 외부 성공을 증명하지 않는다` 상태인데도 Green을 주장하게 된다.

❌ 실패 때 report upload를 건너뛴다

왜 틀리나 외부 GitHub Actions evidence 계약의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 commit과 test summary·artifact를 묶는다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `required check 설정은 사람이 확인한다` 상태인데도 Green을 주장하게 된다.

❌ 장기 AWS key를 test job에 둔다

왜 틀리나 외부 GitHub Actions evidence 계약의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 사람이 required check와 실패 artifact를 대조한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `장기 credential 부재도 실제 workflow를 검사해야 한다` 상태인데도 Green을 주장하게 된다.

❌ self-declared PASS를 공식 conclusion으로 착각한다

왜 틀리나 외부 GitHub Actions evidence 계약의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 사람이 required check와 실패 artifact를 대조한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `실제 GitHub run이 아니다` 상태인데도 Green을 주장하게 된다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

이 코드가 책임지지 않는 일을 분리합니다.

직접 미보장

실제 GitHub run이 아니다

이 책임을 맡는 곳: 별도 외부/selector 실행
직접 미보장

로컬 파일·문자열 검사는 외부 성공을 증명하지 않는다

이 책임을 맡는 곳: secret·운영 정책
직접 미보장

required check 설정은 사람이 확인한다

이 책임을 맡는 곳: infrastructure·사람 검토
직접 미보장

장기 credential 부재도 실제 workflow를 검사해야 한다

이 책임을 맡는 곳: owner lifecycle
12

STEP 12 / 13

직접 다시 써보기

뜻 → 조각 → 전체 코드 순서로 다시 씁니다.

1단계 · 뜻부터 복원

다음 역할을 고정값과 미보장 경계까지 말한다: GitHub Actions의 공식 run URL·commit·실패 report artifact를 사람 검토에 묶고 로컬 Green을 금지하는 외부 실행 계약이다.

2단계 · 코드 조각 재조립

  1. 원문 1–10줄
  2. 원문 11–11줄

3단계 · 파일 전체 다시 쓰기

11개 물리 줄을 원본 순서로 복원하고 SHA-256 1cb8a4605cae9d6e9c531b6b33e4f3d3066f27370e3b04043aa7f3b09c10a9dc와 대조한다.

자가 점검
  • 원본 source/template bytes를 바꾸지 않았는가?
  • 외부 미실행과 local restore Green을 구분했는가?
  • secret 원문을 evidence에 남기지 않았는가?
  • D7 checked_at 충돌과 사람 검토 경계를 보았는가?
  • Q35/Q36을 workbook 정본 답안이라고 부르지 않았는가?
13

STEP 13 / 13

전체 원본 source

감사로 고정한 전체 source를 가감 없이 확인합니다.

학습용 예시 전체 확인하기 · 정본 답안 아님
학습용 예시 · PDF contract/template · 정본 답안 아님illustrative/text/W22-D1-external-ci-contract.txtSHA-256 1cb8a4605cae9d6e9c531b6b33e4f3d3066f27370e3b04043aa7f3b09c10a9dc
외부 CI 계약 — clean runner와 실패 artifact는 공식 run으로만 증명 전체
학습용 예시 · PDF 외부 실행 계약 · 정본 답안 아님
status: FUTURE_TRIGGER
execution: NOT_RUN_EXTERNAL
required_fields: official_run_url, run_id, commit_sha, workflow_name, conclusion, screenshot_path, screenshot_sha256, artifact_url
url_rule: official HTTPS GitHub Actions run URL
hash_rule: screenshot_sha256 is exact 64-hex hash of screenshot_path
local_green_owner: none
local_restore_owner: scripts/run-w22-restore.ps1 (Saturday)
manual_rule: 승인된 repository의 실제 push/PR 뒤 공식 run URL과 commit SHA를 사람이 대조한다.
failure_artifact_rule: 고의 실패 run에서도 test report artifact가 남아야 한다.
boundary: 로컬 파일 존재·문자열 검사·self-declared PASS는 외부 CI Green이 아니다.
02

AWS 경계 — public 443, private app·RDS, 관리 접속은 SSM

illustrative/text/W22-D2-architecture-rules.txt

학습용 예시 · PDF contract/template · 정본 답안 아님 · 학습용 예시 · 정본 답안 아님 · W22-F02
11줄 연결11줄 번역2 chunks
01

STEP 01 / 13

오늘 이 코드에서 해결할 문제

무엇을 이해해야 하는지 질문부터 잡습니다.

오늘의 한 문장

public ALB 443에서 private app 8080과 private RDS 5432로 이어지는 SG-to-SG 최소 AWS 경계를 고정한다.

  1. `ALB:443 public`은 어느 줄에서 생길까?
  2. 입력→guard→관찰→cleanup 순서는 무엇인가?
  3. local owner와 external human review는 누구인가?
  4. 직접 관찰하지 않은 Green은 무엇인가?
  5. 반례는 `diagram template은 실제 resource 생성 증거가 아니다`이라는 경계와 어떻게 연결되는가?
이 파일에서 끝까지 다시 쓰는 값ALB:443 publicApp:8080 privateRDS:5432 privateSSM no SSH 22CloudWatch
02

STEP 02 / 13

아주 짧게: 이 코드는 왜 필요할까?

웹소설 대신 이 코드가 필요한 이유만 두 문단으로 쉽게 봅니다.

STARRY가 GitHub run표·AWS 출입증·DB 복구 영수증·SQL 결과표를 서로 다른 칸에 놓는다.

AWS 경계 — public 443, private app·RDS, 관리 접속은 SSM ― 증거 흐름으로 바꾸기

public ALB 443에서 private app 8080과 private RDS 5432로 이어지는 SG-to-SG 최소 AWS 경계를 고정한다.

핵심값 ALB:443 public, App:8080 private, RDS:5432 private, SSM no SSH 22, CloudWatch을 원본 줄로 따라가되, `diagram template은 실제 resource 생성 증거가 아니다`까지 함께 표시해 Green 범위를 부풀리지 않는다.

딱 여기까지만 비유는 owner와 순서를 기억하게 할 뿐 외부 실행·AWS 계정 상태·PostgreSQL restore·SQL 결과를 자동 증명하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

생활 비유와 실제 코드의 경계를 함께 확인합니다.

원문 1–10줄

1~10줄을 한 덩어리로 읽어 1번째 움직임을 본다. public ALB 443에서 private app 8080과 private RDS 5432로 이어지는 SG-to-SG 최소 AWS 경계를 고정한다.

코드 연결
1~10줄
비유
거리의 정문은 443 하나만 열고, 주방 8080과 금고 5432는 앞방의 출입증으로만 이어지는 건물 도면
비유의 끝
diagram template은 실제 resource 생성 증거가 아니다

원문 11–11줄

11~11줄을 한 덩어리로 읽어 2번째 움직임을 본다. public ALB 443에서 private app 8080과 private RDS 5432로 이어지는 SG-to-SG 최소 AWS 경계를 고정한다.

코드 연결
11~11줄
비유
거리의 정문은 443 하나만 열고, 주방 8080과 금고 5432는 앞방의 출입증으로만 이어지는 건물 도면
비유의 끝
single-instance 학습 설계는 production HA가 아니다
문제의 첫 장면
  1. 첫 고정값은 `ALB:443 public` 맞아?

  2. public ALB 443에서 private app 8080과 private RDS 5432로 이어지는 SG-to-SG 최소 AWS 경계를 고정한다.

  3. 원문에서 `ALB:443 public`이 생기는 위치를 찾자.

  4. 그리고 `diagram template은 실제 resource 생성 증거가 아니다`도 같이 적어.

입력에서 결과까지
  1. `App:8080 private`은 언제 생겨?

  2. ALB 443만 public으로 둔다. → App 8080은 ALB SG에서만 허용한다.

  3. RDS 5432는 App SG에서만 허용한다. → 관리 접속은 inbound SSH 없이 SSM으로 한다.

  4. 관찰값과 `single-instance 학습 설계는 production HA가 아니다`을 분리하면 돼.

04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

감사 규칙상 연결 대상인 원본 11줄을 빠짐없이 연결합니다.

단어 몇 개만 뽑은 표가 아닙니다.학습용 예시 · PDF contract/template · 정본 답안 아님에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.11 / 11 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F02-L01 학습용 예시 · PDF architecture template · 정본 답안 아님 · 그대로 실행 금지 거리의 정문은 443 하나만 열고, 주방 8080과 금고 5432는 앞방의 출입증으로만 이어지는 건물 도면 AWS network·administration 경계 template의 1번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
ALB/App/RDS SG와 public/private subnet 결정
결과·효과
이 줄 뒤에는 항목 전체의 `ALB:443 public` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
diagram template은 실제 resource 생성 증거가 아니다
2줄F02-L02 Internet -> ALB:443 (public) 거리의 정문은 443 하나만 열고, 주방 8080과 금고 5432는 앞방의 출입증으로만 이어지는 건물 도면 인터넷 entry와 private application 사이의 ALB 443 경계를 표현한다.
입력
ALB/App/RDS SG와 public/private subnet 결정
결과·효과
이 줄 뒤에는 항목 전체의 `App:8080 private` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
single-instance 학습 설계는 production HA가 아니다
3줄F02-L03 ALB SG -> App:8080 (private) 거리의 정문은 443 하나만 열고, 주방 8080과 금고 5432는 앞방의 출입증으로만 이어지는 건물 도면 인터넷 entry와 private application 사이의 ALB 443 경계를 표현한다.
입력
ALB/App/RDS SG와 public/private subnet 결정
결과·효과
이 줄 뒤에는 항목 전체의 `RDS:5432 private` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
RDS public accessibility false는 별도 확인이 필요하다
4줄F02-L04 App SG -> RDS PostgreSQL:5432 (private) 거리의 정문은 443 하나만 열고, 주방 8080과 금고 5432는 앞방의 출입증으로만 이어지는 건물 도면 private PostgreSQL 5432와 application SG 사이의 DB 경계를 표현한다.
입력
ALB/App/RDS SG와 public/private subnet 결정
결과·효과
이 줄 뒤에는 항목 전체의 `SSM no SSH 22` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
cost gate 전에 cloud resource를 만들지 않는다
5줄F02-L05 Admin -> SSM Session Manager (no inbound SSH 22) 거리의 정문은 443 하나만 열고, 주방 8080과 금고 5432는 앞방의 출입증으로만 이어지는 건물 도면 inbound SSH 없이 관리 session 또는 secret metadata를 다루는 AWS 경계를 나타낸다.
입력
ALB/App/RDS SG와 public/private subnet 결정
결과·효과
이 줄 뒤에는 항목 전체의 `CloudWatch` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
diagram template은 실제 resource 생성 증거가 아니다
6줄F02-L06 Secrets -> SSM Parameter Store or Secrets Manager 거리의 정문은 443 하나만 열고, 주방 8080과 금고 5432는 앞방의 출입증으로만 이어지는 건물 도면 inbound SSH 없이 관리 session 또는 secret metadata를 다루는 AWS 경계를 나타낸다.
입력
ALB/App/RDS SG와 public/private subnet 결정
결과·효과
이 줄 뒤에는 항목 전체의 `ALB:443 public` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
single-instance 학습 설계는 production HA가 아니다
7줄F02-L07 Logs/Metrics -> CloudWatch 거리의 정문은 443 하나만 열고, 주방 8080과 금고 5432는 앞방의 출입증으로만 이어지는 건물 도면 AWS network·administration 경계 template의 7번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
ALB/App/RDS SG와 public/private subnet 결정
결과·효과
이 줄 뒤에는 항목 전체의 `App:8080 private` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
RDS public accessibility false는 별도 확인이 필요하다
8줄F02-L08 security_group_rule: App inbound source is ALB SG, not 0.0.0.0/0. 거리의 정문은 443 하나만 열고, 주방 8080과 금고 5432는 앞방의 출입증으로만 이어지는 건물 도면 인터넷 entry와 private application 사이의 ALB 443 경계를 표현한다.
입력
ALB/App/RDS SG와 public/private subnet 결정
결과·효과
이 줄 뒤에는 항목 전체의 `RDS:5432 private` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
cost gate 전에 cloud resource를 만들지 않는다
9줄F02-L09 database_rule: RDS public accessibility is false and inbound source is App SG only. 거리의 정문은 443 하나만 열고, 주방 8080과 금고 5432는 앞방의 출입증으로만 이어지는 건물 도면 private PostgreSQL 5432와 application SG 사이의 DB 경계를 표현한다.
입력
ALB/App/RDS SG와 public/private subnet 결정
결과·효과
이 줄 뒤에는 항목 전체의 `SSM no SSH 22` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
diagram template은 실제 resource 생성 증거가 아니다
10줄F02-L10 cost_boundary: account resource creation requires a budget and teardown plan first. 거리의 정문은 443 하나만 열고, 주방 8080과 금고 5432는 앞방의 출입증으로만 이어지는 건물 도면 AWS network·administration 경계 template에서 `cost_boundary: account resource creation require` field·값 또는 assignment를 다음 단계에 전달한다.
입력
ALB/App/RDS SG와 public/private subnet 결정
결과·효과
이 줄 뒤에는 항목 전체의 `CloudWatch` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
single-instance 학습 설계는 production HA가 아니다
11줄F02-L11 non_goal: single-instance learning deployment is not production HA, WAF, or full DR. 거리의 정문은 443 하나만 열고, 주방 8080과 금고 5432는 앞방의 출입증으로만 이어지는 건물 도면 AWS network·administration 경계 template에서 `non_goal: single-instance learning deployment is` field·값 또는 assignment를 다음 단계에 전달한다.
입력
ALB/App/RDS SG와 public/private subnet 결정
결과·효과
이 줄 뒤에는 항목 전체의 `ALB:443 public` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
RDS public accessibility false는 별도 확인이 필요하다
Green 범위
  1. marker나 파일이 보이면 전부 성공이야?

  2. 아니. source가 직접 검증한 범위만 말해야 해.

  3. 직접 연결되는 대표 값은 `CloudWatch`이야.

  4. `RDS public accessibility false는 별도 확인이 필요하다`는 별도 증거가 필요해.

05

STEP 05 / 13

원본 코드 조각

원본을 2개 의미 조각으로 나누어 그대로 확인합니다.

파일을 한꺼번에 외우지 않고 실행 의미가 이어지는 작은 조각으로 봅니다. 아래 코드는 prompt·fixture·가정을 밝힌 학습용 예시 source이며, 제공 정본 답안이 아닙니다.

F02-C01 · 원문 1–10줄1–10줄
1–10줄 원본
학습용 예시 · PDF architecture template · 정본 답안 아님 · 그대로 실행 금지
Internet -> ALB:443 (public)
ALB SG -> App:8080 (private)
App SG -> RDS PostgreSQL:5432 (private)
Admin -> SSM Session Manager (no inbound SSH 22)
Secrets -> SSM Parameter Store or Secrets Manager
Logs/Metrics -> CloudWatch
security_group_rule: App inbound source is ALB SG, not 0.0.0.0/0.
database_rule: RDS public accessibility is false and inbound source is App SG only.
cost_boundary: account resource creation requires a budget and teardown plan first.
F02-C02 · 원문 11–11줄11–11줄
11–11줄 원본
non_goal: single-instance learning deployment is not production HA, WAF, or full DR.
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

비어 있지 않은 11줄을 모두 한국어로 옮깁니다.

전체 번역 11 / 11

비어 있지 않은 원본 줄은 하나도 생략하지 않습니다.

원본한국어 번역
1학습용 예시 · PDF architecture template · 정본 답안 아님 · 그대로 실행 금지AWS network·administration 경계 template의 1번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
2Internet -> ALB:443 (public)인터넷 entry와 private application 사이의 ALB 443 경계를 표현한다.
3ALB SG -> App:8080 (private)인터넷 entry와 private application 사이의 ALB 443 경계를 표현한다.
4App SG -> RDS PostgreSQL:5432 (private)private PostgreSQL 5432와 application SG 사이의 DB 경계를 표현한다.
5Admin -> SSM Session Manager (no inbound SSH 22)inbound SSH 없이 관리 session 또는 secret metadata를 다루는 AWS 경계를 나타낸다.
6Secrets -> SSM Parameter Store or Secrets Managerinbound SSH 없이 관리 session 또는 secret metadata를 다루는 AWS 경계를 나타낸다.
7Logs/Metrics -> CloudWatchAWS network·administration 경계 template의 7번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
8security_group_rule: App inbound source is ALB SG, not 0.0.0.0/0.인터넷 entry와 private application 사이의 ALB 443 경계를 표현한다.
9database_rule: RDS public accessibility is false and inbound source is App SG only.private PostgreSQL 5432와 application SG 사이의 DB 경계를 표현한다.
10cost_boundary: account resource creation requires a budget and teardown plan first.AWS network·administration 경계 template에서 `cost_boundary: account resource creation require` field·값 또는 assignment를 다음 단계에 전달한다.
11non_goal: single-instance learning deployment is not production HA, WAF, or full DR.AWS network·administration 경계 template에서 `non_goal: single-instance learning deployment is` field·값 또는 assignment를 다음 단계에 전달한다.
07

STEP 07 / 13

기존 수준의 한 줄 읽기·문법 해부

쉬운 설명 다음에 문법과 실행 순서를 정밀하게 읽습니다.

한 줄로 읽기

public ALB 443에서 private app 8080과 private RDS 5432로 이어지는 SG-to-SG 최소 AWS 경계를 고정한다. 다만 diagram template은 실제 resource 생성 증거가 아니다

문법 해부

  • 화살표 왼쪽은 허용 source, 오른쪽은 target port와 public/private 위치다.
  • SG-to-SG는 고정 IP 대신 앞 단계 security group identity를 source로 쓴다.

실행 순서

  1. ALB 443만 public으로 둔다.
  2. App 8080은 ALB SG에서만 허용한다.
  3. RDS 5432는 App SG에서만 허용한다.
  4. 관리 접속은 inbound SSH 없이 SSM으로 한다.

W22 조각별 정밀 해설

F02-C01 · 원문 1–10줄
문법 해부
1~10줄의 `원문 1–10줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `ALB:443 public`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `ALB:443 public`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: diagram template은 실제 resource 생성 증거가 아니다.
착각 방지
`원문 1–10줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: diagram template은 실제 resource 생성 증거가 아니다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F02-C02 · 원문 11–11줄
문법 해부
11~11줄의 `원문 11–11줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `App:8080 private`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `App:8080 private`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: single-instance 학습 설계는 production HA가 아니다.
착각 방지
`원문 11–11줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: single-instance 학습 설계는 production HA가 아니다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
반례
  1. 겉보기에는 맞지만 깨지는 예는?

  2. EC2 8080을 0.0.0.0/0에 연다

  3. 그 상태는 owner·입력·관찰 중 한 칸이 비어 있어.

  4. 수정한 뒤 같은 source와 hash로 다시 대조해.

08

STEP 08 / 13

실제 값 따라가기

같은 입력값이 어느 줄을 지나 어떤 결과가 되는지 추적합니다.

순서들어온 값코드가 하는 일나온 값·상태경계
F02-T01 사용자InternetTLS 443public ALBapp 8080 직접 공개 금지
F02-T02 applicationALB SGprivate 8080app target0.0.0.0/0 금지
F02-T03 databaseApp SGprivate 5432RDSpublic accessibility false
책임 경계
  1. 이 항목의 마지막 책임선은?

  2. 직접 역할은 `AWS network·administration 경계 template`이야.

  3. 대표 경계는 `cost gate 전에 cloud resource를 만들지 않는다`이야.

  4. 정본/비정본 label과 evidence owner까지 확인하면 끝이야.

09

STEP 09 / 13

GitHub·AWS·PowerShell·PostgreSQL 내부에서 벌어지는 일

GitHub·AWS·PowerShell·PostgreSQL에서 실제로 일어나는 일과 증명 범위를 구분합니다.

routing

public entry와 private workload subnet을 분리한다.

diagram은 실제 route table 검사가 아니다.
security group

stateful inbound source를 앞 SG로 제한한다.

NACL·egress 전체 설계는 별도다.
SSM

IAM과 agent/channel로 관리 session을 연다.

아무 IAM principal이나 접근할 수 있다는 뜻은 아니다.
10

STEP 10 / 13

흔한 착각과 틀린 예

그럴듯하지만 틀린 해석을 반례로 고칩니다.

❌ EC2 8080을 0.0.0.0/0에 연다

왜 틀리나 AWS network·administration 경계 template의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 ALB 443만 public으로 둔다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `diagram template은 실제 resource 생성 증거가 아니다` 상태인데도 Green을 주장하게 된다.

❌ RDS 5432를 개인 IP에 공개한다

왜 틀리나 AWS network·administration 경계 template의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 App 8080은 ALB SG에서만 허용한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `single-instance 학습 설계는 production HA가 아니다` 상태인데도 Green을 주장하게 된다.

❌ SSH 22를 관리 기본값으로 둔다

왜 틀리나 AWS network·administration 경계 template의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 RDS 5432는 App SG에서만 허용한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `RDS public accessibility false는 별도 확인이 필요하다` 상태인데도 Green을 주장하게 된다.

❌ 학습 single instance를 production HA라 부른다

왜 틀리나 AWS network·administration 경계 template의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 관리 접속은 inbound SSH 없이 SSM으로 한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `cost gate 전에 cloud resource를 만들지 않는다` 상태인데도 Green을 주장하게 된다.

❌ budget 없이 NAT·ALB·RDS를 만든다

왜 틀리나 AWS network·administration 경계 template의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 관리 접속은 inbound SSH 없이 SSM으로 한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `diagram template은 실제 resource 생성 증거가 아니다` 상태인데도 Green을 주장하게 된다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

이 코드가 책임지지 않는 일을 분리합니다.

직접 미보장

diagram template은 실제 resource 생성 증거가 아니다

이 책임을 맡는 곳: 별도 외부/selector 실행
직접 미보장

single-instance 학습 설계는 production HA가 아니다

이 책임을 맡는 곳: secret·운영 정책
직접 미보장

RDS public accessibility false는 별도 확인이 필요하다

이 책임을 맡는 곳: infrastructure·사람 검토
직접 미보장

cost gate 전에 cloud resource를 만들지 않는다

이 책임을 맡는 곳: owner lifecycle
12

STEP 12 / 13

직접 다시 써보기

뜻 → 조각 → 전체 코드 순서로 다시 씁니다.

1단계 · 뜻부터 복원

다음 역할을 고정값과 미보장 경계까지 말한다: public ALB 443에서 private app 8080과 private RDS 5432로 이어지는 SG-to-SG 최소 AWS 경계를 고정한다.

2단계 · 코드 조각 재조립

  1. 원문 1–10줄
  2. 원문 11–11줄

3단계 · 파일 전체 다시 쓰기

11개 물리 줄을 원본 순서로 복원하고 SHA-256 5c765a310a616e11f12ed8ed8ceefc4a1602b89f522021389635ea774f5a6287와 대조한다.

자가 점검
  • 원본 source/template bytes를 바꾸지 않았는가?
  • 외부 미실행과 local restore Green을 구분했는가?
  • secret 원문을 evidence에 남기지 않았는가?
  • D7 checked_at 충돌과 사람 검토 경계를 보았는가?
  • Q35/Q36을 workbook 정본 답안이라고 부르지 않았는가?
13

STEP 13 / 13

전체 원본 source

감사로 고정한 전체 source를 가감 없이 확인합니다.

학습용 예시 전체 확인하기 · 정본 답안 아님
학습용 예시 · PDF contract/template · 정본 답안 아님illustrative/text/W22-D2-architecture-rules.txtSHA-256 5c765a310a616e11f12ed8ed8ceefc4a1602b89f522021389635ea774f5a6287
AWS 경계 — public 443, private app·RDS, 관리 접속은 SSM 전체
학습용 예시 · PDF architecture template · 정본 답안 아님 · 그대로 실행 금지
Internet -> ALB:443 (public)
ALB SG -> App:8080 (private)
App SG -> RDS PostgreSQL:5432 (private)
Admin -> SSM Session Manager (no inbound SSH 22)
Secrets -> SSM Parameter Store or Secrets Manager
Logs/Metrics -> CloudWatch
security_group_rule: App inbound source is ALB SG, not 0.0.0.0/0.
database_rule: RDS public accessibility is false and inbound source is App SG only.
cost_boundary: account resource creation requires a budget and teardown plan first.
non_goal: single-instance learning deployment is not production HA, WAF, or full DR.
03

GitHub OIDC — 장기 key 대신 repo-bound 임시 AWS session

illustrative/yaml/W22-D3-oidc-workflow.yml

학습용 예시 · PDF YAML template · 정본 답안 아님 · 그대로 실행 금지 · 학습용 예시 · 정본 답안 아님 · W22-F03
13줄 연결13줄 번역2 chunks
01

STEP 01 / 13

오늘 이 코드에서 해결할 문제

무엇을 이해해야 하는지 질문부터 잡습니다.

오늘의 한 문장

GitHub OIDC token으로 짧은 AWS session을 받아 장기 access key 없이 deploy role identity부터 확인하는 workflow 골격이다.

  1. `id-token: write`은 어느 줄에서 생길까?
  2. 입력→guard→관찰→cleanup 순서는 무엇인가?
  3. local owner와 external human review는 누구인가?
  4. 직접 관찰하지 않은 Green은 무엇인가?
  5. 반례는 `sample account ID는 실제 값이 아니다`이라는 경계와 어떻게 연결되는가?
이 파일에서 끝까지 다시 쓰는 값id-token: writecontents: readconfigure-aws-credentials@v4ap-northeast-2sts get-caller-identity
02

STEP 02 / 13

아주 짧게: 이 코드는 왜 필요할까?

웹소설 대신 이 코드가 필요한 이유만 두 문단으로 쉽게 봅니다.

STARRY가 GitHub run표·AWS 출입증·DB 복구 영수증·SQL 결과표를 서로 다른 칸에 놓는다.

GitHub OIDC — 장기 key 대신 repo-bound 임시 AWS session ― 증거 흐름으로 바꾸기

GitHub OIDC token으로 짧은 AWS session을 받아 장기 access key 없이 deploy role identity부터 확인하는 workflow 골격이다.

핵심값 id-token: write, contents: read, configure-aws-credentials@v4, ap-northeast-2, sts get-caller-identity을 원본 줄로 따라가되, `sample account ID는 실제 값이 아니다`까지 함께 표시해 Green 범위를 부풀리지 않는다.

딱 여기까지만 비유는 owner와 순서를 기억하게 할 뿐 외부 실행·AWS 계정 상태·PostgreSQL restore·SQL 결과를 자동 증명하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

생활 비유와 실제 코드의 경계를 함께 확인합니다.

원문 1–10줄

1~10줄을 한 덩어리로 읽어 1번째 움직임을 본다. GitHub OIDC token으로 짧은 AWS session을 받아 장기 access key 없이 deploy role identity부터 확인하는 workflow 골격이다.

코드 연결
1~10줄
비유
창고 열쇠를 GitHub에 오래 보관하지 않고, 정확한 repo 행사표를 보여줄 때만 AWS가 짧은 방문증을 발급하는 방식
비유의 끝
sample account ID는 실제 값이 아니다

원문 11–13줄

11~13줄을 한 덩어리로 읽어 2번째 움직임을 본다. GitHub OIDC token으로 짧은 AWS session을 받아 장기 access key 없이 deploy role identity부터 확인하는 workflow 골격이다.

코드 연결
11~13줄
비유
창고 열쇠를 GitHub에 오래 보관하지 않고, 정확한 repo 행사표를 보여줄 때만 AWS가 짧은 방문증을 발급하는 방식
비유의 끝
trust sub를 repo와 branch/environment에 제한해야 한다
문제의 첫 장면
  1. 첫 고정값은 `id-token: write` 맞아?

  2. GitHub OIDC token으로 짧은 AWS session을 받아 장기 access key 없이 deploy role identity부터 확인하는 workflow 골격이다.

  3. 원문에서 `id-token: write`이 생기는 위치를 찾자.

  4. 그리고 `sample account ID는 실제 값이 아니다`도 같이 적어.

입력에서 결과까지
  1. `contents: read`은 언제 생겨?

  2. OIDC provider와 trust를 만든다. → repo·branch/environment sub를 제한한다.

  3. workflow가 role을 assume한다. → 첫 API로 STS caller identity를 확인한다.

  4. 관찰값과 `trust sub를 repo와 branch/environment에 제한해야 한다`을 분리하면 돼.

04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

감사 규칙상 연결 대상인 원본 13줄을 빠짐없이 연결합니다.

단어 몇 개만 뽑은 표가 아닙니다.학습용 예시 · PDF YAML template · 정본 답안 아님 · 그대로 실행 금지에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.13 / 13 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F03-L01 # 학습용 예시 · PDF OIDC template · 정본 답안 아님 · 그대로 실행 금지 창고 열쇠를 GitHub에 오래 보관하지 않고, 정확한 repo 행사표를 보여줄 때만 AWS가 짧은 방문증을 발급하는 방식 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
GitHub OIDC claims·AWS trust·deploy role
결과·효과
이 줄 뒤에는 항목 전체의 `id-token: write` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
sample account ID는 실제 값이 아니다
2줄F03-L02 permissions: 창고 열쇠를 GitHub에 오래 보관하지 않고, 정확한 repo 행사표를 보여줄 때만 AWS가 짧은 방문증을 발급하는 방식 GitHub OIDC 최소권한 workflow template에서 `permissions:` field·값 또는 assignment를 다음 단계에 전달한다.
입력
GitHub OIDC claims·AWS trust·deploy role
결과·효과
이 줄 뒤에는 항목 전체의 `contents: read` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
trust sub를 repo와 branch/environment에 제한해야 한다
3줄F03-L03 id-token: write 창고 열쇠를 GitHub에 오래 보관하지 않고, 정확한 repo 행사표를 보여줄 때만 AWS가 짧은 방문증을 발급하는 방식 GitHub job이 OIDC identity token을 요청할 최소 permission을 선언한다.
입력
GitHub OIDC claims·AWS trust·deploy role
결과·효과
이 줄 뒤에는 항목 전체의 `configure-aws-credentials@v4` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
AdministratorAccess를 허용하지 않는다
4줄F03-L04 contents: read 창고 열쇠를 GitHub에 오래 보관하지 않고, 정확한 repo 행사표를 보여줄 때만 AWS가 짧은 방문증을 발급하는 방식 GitHub OIDC 최소권한 workflow template에서 `contents: read` field·값 또는 assignment를 다음 단계에 전달한다.
입력
GitHub OIDC claims·AWS trust·deploy role
결과·효과
이 줄 뒤에는 항목 전체의 `ap-northeast-2` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
외부 assume-role 성공은 공식 run으로 검토한다
5줄F03-L05 steps: 창고 열쇠를 GitHub에 오래 보관하지 않고, 정확한 repo 행사표를 보여줄 때만 AWS가 짧은 방문증을 발급하는 방식 GitHub OIDC 최소권한 workflow template에서 `steps:` field·값 또는 assignment를 다음 단계에 전달한다.
입력
GitHub OIDC claims·AWS trust·deploy role
결과·효과
이 줄 뒤에는 항목 전체의 `sts get-caller-identity` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
sample account ID는 실제 값이 아니다
6줄F03-L06 - uses: aws-actions/configure-aws-credentials@v4 창고 열쇠를 GitHub에 오래 보관하지 않고, 정확한 repo 행사표를 보여줄 때만 AWS가 짧은 방문증을 발급하는 방식 GitHub OIDC token으로 AWS deploy role의 임시 session을 구성한다.
입력
GitHub OIDC claims·AWS trust·deploy role
결과·효과
이 줄 뒤에는 항목 전체의 `id-token: write` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
trust sub를 repo와 branch/environment에 제한해야 한다
7줄F03-L07 with: 창고 열쇠를 GitHub에 오래 보관하지 않고, 정확한 repo 행사표를 보여줄 때만 AWS가 짧은 방문증을 발급하는 방식 GitHub OIDC 최소권한 workflow template에서 `with:` field·값 또는 assignment를 다음 단계에 전달한다.
입력
GitHub OIDC claims·AWS trust·deploy role
결과·효과
이 줄 뒤에는 항목 전체의 `contents: read` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
AdministratorAccess를 허용하지 않는다
8줄F03-L08 role-to-assume: arn:aws:iam::123456789012:role/fcl-github-deploy 창고 열쇠를 GitHub에 오래 보관하지 않고, 정확한 repo 행사표를 보여줄 때만 AWS가 짧은 방문증을 발급하는 방식 GitHub OIDC 최소권한 workflow template에서 `role-to-assume: arn:aws:iam::123456789012:role/f` field·값 또는 assignment를 다음 단계에 전달한다.
입력
GitHub OIDC claims·AWS trust·deploy role
결과·효과
이 줄 뒤에는 항목 전체의 `configure-aws-credentials@v4` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
외부 assume-role 성공은 공식 run으로 검토한다
9줄F03-L09 aws-region: ap-northeast-2 창고 열쇠를 GitHub에 오래 보관하지 않고, 정확한 repo 행사표를 보여줄 때만 AWS가 짧은 방문증을 발급하는 방식 GitHub OIDC 최소권한 workflow template에서 `aws-region: ap-northeast-2` field·값 또는 assignment를 다음 단계에 전달한다.
입력
GitHub OIDC claims·AWS trust·deploy role
결과·효과
이 줄 뒤에는 항목 전체의 `ap-northeast-2` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
sample account ID는 실제 값이 아니다
10줄F03-L10 - run: aws sts get-caller-identity 창고 열쇠를 GitHub에 오래 보관하지 않고, 정확한 repo 행사표를 보여줄 때만 AWS가 짧은 방문증을 발급하는 방식 현재 AWS session이 의도한 caller인지 먼저 관찰한다.
입력
GitHub OIDC claims·AWS trust·deploy role
결과·효과
이 줄 뒤에는 항목 전체의 `sts get-caller-identity` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
trust sub를 repo와 branch/environment에 제한해야 한다
11줄F03-L11 # 실제 trust policy는 정확한 repository와 main 또는 승인 environment의 sub claim으로 제한한다. 창고 열쇠를 GitHub에 오래 보관하지 않고, 정확한 repo 행사표를 보여줄 때만 AWS가 짧은 방문증을 발급하는 방식 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
GitHub OIDC claims·AWS trust·deploy role
결과·효과
이 줄 뒤에는 항목 전체의 `id-token: write` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
AdministratorAccess를 허용하지 않는다
12줄F03-L12 # AWS_ACCESS_KEY_ID·AWS_SECRET_ACCESS_KEY 같은 장기 정적 key를 workflow secret에 저장하지 않는다. 창고 열쇠를 GitHub에 오래 보관하지 않고, 정확한 repo 행사표를 보여줄 때만 AWS가 짧은 방문증을 발급하는 방식 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
GitHub OIDC claims·AWS trust·deploy role
결과·효과
이 줄 뒤에는 항목 전체의 `contents: read` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
외부 assume-role 성공은 공식 run으로 검토한다
13줄F03-L13 # 이 조각은 외부 assume-role 성공을 증명하지 않으며 공식 run 증거는 MANUAL_REVIEW_REQUIRED다. 창고 열쇠를 GitHub에 오래 보관하지 않고, 정확한 repo 행사표를 보여줄 때만 AWS가 짧은 방문증을 발급하는 방식 자동 shape/hash 검사 뒤에도 사람의 의미 검토가 남았음을 고정한다.
입력
GitHub OIDC claims·AWS trust·deploy role
결과·효과
이 줄 뒤에는 항목 전체의 `configure-aws-credentials@v4` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
sample account ID는 실제 값이 아니다
Green 범위
  1. marker나 파일이 보이면 전부 성공이야?

  2. 아니. source가 직접 검증한 범위만 말해야 해.

  3. 직접 연결되는 대표 값은 `sts get-caller-identity`이야.

  4. `AdministratorAccess를 허용하지 않는다`는 별도 증거가 필요해.

05

STEP 05 / 13

원본 코드 조각

원본을 2개 의미 조각으로 나누어 그대로 확인합니다.

파일을 한꺼번에 외우지 않고 실행 의미가 이어지는 작은 조각으로 봅니다. 아래 코드는 prompt·fixture·가정을 밝힌 학습용 예시 source이며, 제공 정본 답안이 아닙니다.

F03-C01 · 원문 1–10줄1–10줄
1–10줄 원본
# 학습용 예시 · PDF OIDC template · 정본 답안 아님 · 그대로 실행 금지
permissions:
  id-token: write
  contents: read
steps:
  - uses: aws-actions/configure-aws-credentials@v4
    with:
      role-to-assume: arn:aws:iam::123456789012:role/fcl-github-deploy
      aws-region: ap-northeast-2
  - run: aws sts get-caller-identity
F03-C02 · 원문 11–13줄11–13줄
11–13줄 원본
# 실제 trust policy는 정확한 repository와 main 또는 승인 environment의 sub claim으로 제한한다.
# AWS_ACCESS_KEY_ID·AWS_SECRET_ACCESS_KEY 같은 장기 정적 key를 workflow secret에 저장하지 않는다.
# 이 조각은 외부 assume-role 성공을 증명하지 않으며 공식 run 증거는 MANUAL_REVIEW_REQUIRED다.
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

비어 있지 않은 13줄을 모두 한국어로 옮깁니다.

전체 번역 13 / 13

비어 있지 않은 원본 줄은 하나도 생략하지 않습니다.

원본한국어 번역
1# 학습용 예시 · PDF OIDC template · 정본 답안 아님 · 그대로 실행 금지이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
2permissions:GitHub OIDC 최소권한 workflow template에서 `permissions:` field·값 또는 assignment를 다음 단계에 전달한다.
3 id-token: writeGitHub job이 OIDC identity token을 요청할 최소 permission을 선언한다.
4 contents: readGitHub OIDC 최소권한 workflow template에서 `contents: read` field·값 또는 assignment를 다음 단계에 전달한다.
5steps:GitHub OIDC 최소권한 workflow template에서 `steps:` field·값 또는 assignment를 다음 단계에 전달한다.
6 - uses: aws-actions/configure-aws-credentials@v4GitHub OIDC token으로 AWS deploy role의 임시 session을 구성한다.
7 with:GitHub OIDC 최소권한 workflow template에서 `with:` field·값 또는 assignment를 다음 단계에 전달한다.
8 role-to-assume: arn:aws:iam::123456789012:role/fcl-github-deployGitHub OIDC 최소권한 workflow template에서 `role-to-assume: arn:aws:iam::123456789012:role/f` field·값 또는 assignment를 다음 단계에 전달한다.
9 aws-region: ap-northeast-2GitHub OIDC 최소권한 workflow template에서 `aws-region: ap-northeast-2` field·값 또는 assignment를 다음 단계에 전달한다.
10 - run: aws sts get-caller-identity현재 AWS session이 의도한 caller인지 먼저 관찰한다.
11# 실제 trust policy는 정확한 repository와 main 또는 승인 environment의 sub claim으로 제한한다.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
12# AWS_ACCESS_KEY_ID·AWS_SECRET_ACCESS_KEY 같은 장기 정적 key를 workflow secret에 저장하지 않는다.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
13# 이 조각은 외부 assume-role 성공을 증명하지 않으며 공식 run 증거는 MANUAL_REVIEW_REQUIRED다.자동 shape/hash 검사 뒤에도 사람의 의미 검토가 남았음을 고정한다.
07

STEP 07 / 13

기존 수준의 한 줄 읽기·문법 해부

쉬운 설명 다음에 문법과 실행 순서를 정밀하게 읽습니다.

한 줄로 읽기

GitHub OIDC token으로 짧은 AWS session을 받아 장기 access key 없이 deploy role identity부터 확인하는 workflow 골격이다. 다만 sample account ID는 실제 값이 아니다

문법 해부

  • `permissions.id-token: write`가 GitHub OIDC token 발급을 허용한다.
  • `role-to-assume`와 trust `sub` 조건은 workflow 쪽과 AWS 쪽을 함께 묶어야 한다.

실행 순서

  1. OIDC provider와 trust를 만든다.
  2. repo·branch/environment sub를 제한한다.
  3. workflow가 role을 assume한다.
  4. 첫 API로 STS caller identity를 확인한다.

W22 조각별 정밀 해설

F03-C01 · 원문 1–10줄
문법 해부
1~10줄의 `원문 1–10줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `id-token: write`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `id-token: write`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: sample account ID는 실제 값이 아니다.
착각 방지
`원문 1–10줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: sample account ID는 실제 값이 아니다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F03-C02 · 원문 11–13줄
문법 해부
11~13줄의 `원문 11–13줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `contents: read`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `contents: read`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: trust sub를 repo와 branch/environment에 제한해야 한다.
착각 방지
`원문 11–13줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: trust sub를 repo와 branch/environment에 제한해야 한다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
반례
  1. 겉보기에는 맞지만 깨지는 예는?

  2. AWS_ACCESS_KEY_ID를 repository secret에 장기 보관한다

  3. 그 상태는 owner·입력·관찰 중 한 칸이 비어 있어.

  4. 수정한 뒤 같은 source와 hash로 다시 대조해.

08

STEP 08 / 13

실제 값 따라가기

같은 입력값이 어느 줄을 지나 어떤 결과가 되는지 추적합니다.

순서들어온 값코드가 하는 일나온 값·상태경계
F03-T01 tokenapproved workflowOIDC 발급short-lived assertionAWS key가 아님
F03-T02 assumetoken claimstrust policytemporary sessionrepo wildcard 금지
F03-T03 probesessionsts identityassumed roledeploy 권한 전체 Green 아님
책임 경계
  1. 이 항목의 마지막 책임선은?

  2. 직접 역할은 `GitHub OIDC 최소권한 workflow template`이야.

  3. 대표 경계는 `외부 assume-role 성공은 공식 run으로 검토한다`이야.

  4. 정본/비정본 label과 evidence owner까지 확인하면 끝이야.

09

STEP 09 / 13

GitHub·AWS·PowerShell·PostgreSQL 내부에서 벌어지는 일

GitHub·AWS·PowerShell·PostgreSQL에서 실제로 일어나는 일과 증명 범위를 구분합니다.

GitHub

job identity claim을 서명된 token으로 만든다.

id-token write가 contents write를 뜻하지 않는다.
AWS STS

trust가 맞을 때 임시 credential을 발급한다.

policy action은 별도 최소화가 필요하다.
IAM

trust policy와 permission policy가 각각 who와 what을 제한한다.

AdministratorAccess는 최소권한이 아니다.
10

STEP 10 / 13

흔한 착각과 틀린 예

그럴듯하지만 틀린 해석을 반례로 고칩니다.

❌ AWS_ACCESS_KEY_ID를 repository secret에 장기 보관한다

왜 틀리나 GitHub OIDC 최소권한 workflow template의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 OIDC provider와 trust를 만든다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `sample account ID는 실제 값이 아니다` 상태인데도 Green을 주장하게 된다.

❌ trust sub에 모든 repository wildcard를 쓴다

왜 틀리나 GitHub OIDC 최소권한 workflow template의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 repo·branch/environment sub를 제한한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `trust sub를 repo와 branch/environment에 제한해야 한다` 상태인데도 Green을 주장하게 된다.

❌ AdministratorAccess로 먼저 통과시킨다

왜 틀리나 GitHub OIDC 최소권한 workflow template의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 workflow가 role을 assume한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `AdministratorAccess를 허용하지 않는다` 상태인데도 Green을 주장하게 된다.

❌ sample account ID를 실제 role ARN처럼 쓴다

왜 틀리나 GitHub OIDC 최소권한 workflow template의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 첫 API로 STS caller identity를 확인한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `외부 assume-role 성공은 공식 run으로 검토한다` 상태인데도 Green을 주장하게 된다.

❌ STS identity 성공을 배포 전체 Green으로 부른다

왜 틀리나 GitHub OIDC 최소권한 workflow template의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 첫 API로 STS caller identity를 확인한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `sample account ID는 실제 값이 아니다` 상태인데도 Green을 주장하게 된다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

이 코드가 책임지지 않는 일을 분리합니다.

직접 미보장

sample account ID는 실제 값이 아니다

이 책임을 맡는 곳: 별도 외부/selector 실행
직접 미보장

trust sub를 repo와 branch/environment에 제한해야 한다

이 책임을 맡는 곳: secret·운영 정책
직접 미보장

AdministratorAccess를 허용하지 않는다

이 책임을 맡는 곳: infrastructure·사람 검토
직접 미보장

외부 assume-role 성공은 공식 run으로 검토한다

이 책임을 맡는 곳: owner lifecycle
12

STEP 12 / 13

직접 다시 써보기

뜻 → 조각 → 전체 코드 순서로 다시 씁니다.

1단계 · 뜻부터 복원

다음 역할을 고정값과 미보장 경계까지 말한다: GitHub OIDC token으로 짧은 AWS session을 받아 장기 access key 없이 deploy role identity부터 확인하는 workflow 골격이다.

2단계 · 코드 조각 재조립

  1. 원문 1–10줄
  2. 원문 11–13줄

3단계 · 파일 전체 다시 쓰기

13개 물리 줄을 원본 순서로 복원하고 SHA-256 00c9735277fe975fe6304610dc3856d41ed2ccd390793ca286a8526d122a05d6와 대조한다.

자가 점검
  • 원본 source/template bytes를 바꾸지 않았는가?
  • 외부 미실행과 local restore Green을 구분했는가?
  • secret 원문을 evidence에 남기지 않았는가?
  • D7 checked_at 충돌과 사람 검토 경계를 보았는가?
  • Q35/Q36을 workbook 정본 답안이라고 부르지 않았는가?
13

STEP 13 / 13

전체 원본 source

감사로 고정한 전체 source를 가감 없이 확인합니다.

학습용 예시 전체 확인하기 · 정본 답안 아님
학습용 예시 · PDF YAML template · 정본 답안 아님 · 그대로 실행 금지illustrative/yaml/W22-D3-oidc-workflow.ymlSHA-256 00c9735277fe975fe6304610dc3856d41ed2ccd390793ca286a8526d122a05d6
GitHub OIDC — 장기 key 대신 repo-bound 임시 AWS session 전체
# 학습용 예시 · PDF OIDC template · 정본 답안 아님 · 그대로 실행 금지
permissions:
  id-token: write
  contents: read
steps:
  - uses: aws-actions/configure-aws-credentials@v4
    with:
      role-to-assume: arn:aws:iam::123456789012:role/fcl-github-deploy
      aws-region: ap-northeast-2
  - run: aws sts get-caller-identity
# 실제 trust policy는 정확한 repository와 main 또는 승인 environment의 sub claim으로 제한한다.
# AWS_ACCESS_KEY_ID·AWS_SECRET_ACCESS_KEY 같은 장기 정적 key를 workflow secret에 저장하지 않는다.
# 이 조각은 외부 assume-role 성공을 증명하지 않으며 공식 run 증거는 MANUAL_REVIEW_REQUIRED다.
04

배포 manifest — commit·immutable digest·실제 migration inventory 연결

illustrative/json/W22-D4-deployment-manifest.json

학습용 예시 · PDF JSON schema/worksheet · 정본 답안 아님 · 비실행 · 학습용 예시 · 정본 답안 아님 · W22-F04
21줄 연결21줄 번역3 chunks
01

STEP 01 / 13

오늘 이 코드에서 해결할 문제

무엇을 이해해야 하는지 질문부터 잡습니다.

오늘의 한 문장

source commit·immutable image digest·실제 Flyway migration inventory hash를 한 manifest에 연결하는 비실행 schema다.

  1. `40-char git SHA`은 어느 줄에서 생길까?
  2. 입력→guard→관찰→cleanup 순서는 무엇인가?
  3. local owner와 external human review는 누구인가?
  4. 직접 관찰하지 않은 Green은 무엇인가?
  5. 반례는 `0과 example 값은 실제 배포 증거가 아니다`이라는 경계와 어떻게 연결되는가?
이 파일에서 끝까지 다시 쓰는 값40-char git SHArepository@sha256Java 21V001/V019 expected scriptsMANUAL_REVIEW_REQUIRED
02

STEP 02 / 13

아주 짧게: 이 코드는 왜 필요할까?

웹소설 대신 이 코드가 필요한 이유만 두 문단으로 쉽게 봅니다.

STARRY가 GitHub run표·AWS 출입증·DB 복구 영수증·SQL 결과표를 서로 다른 칸에 놓는다.

배포 manifest — commit·immutable digest·실제 migration inventory 연결 ― 증거 흐름으로 바꾸기

source commit·immutable image digest·실제 Flyway migration inventory hash를 한 manifest에 연결하는 비실행 schema다.

핵심값 40-char git SHA, repository@sha256, Java 21, V001/V019 expected scripts, MANUAL_REVIEW_REQUIRED을 원본 줄로 따라가되, `0과 example 값은 실제 배포 증거가 아니다`까지 함께 표시해 Green 범위를 부풀리지 않는다.

딱 여기까지만 비유는 owner와 순서를 기억하게 할 뿐 외부 실행·AWS 계정 상태·PostgreSQL restore·SQL 결과를 자동 증명하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

생활 비유와 실제 코드의 경계를 함께 확인합니다.

원문 1–10줄

1~10줄을 한 덩어리로 읽어 1번째 움직임을 본다. source commit·immutable image digest·실제 Flyway migration inventory hash를 한 manifest에 연결하는 비실행 schema다.

코드 연결
1~10줄
비유
상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표
비유의 끝
0과 example 값은 실제 배포 증거가 아니다

원문 11–20줄

11~20줄을 한 덩어리로 읽어 2번째 움직임을 본다. source commit·immutable image digest·실제 Flyway migration inventory hash를 한 manifest에 연결하는 비실행 schema다.

코드 연결
11~20줄
비유
상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표
비유의 끝
V001/V019는 packaged reference 예상값일 뿐 실제 history를 읽어야 한다

원문 21–21줄

21~21줄을 한 덩어리로 읽어 3번째 움직임을 본다. source commit·immutable image digest·실제 Flyway migration inventory hash를 한 manifest에 연결하는 비실행 schema다.

코드 연결
21~21줄
비유
상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표
비유의 끝
generic hash 검사는 값의 의미를 증명하지 않는다
문제의 첫 장면
  1. 첫 고정값은 `40-char git SHA` 맞아?

  2. source commit·immutable image digest·실제 Flyway migration inventory hash를 한 manifest에 연결하는 비실행 schema다.

  3. 원문에서 `40-char git SHA`이 생기는 위치를 찾자.

  4. 그리고 `0과 example 값은 실제 배포 증거가 아니다`도 같이 적어.

입력에서 결과까지
  1. `repository@sha256`은 언제 생겨?

  2. 실제 git SHA를 읽는다. → registry immutable digest를 읽는다.

  3. DB schema history를 export한다. → inventory file hash와 manual status를 manifest에 쓴다.

  4. 관찰값과 `V001/V019는 packaged reference 예상값일 뿐 실제 history를 읽어야 한다`을 분리하면 돼.

04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

감사 규칙상 연결 대상인 원본 21줄을 빠짐없이 연결합니다.

단어 몇 개만 뽑은 표가 아닙니다.학습용 예시 · PDF JSON schema/worksheet · 정본 답안 아님 · 비실행에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.21 / 21 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F04-L01 { 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `40-char git SHA` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
0과 example 값은 실제 배포 증거가 아니다
2줄F04-L02 "_provenance": "학습용 예시 · PDF manifest schema · 정본 답안 아님 · 비실행", 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 immutable 배포 provenance manifest schema에서 `"_provenance": "학습용 예시 · PDF manifest schema · 정` field·값 또는 assignment를 다음 단계에 전달한다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `repository@sha256` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
V001/V019는 packaged reference 예상값일 뿐 실제 history를 읽어야 한다
3줄F04-L03 "gitSha": "0000000000000000000000000000000000000000", 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 배포 source snapshot을 실제 40-hex commit SHA field에 연결한다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `Java 21` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
generic hash 검사는 값의 의미를 증명하지 않는다
4줄F04-L04 "image": "example.invalid/financial-core@sha256:0000000000000000000000000000000000000000000000000000000000000000", 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 현재 file bytes를 64-hex SHA-256 값과 결박하는 field 또는 검사를 다룬다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `V001/V019 expected scripts` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
latest tag만으로 배포 provenance를 닫지 않는다
5줄F04-L05 "java": "21", 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 immutable 배포 provenance manifest schema에서 `"java": "21",` field·값 또는 assignment를 다음 단계에 전달한다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `MANUAL_REVIEW_REQUIRED` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
0과 example 값은 실제 배포 증거가 아니다
6줄F04-L06 "springBoot": "4.1.0", 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 immutable 배포 provenance manifest schema에서 `"springBoot": "4.1.0",` field·값 또는 assignment를 다음 단계에 전달한다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `40-char git SHA` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
V001/V019는 packaged reference 예상값일 뿐 실제 history를 읽어야 한다
7줄F04-L07 "dbMigrations": [ 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 실제 schema history에서 읽을 migration inventory 배열을 연다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `repository@sha256` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
generic hash 검사는 값의 의미를 증명하지 않는다
8줄F04-L08 { 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `Java 21` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
latest tag만으로 배포 provenance를 닫지 않는다
9줄F04-L09 "version": "001", 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 immutable 배포 provenance manifest schema에서 `"version": "001",` field·값 또는 assignment를 다음 단계에 전달한다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `V001/V019 expected scripts` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
0과 example 값은 실제 배포 증거가 아니다
10줄F04-L10 "script": "V001__common.sql", 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 immutable 배포 provenance manifest schema에서 `"script": "V001__common.sql",` field·값 또는 assignment를 다음 단계에 전달한다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `MANUAL_REVIEW_REQUIRED` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
V001/V019는 packaged reference 예상값일 뿐 실제 history를 읽어야 한다
11줄F04-L11 "checksum": "EXAMPLE_FLYWAY_CHECKSUM" 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 immutable 배포 provenance manifest schema에서 `"checksum": "EXAMPLE_FLYWAY_CHECKSUM"` field·값 또는 assignment를 다음 단계에 전달한다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `40-char git SHA` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
generic hash 검사는 값의 의미를 증명하지 않는다
12줄F04-L12 }, 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `repository@sha256` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
latest tag만으로 배포 provenance를 닫지 않는다
13줄F04-L13 { 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `Java 21` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
0과 example 값은 실제 배포 증거가 아니다
14줄F04-L14 "version": "019", 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 immutable 배포 provenance manifest schema에서 `"version": "019",` field·값 또는 assignment를 다음 단계에 전달한다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `V001/V019 expected scripts` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
V001/V019는 packaged reference 예상값일 뿐 실제 history를 읽어야 한다
15줄F04-L15 "script": "V019__audit.sql", 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 immutable 배포 provenance manifest schema에서 `"script": "V019__audit.sql",` field·값 또는 assignment를 다음 단계에 전달한다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `MANUAL_REVIEW_REQUIRED` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
generic hash 검사는 값의 의미를 증명하지 않는다
16줄F04-L16 "checksum": "EXAMPLE_FLYWAY_CHECKSUM" 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 immutable 배포 provenance manifest schema에서 `"checksum": "EXAMPLE_FLYWAY_CHECKSUM"` field·값 또는 assignment를 다음 단계에 전달한다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `40-char git SHA` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
latest tag만으로 배포 provenance를 닫지 않는다
17줄F04-L17 } 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `repository@sha256` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
0과 example 값은 실제 배포 증거가 아니다
18줄F04-L18 ], 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `Java 21` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
V001/V019는 packaged reference 예상값일 뿐 실제 history를 읽어야 한다
19줄F04-L19 "dbMigrationInventorySha256": "0000000000000000000000000000000000000000000000000000000000000000", 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 현재 file bytes를 64-hex SHA-256 값과 결박하는 field 또는 검사를 다룬다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `V001/V019 expected scripts` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
generic hash 검사는 값의 의미를 증명하지 않는다
20줄F04-L20 "verificationStatus": "MANUAL_REVIEW_REQUIRED" 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 자동 shape/hash 검사 뒤에도 사람의 의미 검토가 남았음을 고정한다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `MANUAL_REVIEW_REQUIRED` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
latest tag만으로 배포 provenance를 닫지 않는다
21줄F04-L21 } 상품의 원재료 commit, 밀봉 번호 digest, 사용한 조리법 migration 목록을 한 영수증에 묶는 배포 추적표 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
git commit·registry digest·Flyway schema history
결과·효과
이 줄 뒤에는 항목 전체의 `40-char git SHA` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
0과 example 값은 실제 배포 증거가 아니다
Green 범위
  1. marker나 파일이 보이면 전부 성공이야?

  2. 아니. source가 직접 검증한 범위만 말해야 해.

  3. 직접 연결되는 대표 값은 `MANUAL_REVIEW_REQUIRED`이야.

  4. `generic hash 검사는 값의 의미를 증명하지 않는다`는 별도 증거가 필요해.

05

STEP 05 / 13

원본 코드 조각

원본을 3개 의미 조각으로 나누어 그대로 확인합니다.

파일을 한꺼번에 외우지 않고 실행 의미가 이어지는 작은 조각으로 봅니다. 아래 코드는 prompt·fixture·가정을 밝힌 학습용 예시 source이며, 제공 정본 답안이 아닙니다.

F04-C01 · 원문 1–10줄1–10줄
1–10줄 원본
{
  "_provenance": "학습용 예시 · PDF manifest schema · 정본 답안 아님 · 비실행",
  "gitSha": "0000000000000000000000000000000000000000",
  "image": "example.invalid/financial-core@sha256:0000000000000000000000000000000000000000000000000000000000000000",
  "java": "21",
  "springBoot": "4.1.0",
  "dbMigrations": [
    {
      "version": "001",
      "script": "V001__common.sql",
F04-C02 · 원문 11–20줄11–20줄
11–20줄 원본
      "checksum": "EXAMPLE_FLYWAY_CHECKSUM"
    },
    {
      "version": "019",
      "script": "V019__audit.sql",
      "checksum": "EXAMPLE_FLYWAY_CHECKSUM"
    }
  ],
  "dbMigrationInventorySha256": "0000000000000000000000000000000000000000000000000000000000000000",
  "verificationStatus": "MANUAL_REVIEW_REQUIRED"
F04-C03 · 원문 21–21줄21–21줄
21–21줄 원본
}
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

비어 있지 않은 21줄을 모두 한국어로 옮깁니다.

전체 번역 21 / 21

비어 있지 않은 원본 줄은 하나도 생략하지 않습니다.

원본한국어 번역
1{현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
2 "_provenance": "학습용 예시 · PDF manifest schema · 정본 답안 아님 · 비실행",immutable 배포 provenance manifest schema에서 `"_provenance": "학습용 예시 · PDF manifest schema · 정` field·값 또는 assignment를 다음 단계에 전달한다.
3 "gitSha": "0000000000000000000000000000000000000000",배포 source snapshot을 실제 40-hex commit SHA field에 연결한다.
4 "image": "example.invalid/financial-core@sha256:0000000000000000000000000000000000000000000000000000000000000000",현재 file bytes를 64-hex SHA-256 값과 결박하는 field 또는 검사를 다룬다.
5 "java": "21",immutable 배포 provenance manifest schema에서 `"java": "21",` field·값 또는 assignment를 다음 단계에 전달한다.
6 "springBoot": "4.1.0",immutable 배포 provenance manifest schema에서 `"springBoot": "4.1.0",` field·값 또는 assignment를 다음 단계에 전달한다.
7 "dbMigrations": [실제 schema history에서 읽을 migration inventory 배열을 연다.
8 {현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
9 "version": "001",immutable 배포 provenance manifest schema에서 `"version": "001",` field·값 또는 assignment를 다음 단계에 전달한다.
10 "script": "V001__common.sql",immutable 배포 provenance manifest schema에서 `"script": "V001__common.sql",` field·값 또는 assignment를 다음 단계에 전달한다.
11 "checksum": "EXAMPLE_FLYWAY_CHECKSUM"immutable 배포 provenance manifest schema에서 `"checksum": "EXAMPLE_FLYWAY_CHECKSUM"` field·값 또는 assignment를 다음 단계에 전달한다.
12 },현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
13 {현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
14 "version": "019",immutable 배포 provenance manifest schema에서 `"version": "019",` field·값 또는 assignment를 다음 단계에 전달한다.
15 "script": "V019__audit.sql",immutable 배포 provenance manifest schema에서 `"script": "V019__audit.sql",` field·값 또는 assignment를 다음 단계에 전달한다.
16 "checksum": "EXAMPLE_FLYWAY_CHECKSUM"immutable 배포 provenance manifest schema에서 `"checksum": "EXAMPLE_FLYWAY_CHECKSUM"` field·값 또는 assignment를 다음 단계에 전달한다.
17 }현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
18 ],현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
19 "dbMigrationInventorySha256": "0000000000000000000000000000000000000000000000000000000000000000",현재 file bytes를 64-hex SHA-256 값과 결박하는 field 또는 검사를 다룬다.
20 "verificationStatus": "MANUAL_REVIEW_REQUIRED"자동 shape/hash 검사 뒤에도 사람의 의미 검토가 남았음을 고정한다.
21}현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
07

STEP 07 / 13

기존 수준의 한 줄 읽기·문법 해부

쉬운 설명 다음에 문법과 실행 순서를 정밀하게 읽습니다.

한 줄로 읽기

source commit·immutable image digest·실제 Flyway migration inventory hash를 한 manifest에 연결하는 비실행 schema다. 다만 0과 example 값은 실제 배포 증거가 아니다

문법 해부

  • JSON object는 source·image·DB inventory field를 한 receipt에 묶는다.
  • image는 mutable tag가 아니라 `repository@sha256:digest` 모양으로 고정한다.

실행 순서

  1. 실제 git SHA를 읽는다.
  2. registry immutable digest를 읽는다.
  3. DB schema history를 export한다.
  4. inventory file hash와 manual status를 manifest에 쓴다.

W22 조각별 정밀 해설

F04-C01 · 원문 1–10줄
문법 해부
1~10줄의 `원문 1–10줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `40-char git SHA`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `40-char git SHA`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: 0과 example 값은 실제 배포 증거가 아니다.
착각 방지
`원문 1–10줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: 0과 example 값은 실제 배포 증거가 아니다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F04-C02 · 원문 11–20줄
문법 해부
11~20줄의 `원문 11–20줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `repository@sha256`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `repository@sha256`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: V001/V019는 packaged reference 예상값일 뿐 실제 history를 읽어야 한다.
착각 방지
`원문 11–20줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: V001/V019는 packaged reference 예상값일 뿐 실제 history를 읽어야 한다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F04-C03 · 원문 21–21줄
문법 해부
21~21줄의 `원문 21–21줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `Java 21`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `Java 21`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: generic hash 검사는 값의 의미를 증명하지 않는다.
착각 방지
`원문 21–21줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: generic hash 검사는 값의 의미를 증명하지 않는다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
반례
  1. 겉보기에는 맞지만 깨지는 예는?

  2. latest tag만 기록한다

  3. 그 상태는 owner·입력·관찰 중 한 칸이 비어 있어.

  4. 수정한 뒤 같은 source와 hash로 다시 대조해.

08

STEP 08 / 13

실제 값 따라가기

같은 입력값이 어느 줄을 지나 어떤 결과가 되는지 추적합니다.

순서들어온 값코드가 하는 일나온 값·상태경계
F04-T01 sourcecommit40-hex recordgitSha0 예시는 미실행
F04-T02 imageregistry resultdigest bindrepository@sha256latest tag 불충분
F04-T03 databaseflyway historyinventory+hashversions/scripts/checksums예상 V001/V019와 실제값 구분
책임 경계
  1. 이 항목의 마지막 책임선은?

  2. 직접 역할은 `immutable 배포 provenance manifest schema`이야.

  3. 대표 경계는 `latest tag만으로 배포 provenance를 닫지 않는다`이야.

  4. 정본/비정본 label과 evidence owner까지 확인하면 끝이야.

09

STEP 09 / 13

GitHub·AWS·PowerShell·PostgreSQL 내부에서 벌어지는 일

GitHub·AWS·PowerShell·PostgreSQL에서 실제로 일어나는 일과 증명 범위를 구분합니다.

Git

commit SHA가 source snapshot을 가리킨다.

미커밋 파일은 포함하지 않는다.
OCI registry

digest가 image content 주소가 된다.

signature·SBOM까지 자동 검증하지 않는다.
Flyway

schema history가 실제 적용 version·script·checksum을 가진다.

JSON 예시 목록을 복사하면 live DB proof가 아니다.
10

STEP 10 / 13

흔한 착각과 틀린 예

그럴듯하지만 틀린 해석을 반례로 고칩니다.

❌ latest tag만 기록한다

왜 틀리나 immutable 배포 provenance manifest schema의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 실제 git SHA를 읽는다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `0과 example 값은 실제 배포 증거가 아니다` 상태인데도 Green을 주장하게 된다.

❌ git SHA 대신 branch 이름만 쓴다

왜 틀리나 immutable 배포 provenance manifest schema의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 registry immutable digest를 읽는다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `V001/V019는 packaged reference 예상값일 뿐 실제 history를 읽어야 한다` 상태인데도 Green을 주장하게 된다.

❌ migration을 오래된 V5로 고정한다

왜 틀리나 immutable 배포 provenance manifest schema의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 DB schema history를 export한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `generic hash 검사는 값의 의미를 증명하지 않는다` 상태인데도 Green을 주장하게 된다.

❌ inventory path 없이 hash만 적는다

왜 틀리나 immutable 배포 provenance manifest schema의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 inventory file hash와 manual status를 manifest에 쓴다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `latest tag만으로 배포 provenance를 닫지 않는다` 상태인데도 Green을 주장하게 된다.

❌ 파일 hash가 맞으면 의미도 맞다고 본다

왜 틀리나 immutable 배포 provenance manifest schema의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 inventory file hash와 manual status를 manifest에 쓴다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `0과 example 값은 실제 배포 증거가 아니다` 상태인데도 Green을 주장하게 된다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

이 코드가 책임지지 않는 일을 분리합니다.

직접 미보장

0과 example 값은 실제 배포 증거가 아니다

이 책임을 맡는 곳: 별도 외부/selector 실행
직접 미보장

V001/V019는 packaged reference 예상값일 뿐 실제 history를 읽어야 한다

이 책임을 맡는 곳: secret·운영 정책
직접 미보장

generic hash 검사는 값의 의미를 증명하지 않는다

이 책임을 맡는 곳: infrastructure·사람 검토
직접 미보장

latest tag만으로 배포 provenance를 닫지 않는다

이 책임을 맡는 곳: owner lifecycle
12

STEP 12 / 13

직접 다시 써보기

뜻 → 조각 → 전체 코드 순서로 다시 씁니다.

1단계 · 뜻부터 복원

다음 역할을 고정값과 미보장 경계까지 말한다: source commit·immutable image digest·실제 Flyway migration inventory hash를 한 manifest에 연결하는 비실행 schema다.

2단계 · 코드 조각 재조립

  1. 원문 1–10줄
  2. 원문 11–20줄
  3. 원문 21–21줄

3단계 · 파일 전체 다시 쓰기

21개 물리 줄을 원본 순서로 복원하고 SHA-256 033ffaf3e3593b697c693a87913886c51fbcfb0b2fd82508215b146e6c421418와 대조한다.

자가 점검
  • 원본 source/template bytes를 바꾸지 않았는가?
  • 외부 미실행과 local restore Green을 구분했는가?
  • secret 원문을 evidence에 남기지 않았는가?
  • D7 checked_at 충돌과 사람 검토 경계를 보았는가?
  • Q35/Q36을 workbook 정본 답안이라고 부르지 않았는가?
13

STEP 13 / 13

전체 원본 source

감사로 고정한 전체 source를 가감 없이 확인합니다.

학습용 예시 전체 확인하기 · 정본 답안 아님
학습용 예시 · PDF JSON schema/worksheet · 정본 답안 아님 · 비실행illustrative/json/W22-D4-deployment-manifest.jsonSHA-256 033ffaf3e3593b697c693a87913886c51fbcfb0b2fd82508215b146e6c421418
배포 manifest — commit·immutable digest·실제 migration inventory 연결 전체
{
  "_provenance": "학습용 예시 · PDF manifest schema · 정본 답안 아님 · 비실행",
  "gitSha": "0000000000000000000000000000000000000000",
  "image": "example.invalid/financial-core@sha256:0000000000000000000000000000000000000000000000000000000000000000",
  "java": "21",
  "springBoot": "4.1.0",
  "dbMigrations": [
    {
      "version": "001",
      "script": "V001__common.sql",
      "checksum": "EXAMPLE_FLYWAY_CHECKSUM"
    },
    {
      "version": "019",
      "script": "V019__audit.sql",
      "checksum": "EXAMPLE_FLYWAY_CHECKSUM"
    }
  ],
  "dbMigrationInventorySha256": "0000000000000000000000000000000000000000000000000000000000000000",
  "verificationStatus": "MANUAL_REVIEW_REQUIRED"
}
05

RDS 5단 진단 — identity→secret→network→migration→readiness

illustrative/shell/W22-D5-rds-connectivity.sh

학습용 예시 · PDF shell 학습 골격 · 정본 답안 아님 · 그대로 실행 금지 · 학습용 예시 · 정본 답안 아님 · W22-F05
14줄 연결14줄 번역2 chunks
01

STEP 01 / 13

오늘 이 코드에서 해결할 문제

무엇을 이해해야 하는지 질문부터 잡습니다.

오늘의 한 문장

RDS 연결 문제를 identity→secret ARN→network→migration→readiness 순서로 분리하는 PDF 학습 runbook이다.

  1. `caller identity`은 어느 줄에서 생길까?
  2. 입력→guard→관찰→cleanup 순서는 무엇인가?
  3. local owner와 external human review는 누구인가?
  4. 직접 관찰하지 않은 Green은 무엇인가?
  5. 반례는 `그대로 실행할 완전한 script가 아니다`이라는 경계와 어떻게 연결되는가?
이 파일에서 끝까지 다시 쓰는 값caller identityparameter ARN onlypg_isready 5432flywayInforeadiness
02

STEP 02 / 13

아주 짧게: 이 코드는 왜 필요할까?

웹소설 대신 이 코드가 필요한 이유만 두 문단으로 쉽게 봅니다.

STARRY가 GitHub run표·AWS 출입증·DB 복구 영수증·SQL 결과표를 서로 다른 칸에 놓는다.

RDS 5단 진단 — identity→secret→network→migration→readiness ― 증거 흐름으로 바꾸기

RDS 연결 문제를 identity→secret ARN→network→migration→readiness 순서로 분리하는 PDF 학습 runbook이다.

핵심값 caller identity, parameter ARN only, pg_isready 5432, flywayInfo, readiness을 원본 줄로 따라가되, `그대로 실행할 완전한 script가 아니다`까지 함께 표시해 Green 범위를 부풀리지 않는다.

딱 여기까지만 비유는 owner와 순서를 기억하게 할 뿐 외부 실행·AWS 계정 상태·PostgreSQL restore·SQL 결과를 자동 증명하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

생활 비유와 실제 코드의 경계를 함께 확인합니다.

원문 1–10줄

1~10줄을 한 덩어리로 읽어 1번째 움직임을 본다. RDS 연결 문제를 identity→secret ARN→network→migration→readiness 순서로 분리하는 PDF 학습 runbook이다.

코드 연결
1~10줄
비유
출입증(identity), 복도(network), 잠금번호(secret), 방 배치(schema), 영업등(readiness)을 차례로 보는 장애 진단 사다리
비유의 끝
그대로 실행할 완전한 script가 아니다

원문 11–14줄

11~14줄을 한 덩어리로 읽어 2번째 움직임을 본다. RDS 연결 문제를 identity→secret ARN→network→migration→readiness 순서로 분리하는 PDF 학습 runbook이다.

코드 연결
11~14줄
비유
출입증(identity), 복도(network), 잠금번호(secret), 방 배치(schema), 영업등(readiness)을 차례로 보는 장애 진단 사다리
비유의 끝
secret Value를 출력하지 않는다
문제의 첫 장면
  1. 첫 고정값은 `caller identity` 맞아?

  2. RDS 연결 문제를 identity→secret ARN→network→migration→readiness 순서로 분리하는 PDF 학습 runbook이다.

  3. 원문에서 `caller identity`이 생기는 위치를 찾자.

  4. 그리고 `그대로 실행할 완전한 script가 아니다`도 같이 적어.

입력에서 결과까지
  1. `parameter ARN only`은 언제 생겨?

  2. caller identity를 확인한다. → secret ARN과 권한 경계를 확인한다.

  3. private host에서 5432를 확인한다. → migration 뒤 readiness를 확인한다.

  4. 관찰값과 `secret Value를 출력하지 않는다`을 분리하면 돼.

04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

감사 규칙상 연결 대상인 원본 14줄을 빠짐없이 연결합니다.

단어 몇 개만 뽑은 표가 아닙니다.학습용 예시 · PDF shell 학습 골격 · 정본 답안 아님 · 그대로 실행 금지에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.14 / 14 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F05-L01 #!/usr/bin/env bash 출입증(identity), 복도(network), 잠금번호(secret), 방 배치(schema), 영업등(readiness)을 차례로 보는 장애 진단 사다리 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
AWS caller·parameter ARN·private endpoint·migration·health
결과·효과
이 줄 뒤에는 항목 전체의 `caller identity` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
그대로 실행할 완전한 script가 아니다
2줄F05-L02 # 학습용 예시 · PDF 연결 순서 template · 정본 답안 아님 · 그대로 실행 금지 출입증(identity), 복도(network), 잠금번호(secret), 방 배치(schema), 영업등(readiness)을 차례로 보는 장애 진단 사다리 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
AWS caller·parameter ARN·private endpoint·migration·health
결과·효과
이 줄 뒤에는 항목 전체의 `parameter ARN only` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
secret Value를 출력하지 않는다
3줄F05-L03 # 1. identity: 현재 AWS caller가 의도한 deploy/app role인지 확인한다. 출입증(identity), 복도(network), 잠금번호(secret), 방 배치(schema), 영업등(readiness)을 차례로 보는 장애 진단 사다리 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
AWS caller·parameter ARN·private endpoint·migration·health
결과·효과
이 줄 뒤에는 항목 전체의 `pg_isready 5432` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
private host 밖에서 RDS를 공개하지 않는다
4줄F05-L04 aws sts get-caller-identity 출입증(identity), 복도(network), 잠금번호(secret), 방 배치(schema), 영업등(readiness)을 차례로 보는 장애 진단 사다리 현재 AWS session이 의도한 caller인지 먼저 관찰한다.
입력
AWS caller·parameter ARN·private endpoint·migration·health
결과·효과
이 줄 뒤에는 항목 전체의 `flywayInfo` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
migration 성공 전 traffic readiness를 열지 않는다
5줄F05-L05 # 2. secret boundary: decrypted Value를 출력하지 않고 parameter ARN만 확인한다. 출입증(identity), 복도(network), 잠금번호(secret), 방 배치(schema), 영업등(readiness)을 차례로 보는 장애 진단 사다리 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
AWS caller·parameter ARN·private endpoint·migration·health
결과·효과
이 줄 뒤에는 항목 전체의 `readiness` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
그대로 실행할 완전한 script가 아니다
6줄F05-L06 aws ssm get-parameter --name /fcl/prod/db/password --query Parameter.ARN 출입증(identity), 복도(network), 잠금번호(secret), 방 배치(schema), 영업등(readiness)을 차례로 보는 장애 진단 사다리 inbound SSH 없이 관리 session 또는 secret metadata를 다루는 AWS 경계를 나타낸다.
입력
AWS caller·parameter ARN·private endpoint·migration·health
결과·효과
이 줄 뒤에는 항목 전체의 `caller identity` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
secret Value를 출력하지 않는다
7줄F05-L07 # 3. network: private app host에서만 private RDS endpoint와 5432 도달성을 확인한다. 출입증(identity), 복도(network), 잠금번호(secret), 방 배치(schema), 영업등(readiness)을 차례로 보는 장애 진단 사다리 private PostgreSQL 5432와 application SG 사이의 DB 경계를 표현한다.
입력
AWS caller·parameter ARN·private endpoint·migration·health
결과·효과
이 줄 뒤에는 항목 전체의 `parameter ARN only` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
private host 밖에서 RDS를 공개하지 않는다
8줄F05-L08 pg_isready -h private-rds-endpoint.internal -p 5432 출입증(identity), 복도(network), 잠금번호(secret), 방 배치(schema), 영업등(readiness)을 차례로 보는 장애 진단 사다리 private PostgreSQL 5432와 application SG 사이의 DB 경계를 표현한다.
입력
AWS caller·parameter ARN·private endpoint·migration·health
결과·효과
이 줄 뒤에는 항목 전체의 `pg_isready 5432` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
migration 성공 전 traffic readiness를 열지 않는다
9줄F05-L09 # 4. migration: Flyway info와 실제 schema history의 version·script·checksum을 대조한다. 출입증(identity), 복도(network), 잠금번호(secret), 방 배치(schema), 영업등(readiness)을 차례로 보는 장애 진단 사다리 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
AWS caller·parameter ARN·private endpoint·migration·health
결과·효과
이 줄 뒤에는 항목 전체의 `flywayInfo` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
그대로 실행할 완전한 script가 아니다
10줄F05-L10 ./gradlew flywayInfo 출입증(identity), 복도(network), 잠금번호(secret), 방 배치(schema), 영업등(readiness)을 차례로 보는 장애 진단 사다리 application traffic 전에 migration 상태를 읽는 학습 단계다.
입력
AWS caller·parameter ARN·private endpoint·migration·health
결과·효과
이 줄 뒤에는 항목 전체의 `readiness` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
secret Value를 출력하지 않는다
11줄F05-L11 # 5. readiness: migration 성공 뒤에만 application traffic readiness를 확인한다. 출입증(identity), 복도(network), 잠금번호(secret), 방 배치(schema), 영업등(readiness)을 차례로 보는 장애 진단 사다리 migration과 dependency가 준비된 뒤 traffic 수락 상태를 확인한다.
입력
AWS caller·parameter ARN·private endpoint·migration·health
결과·효과
이 줄 뒤에는 항목 전체의 `caller identity` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
private host 밖에서 RDS를 공개하지 않는다
12줄F05-L12 curl --fail --silent http://127.0.0.1:8080/actuator/health/readiness 출입증(identity), 복도(network), 잠금번호(secret), 방 배치(schema), 영업등(readiness)을 차례로 보는 장애 진단 사다리 migration과 dependency가 준비된 뒤 traffic 수락 상태를 확인한다.
입력
AWS caller·parameter ARN·private endpoint·migration·health
결과·효과
이 줄 뒤에는 항목 전체의 `parameter ARN only` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
migration 성공 전 traffic readiness를 열지 않는다
13줄F05-L13 # timeout은 route·DNS·SG 단계, password authentication failed는 secret·user·DB name 단계를 먼저 본다. 출입증(identity), 복도(network), 잠금번호(secret), 방 배치(schema), 영업등(readiness)을 차례로 보는 장애 진단 사다리 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
AWS caller·parameter ARN·private endpoint·migration·health
결과·효과
이 줄 뒤에는 항목 전체의 `pg_isready 5432` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
그대로 실행할 완전한 script가 아니다
14줄F05-L14 # secret 원문, account ID, endpoint 전체는 evidence에 저장하지 않는다. 출입증(identity), 복도(network), 잠금번호(secret), 방 배치(schema), 영업등(readiness)을 차례로 보는 장애 진단 사다리 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
AWS caller·parameter ARN·private endpoint·migration·health
결과·효과
이 줄 뒤에는 항목 전체의 `flywayInfo` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
secret Value를 출력하지 않는다
Green 범위
  1. marker나 파일이 보이면 전부 성공이야?

  2. 아니. source가 직접 검증한 범위만 말해야 해.

  3. 직접 연결되는 대표 값은 `readiness`이야.

  4. `private host 밖에서 RDS를 공개하지 않는다`는 별도 증거가 필요해.

05

STEP 05 / 13

원본 코드 조각

원본을 2개 의미 조각으로 나누어 그대로 확인합니다.

파일을 한꺼번에 외우지 않고 실행 의미가 이어지는 작은 조각으로 봅니다. 아래 코드는 prompt·fixture·가정을 밝힌 학습용 예시 source이며, 제공 정본 답안이 아닙니다.

F05-C01 · 원문 1–10줄1–10줄
1–10줄 원본
#!/usr/bin/env bash
# 학습용 예시 · PDF 연결 순서 template · 정본 답안 아님 · 그대로 실행 금지
# 1. identity: 현재 AWS caller가 의도한 deploy/app role인지 확인한다.
aws sts get-caller-identity
# 2. secret boundary: decrypted Value를 출력하지 않고 parameter ARN만 확인한다.
aws ssm get-parameter --name /fcl/prod/db/password --query Parameter.ARN
# 3. network: private app host에서만 private RDS endpoint와 5432 도달성을 확인한다.
pg_isready -h private-rds-endpoint.internal -p 5432
# 4. migration: Flyway info와 실제 schema history의 version·script·checksum을 대조한다.
./gradlew flywayInfo
F05-C02 · 원문 11–14줄11–14줄
11–14줄 원본
# 5. readiness: migration 성공 뒤에만 application traffic readiness를 확인한다.
curl --fail --silent http://127.0.0.1:8080/actuator/health/readiness
# timeout은 route·DNS·SG 단계, password authentication failed는 secret·user·DB name 단계를 먼저 본다.
# secret 원문, account ID, endpoint 전체는 evidence에 저장하지 않는다.
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

비어 있지 않은 14줄을 모두 한국어로 옮깁니다.

전체 번역 14 / 14

비어 있지 않은 원본 줄은 하나도 생략하지 않습니다.

원본한국어 번역
1#!/usr/bin/env bash이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
2# 학습용 예시 · PDF 연결 순서 template · 정본 답안 아님 · 그대로 실행 금지이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
3# 1. identity: 현재 AWS caller가 의도한 deploy/app role인지 확인한다.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
4aws sts get-caller-identity현재 AWS session이 의도한 caller인지 먼저 관찰한다.
5# 2. secret boundary: decrypted Value를 출력하지 않고 parameter ARN만 확인한다.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
6aws ssm get-parameter --name /fcl/prod/db/password --query Parameter.ARNinbound SSH 없이 관리 session 또는 secret metadata를 다루는 AWS 경계를 나타낸다.
7# 3. network: private app host에서만 private RDS endpoint와 5432 도달성을 확인한다.private PostgreSQL 5432와 application SG 사이의 DB 경계를 표현한다.
8pg_isready -h private-rds-endpoint.internal -p 5432private PostgreSQL 5432와 application SG 사이의 DB 경계를 표현한다.
9# 4. migration: Flyway info와 실제 schema history의 version·script·checksum을 대조한다.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
10./gradlew flywayInfoapplication traffic 전에 migration 상태를 읽는 학습 단계다.
11# 5. readiness: migration 성공 뒤에만 application traffic readiness를 확인한다.migration과 dependency가 준비된 뒤 traffic 수락 상태를 확인한다.
12curl --fail --silent http://127.0.0.1:8080/actuator/health/readinessmigration과 dependency가 준비된 뒤 traffic 수락 상태를 확인한다.
13# timeout은 route·DNS·SG 단계, password authentication failed는 secret·user·DB name 단계를 먼저 본다.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
14# secret 원문, account ID, endpoint 전체는 evidence에 저장하지 않는다.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
07

STEP 07 / 13

기존 수준의 한 줄 읽기·문법 해부

쉬운 설명 다음에 문법과 실행 순서를 정밀하게 읽습니다.

한 줄로 읽기

RDS 연결 문제를 identity→secret ARN→network→migration→readiness 순서로 분리하는 PDF 학습 runbook이다. 다만 그대로 실행할 완전한 script가 아니다

문법 해부

  • 각 명령은 서로 다른 실패 layer를 관찰하며 앞 단계 성공을 뒤 단계 성공으로 확대하지 않는다.
  • `--query Parameter.ARN`은 decrypted secret Value 대신 식별자만 읽는다.

실행 순서

  1. caller identity를 확인한다.
  2. secret ARN과 권한 경계를 확인한다.
  3. private host에서 5432를 확인한다.
  4. migration 뒤 readiness를 확인한다.

W22 조각별 정밀 해설

F05-C01 · 원문 1–10줄
문법 해부
1~10줄의 `원문 1–10줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `caller identity`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `caller identity`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: 그대로 실행할 완전한 script가 아니다.
착각 방지
`원문 1–10줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: 그대로 실행할 완전한 script가 아니다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F05-C02 · 원문 11–14줄
문법 해부
11~14줄의 `원문 11–14줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `parameter ARN only`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `parameter ARN only`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: secret Value를 출력하지 않는다.
착각 방지
`원문 11–14줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: secret Value를 출력하지 않는다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
반례
  1. 겉보기에는 맞지만 깨지는 예는?

  2. timeout과 password authentication failed를 같은 문제로 본다

  3. 그 상태는 owner·입력·관찰 중 한 칸이 비어 있어.

  4. 수정한 뒤 같은 source와 hash로 다시 대조해.

08

STEP 08 / 13

실제 값 따라가기

같은 입력값이 어느 줄을 지나 어떤 결과가 되는지 추적합니다.

순서들어온 값코드가 하는 일나온 값·상태경계
F05-T01 identityAWS sessionstscalleraccount 전체 노출 주의
F05-T02 connectivityprivate endpointpg_isreadyaccepting/timeoutschema는 모름
F05-T03 applicationmigrated DBreadiness GETUPsecret 원문 저장 금지
책임 경계
  1. 이 항목의 마지막 책임선은?

  2. 직접 역할은 `RDS 연결 단계별 진단 template`이야.

  3. 대표 경계는 `migration 성공 전 traffic readiness를 열지 않는다`이야.

  4. 정본/비정본 label과 evidence owner까지 확인하면 끝이야.

09

STEP 09 / 13

GitHub·AWS·PowerShell·PostgreSQL 내부에서 벌어지는 일

GitHub·AWS·PowerShell·PostgreSQL에서 실제로 일어나는 일과 증명 범위를 구분합니다.

DNS/routing/SG

timeout의 network 경로를 구성한다.

auth failure와 구분한다.
PostgreSQL auth

도달 뒤 user/password/DB name을 확인한다.

log에 password를 쓰지 않는다.
Spring/Flyway

migration 성공 뒤 readiness를 traffic 신호로 쓴다.

migration 실패 중 traffic을 받지 않는다.
10

STEP 10 / 13

흔한 착각과 틀린 예

그럴듯하지만 틀린 해석을 반례로 고칩니다.

❌ timeout과 password authentication failed를 같은 문제로 본다

왜 틀리나 RDS 연결 단계별 진단 template의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 caller identity를 확인한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `그대로 실행할 완전한 script가 아니다` 상태인데도 Green을 주장하게 된다.

❌ SSM parameter Value를 evidence에 출력한다

왜 틀리나 RDS 연결 단계별 진단 template의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 secret ARN과 권한 경계를 확인한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `secret Value를 출력하지 않는다` 상태인데도 Green을 주장하게 된다.

❌ 노트북에서 private RDS를 직접 공개한다

왜 틀리나 RDS 연결 단계별 진단 template의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 private host에서 5432를 확인한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `private host 밖에서 RDS를 공개하지 않는다` 상태인데도 Green을 주장하게 된다.

❌ Flyway 실패인데 readiness를 연다

왜 틀리나 RDS 연결 단계별 진단 template의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 migration 뒤 readiness를 확인한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `migration 성공 전 traffic readiness를 열지 않는다` 상태인데도 Green을 주장하게 된다.

❌ 명령 조각을 완전 자동 script라고 부른다

왜 틀리나 RDS 연결 단계별 진단 template의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 migration 뒤 readiness를 확인한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `그대로 실행할 완전한 script가 아니다` 상태인데도 Green을 주장하게 된다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

이 코드가 책임지지 않는 일을 분리합니다.

직접 미보장

그대로 실행할 완전한 script가 아니다

이 책임을 맡는 곳: 별도 외부/selector 실행
직접 미보장

secret Value를 출력하지 않는다

이 책임을 맡는 곳: secret·운영 정책
직접 미보장

private host 밖에서 RDS를 공개하지 않는다

이 책임을 맡는 곳: infrastructure·사람 검토
직접 미보장

migration 성공 전 traffic readiness를 열지 않는다

이 책임을 맡는 곳: owner lifecycle
12

STEP 12 / 13

직접 다시 써보기

뜻 → 조각 → 전체 코드 순서로 다시 씁니다.

1단계 · 뜻부터 복원

다음 역할을 고정값과 미보장 경계까지 말한다: RDS 연결 문제를 identity→secret ARN→network→migration→readiness 순서로 분리하는 PDF 학습 runbook이다.

2단계 · 코드 조각 재조립

  1. 원문 1–10줄
  2. 원문 11–14줄

3단계 · 파일 전체 다시 쓰기

14개 물리 줄을 원본 순서로 복원하고 SHA-256 b88ed6cf171060bd793fd57c682ad0444ce5ace14fd16ba0423c6ba42e312006와 대조한다.

자가 점검
  • 원본 source/template bytes를 바꾸지 않았는가?
  • 외부 미실행과 local restore Green을 구분했는가?
  • secret 원문을 evidence에 남기지 않았는가?
  • D7 checked_at 충돌과 사람 검토 경계를 보았는가?
  • Q35/Q36을 workbook 정본 답안이라고 부르지 않았는가?
13

STEP 13 / 13

전체 원본 source

감사로 고정한 전체 source를 가감 없이 확인합니다.

학습용 예시 전체 확인하기 · 정본 답안 아님
학습용 예시 · PDF shell 학습 골격 · 정본 답안 아님 · 그대로 실행 금지illustrative/shell/W22-D5-rds-connectivity.shSHA-256 b88ed6cf171060bd793fd57c682ad0444ce5ace14fd16ba0423c6ba42e312006
RDS 5단 진단 — identity→secret→network→migration→readiness 전체
#!/usr/bin/env bash
# 학습용 예시 · PDF 연결 순서 template · 정본 답안 아님 · 그대로 실행 금지
# 1. identity: 현재 AWS caller가 의도한 deploy/app role인지 확인한다.
aws sts get-caller-identity
# 2. secret boundary: decrypted Value를 출력하지 않고 parameter ARN만 확인한다.
aws ssm get-parameter --name /fcl/prod/db/password --query Parameter.ARN
# 3. network: private app host에서만 private RDS endpoint와 5432 도달성을 확인한다.
pg_isready -h private-rds-endpoint.internal -p 5432
# 4. migration: Flyway info와 실제 schema history의 version·script·checksum을 대조한다.
./gradlew flywayInfo
# 5. readiness: migration 성공 뒤에만 application traffic readiness를 확인한다.
curl --fail --silent http://127.0.0.1:8080/actuator/health/readiness
# timeout은 route·DNS·SG 단계, password authentication failed는 secret·user·DB name 단계를 먼저 본다.
# secret 원문, account ID, endpoint 전체는 evidence에 저장하지 않는다.
06

run-w22-restore.ps1 — disposable restore 3·120·0 owner

scripts/run-w22-restore.ps1

원문 정본 · 완전한 packaged PowerShell source · 정본 · W22-F06
122줄 연결122줄 번역12 chunks
01

STEP 01 / 13

오늘 이 코드에서 해결할 문제

무엇을 이해해야 하는지 질문부터 잡습니다.

오늘의 한 문장

고정 3행을 별도 DB에 dump/restore해 3·120·0과 cleanup을 검증하고 canonical restore-result.json을 atomic publish하는 W22 packaged owner다.

  1. `row_count=3`은 어느 줄에서 생길까?
  2. 입력→guard→관찰→cleanup 순서는 무엇인가?
  3. local owner와 external human review는 누구인가?
  4. 직접 관찰하지 않은 Green은 무엇인가?
  5. 반례는 `production RPO/RTO 보장이 아니다`이라는 경계와 어떻게 연결되는가?
이 파일에서 끝까지 다시 쓰는 값row_count=3ledger_sum=120mismatch=0cleanup=1W22_RESTORE_GREEN
02

STEP 02 / 13

아주 짧게: 이 코드는 왜 필요할까?

웹소설 대신 이 코드가 필요한 이유만 두 문단으로 쉽게 봅니다.

STARRY가 GitHub run표·AWS 출입증·DB 복구 영수증·SQL 결과표를 서로 다른 칸에 놓는다.

run-w22-restore.ps1 — disposable restore 3·120·0 owner ― 증거 흐름으로 바꾸기

고정 3행을 별도 DB에 dump/restore해 3·120·0과 cleanup을 검증하고 canonical restore-result.json을 atomic publish하는 W22 packaged owner다.

핵심값 row_count=3, ledger_sum=120, mismatch=0, cleanup=1, W22_RESTORE_GREEN을 원본 줄로 따라가되, `production RPO/RTO 보장이 아니다`까지 함께 표시해 Green 범위를 부풀리지 않는다.

딱 여기까지만 비유는 owner와 순서를 기억하게 할 뿐 외부 실행·AWS 계정 상태·PostgreSQL restore·SQL 결과를 자동 증명하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

생활 비유와 실제 코드의 경계를 함께 확인합니다.

원문 1–12줄

1~12줄을 한 덩어리로 읽어 1번째 움직임을 본다. 고정 3행을 별도 DB에 dump/restore해 3·120·0과 cleanup을 검증하고 canonical restore-result.json을 atomic publish하는 W22 packaged owner다.

코드 연결
1~12줄
비유
감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련
비유의 끝
production RPO/RTO 보장이 아니다

원문 13–24줄

13~24줄을 한 덩어리로 읽어 2번째 움직임을 본다. 고정 3행을 별도 DB에 dump/restore해 3·120·0과 cleanup을 검증하고 canonical restore-result.json을 atomic publish하는 W22 packaged owner다.

코드 연결
13~24줄
비유
감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련
비유의 끝
run-w42-restore-drill.ps1에 transitive 의존한다

원문 25–36줄

25~36줄을 한 덩어리로 읽어 3번째 움직임을 본다. 고정 3행을 별도 DB에 dump/restore해 3·120·0과 cleanup을 검증하고 canonical restore-result.json을 atomic publish하는 W22 packaged owner다.

코드 연결
25~36줄
비유
감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련
비유의 끝
허용 target DB 이름만 쓴다
문제의 첫 장면
  1. 첫 고정값은 `row_count=3` 맞아?

  2. 고정 3행을 별도 DB에 dump/restore해 3·120·0과 cleanup을 검증하고 canonical restore-result.json을 atomic publish하는 W22 packaged owner다.

  3. 원문에서 `row_count=3`이 생기는 위치를 찾자.

  4. 그리고 `production RPO/RTO 보장이 아니다`도 같이 적어.

입력에서 결과까지
  1. `ledger_sum=120`은 언제 생겨?

  2. allowlist와 transitive tool을 검사한다. → Compose 또는 caller container를 선택한다.

  3. W42 restore 결과 3·120·0을 재검증한다. → cleanup 뒤 restore-result.json을 atomic publish한다.

  4. 관찰값과 `run-w42-restore-drill.ps1에 transitive 의존한다`을 분리하면 돼.

04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

감사 규칙상 연결 대상인 원본 122줄을 빠짐없이 연결합니다.

단어 몇 개만 뽑은 표가 아닙니다.원문 정본 · 완전한 packaged PowerShell source에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.122 / 122 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F06-L01 param( 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 W22 restore runner의 호출 parameter 계약을 연다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
2줄F06-L02 [ValidateSet('Compose','Container')][string]$Mode = 'Compose', 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 허용 실행 mode를 Compose와 Container 두 값으로 제한한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
3줄F06-L03 [string]$ComposeProject = 'w22-restore-lab', 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `[string]$ComposeProject = 'w22-restore-lab',` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
4줄F06-L04 [string]$ContainerName = '', 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `[string]$ContainerName = '',` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
5줄F06-L05 [string]$EvidenceDir = 'evidence/w22', 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `[string]$EvidenceDir = 'evidence/w22',` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
6줄F06-L06 [string]$TargetDb = 'financial_core_restore' 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 disposable restore target 이름과 exact allowlist를 다룬다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
7줄F06-L07 ) 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
9줄F06-L09 Set-StrictMode -Version Latest 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 미정의 변수 등 PowerShell 오류를 조기에 드러낸다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
10줄F06-L10 $ErrorActionPreference = 'Stop' 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 PowerShell cmdlet 오류를 terminating error로 처리한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
12줄F06-L12 if ($TargetDb -cne 'financial_core_restore') { 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 disposable restore target 이름과 exact allowlist를 다룬다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
13줄F06-L13 throw 'W22 disposable target allowlist violation' 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer의 13번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
14줄F06-L14 } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
16줄F06-L16 $root = Split-Path -Parent $PSScriptRoot 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `$root = Split-Path -Parent $PSScriptRoot` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
17줄F06-L17 $evidence = if ([IO.Path]::IsPathRooted($EvidenceDir)) { 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `$evidence = if ([IO.Path]::IsPathRooted($Evidenc` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
18줄F06-L18 [IO.Path]::GetFullPath($EvidenceDir) 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `[IO.Path]::GetFullPath($EvidenceDir)` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
19줄F06-L19 } else { 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer의 19번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
20줄F06-L20 [IO.Path]::GetFullPath((Join-Path $root $EvidenceDir)) 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `[IO.Path]::GetFullPath((Join-Path $root $Evidenc` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
21줄F06-L21 } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
22줄F06-L22 $tool = Join-Path $PSScriptRoot 'run-w42-restore-drill.ps1' 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 완전한 restore 수행을 맡는 packaged W42 transitive tool을 찾는다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
23줄F06-L23 $compose = Join-Path $root 'compose.yaml' 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `$compose = Join-Path $root 'compose.yaml'` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
24줄F06-L24 $ownedCompose = $false 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `$ownedCompose = $false` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
25줄F06-L25 $composeCleanup = $false 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 source/target DB와 소유 resource 정리 결과를 evidence에 묶는다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
26줄F06-L26 $failure = $null 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `$failure = $null` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
27줄F06-L27 $body = $null 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `$body = $null` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
29줄F06-L29 if (!(Test-Path -LiteralPath $tool -PathType Leaf)) { 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
30줄F06-L30 throw 'W22 transitive W42 tool missing' 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer의 30번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
31줄F06-L31 } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
33줄F06-L33 try { 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer의 33번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
34줄F06-L34 if ($Mode -ceq 'Compose') { 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
35줄F06-L35 if ($ContainerName) { throw 'W22 Compose mode rejects ContainerName' } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
36줄F06-L36 if ([string]::IsNullOrWhiteSpace($env:FCL_DB_PASSWORD)) { 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
37줄F06-L37 $env:FCL_DB_PASSWORD = 'w22-disposable-password' 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `$env:FCL_DB_PASSWORD = 'w22-disposable-password'` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
38줄F06-L38 } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
39줄F06-L39 # Own the unique Compose project before startup so a partial `up` 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
40줄F06-L40 # failure still reaches finally/down and cannot leak resources. 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
41줄F06-L41 $ownedCompose = $true 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `$ownedCompose = $true` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
42줄F06-L42 & docker compose -f $compose -p $ComposeProject up -d --wait db 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 W22가 소유한 DB Compose project를 시작하거나 finally에서 정리한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
43줄F06-L43 if ($LASTEXITCODE -ne 0) { throw "W22 compose up exit=$LASTEXITCODE" } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
44줄F06-L44 $ContainerName = (& docker compose -f $compose -p $ComposeProject ps -q db).Trim() 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 W22가 소유한 DB Compose project를 시작하거나 finally에서 정리한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
45줄F06-L45 } elseif ([string]::IsNullOrWhiteSpace($ContainerName)) { 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `} elseif ([string]::IsNullOrWhiteSpace($Containe` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
46줄F06-L46 throw 'W22 Container mode requires ContainerName' 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer의 46번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
47줄F06-L47 } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
48줄F06-L48 if ([string]::IsNullOrWhiteSpace($ContainerName)) { 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
49줄F06-L49 throw 'W22 container resolution failed' 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer의 49번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
50줄F06-L50 } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
52줄F06-L52 $output = @( 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `$output = @(` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
53줄F06-L53 & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $tool ` 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer의 53번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
54줄F06-L54 -Mode Container ` 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer의 54번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
55줄F06-L55 -ContainerName $ContainerName ` 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer의 55번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
56줄F06-L56 -AdminDatabase financial_core ` 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer의 56번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
57줄F06-L57 -Username app ` 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer의 57번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
58줄F06-L58 -TargetDb $TargetDb ` 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 disposable restore target 이름과 exact allowlist를 다룬다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
59줄F06-L59 -EvidenceDir $evidence 2>&1 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer의 59번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
60줄F06-L60 ) 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
61줄F06-L61 $nativeExit = $LASTEXITCODE 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `$nativeExit = $LASTEXITCODE` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
62줄F06-L62 if ($nativeExit -ne 0) { 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
63줄F06-L63 throw "W22 restore native exit=$nativeExit`n$($output -join "`n")" 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `throw "W22 restore native exit=$nativeExit`n$($o` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
64줄F06-L64 } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
65줄F06-L65 $line = $output | Where-Object { $_ -match '^PASS W42_RESTORE ' } | Select-Object -Last 1 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 inner restore transcript의 exact success marker를 선택한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
66줄F06-L66 if (!$line -or $line -cnotmatch 'row_count=3 ledger_sum=120 mismatch=0 rto_seconds=([0-9]+(?:\.[0-9]+)?) source_dropped=1 target_dropped=1') { 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 복구된 고정 fixture가 정확히 3행인지 기록하거나 검사한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
67줄F06-L67 throw "W22 transcript mismatch: $output" 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 source와 restore 비교 불일치가 정확히 0인지 기록하거나 검사한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
68줄F06-L68 } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
70줄F06-L70 $innerPath = Join-Path $evidence '5-restore-result.json' 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `$innerPath = Join-Path $evidence '5-restore-resu` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
71줄F06-L71 if (!(Test-Path -LiteralPath $innerPath -PathType Leaf)) { 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
72줄F06-L72 throw 'W22 inner restore result missing' 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer의 72번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
73줄F06-L73 } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
74줄F06-L74 $inner = Get-Content -Raw -LiteralPath $innerPath | ConvertFrom-Json 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `$inner = Get-Content -Raw -LiteralPath $innerPat` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
75줄F06-L75 if ([int]$inner.row_count -ne 3 -or [long]$inner.ledger_sum -ne 120 -or 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 복구된 고정 fixture가 정확히 3행인지 기록하거나 검사한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
76줄F06-L76 [int]$inner.mismatch_count -ne 0 -or [long]$inner.dump_bytes -le 0) { 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 source와 restore 비교 불일치가 정확히 0인지 기록하거나 검사한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
77줄F06-L77 throw 'W22 inner restore invariant mismatch' 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 source와 restore 비교 불일치가 정확히 0인지 기록하거나 검사한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
78줄F06-L78 } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
79줄F06-L79 $start = [DateTimeOffset]::MinValue 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `$start = [DateTimeOffset]::MinValue` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
80줄F06-L80 $end = [DateTimeOffset]::MinValue 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `$end = [DateTimeOffset]::MinValue` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
81줄F06-L81 if (![DateTimeOffset]::TryParse([string]$inner.start_utc, [ref]$start) -or 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
82줄F06-L82 ![DateTimeOffset]::TryParse([string]$inner.end_utc, [ref]$end) -or $end -lt $start) { 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `![DateTimeOffset]::TryParse([string]$inner.end_u` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
83줄F06-L83 throw 'W22 inner restore timestamps invalid' 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer의 83번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
84줄F06-L84 } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
86줄F06-L86 $body = [ordered]@{ 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `$body = [ordered]@{` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
87줄F06-L87 owner = 'W22' 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `owner = 'W22'` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
88줄F06-L88 run_id = [guid]::NewGuid().ToString('N') 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `run_id = [guid]::NewGuid().ToString('N')` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
89줄F06-L89 started_at_utc = $start.ToString('o') 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `started_at_utc = $start.ToString('o')` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
90줄F06-L90 completed_at_utc = $end.ToString('o') 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `completed_at_utc = $end.ToString('o')` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
91줄F06-L91 source_db = 'financial_core_restore_source' 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `source_db = 'financial_core_restore_source'` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
92줄F06-L92 target_db = $TargetDb 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 disposable restore target 이름과 exact allowlist를 다룬다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
93줄F06-L93 fixture_schema = 'restore_probe_v1' 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `fixture_schema = 'restore_probe_v1'` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
94줄F06-L94 row_count = 3 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 복구된 고정 fixture가 정확히 3행인지 기록하거나 검사한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
95줄F06-L95 ledger_sum = 120 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 복구된 signed amount 합계가 정확히 120인지 기록하거나 검사한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
96줄F06-L96 mismatch = 0 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 source와 restore 비교 불일치가 정확히 0인지 기록하거나 검사한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
97줄F06-L97 rto_seconds = [double]$inner.rto_seconds 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 disposable drill의 실측 restore 시간을 기록하되 production RTO로 확대하지 않는다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
98줄F06-L98 dump_bytes = [long]$inner.dump_bytes 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `dump_bytes = [long]$inner.dump_bytes` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
99줄F06-L99 source_dropped = 1 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `source_dropped = 1` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
100줄F06-L100 target_dropped = 1 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `target_dropped = 1` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
101줄F06-L101 cleanup = 1 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 source/target DB와 소유 resource 정리 결과를 evidence에 묶는다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
102줄F06-L102 native_exit = 0 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `native_exit = 0` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
103줄F06-L103 inner_result_path = 'evidence/w22/5-restore-result.json' 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `inner_result_path = 'evidence/w22/5-restore-resu` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
104줄F06-L104 inner_result_sha256 = (Get-FileHash -LiteralPath $innerPath -Algorithm SHA256).Hash.ToLowerInvariant() 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 현재 file bytes를 64-hex SHA-256 값과 결박하는 field 또는 검사를 다룬다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
105줄F06-L105 } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
106줄F06-L106 } catch { 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer의 106번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
107줄F06-L107 $failure = $_ 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `$failure = $_` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
108줄F06-L108 } finally { 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer의 108번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
109줄F06-L109 if ($ownedCompose) { 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
110줄F06-L110 & docker compose -f $compose -p $ComposeProject down -v --remove-orphans | Out-Null 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 W22가 소유한 DB Compose project를 시작하거나 finally에서 정리한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
111줄F06-L111 $composeCleanup = ($LASTEXITCODE -eq 0) 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 source/target DB와 소유 resource 정리 결과를 evidence에 묶는다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
112줄F06-L112 } else { 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer의 112번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
113줄F06-L113 $composeCleanup = $true 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 source/target DB와 소유 resource 정리 결과를 evidence에 묶는다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
114줄F06-L114 } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
115줄F06-L115 } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
117줄F06-L117 if (!$composeCleanup) { 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 source/target DB와 소유 resource 정리 결과를 evidence에 묶는다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
118줄F06-L118 if ($null -ne $failure) { 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
119줄F06-L119 throw "W22 restore failed and owned Compose cleanup failed: $($failure.Exception.Message)" 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 source/target DB와 소유 resource 정리 결과를 evidence에 묶는다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
120줄F06-L120 } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
121줄F06-L121 throw 'W22 owned Compose cleanup failed' 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 source/target DB와 소유 resource 정리 결과를 evidence에 묶는다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
122줄F06-L122 } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
123줄F06-L123 if ($null -ne $failure) { throw $failure } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
124줄F06-L124 if ($null -eq $body) { throw 'W22 restore produced no canonical result' } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
126줄F06-L126 $body['compose_cleanup'] = if ($ownedCompose) { 1 } else { 'not-owned' } 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 source/target DB와 소유 resource 정리 결과를 evidence에 묶는다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
127줄F06-L127 New-Item -ItemType Directory -Force $evidence | Out-Null 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer의 127번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `ledger_sum=120` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
128줄F06-L128 $resultPath = Join-Path $evidence 'restore-result.json' 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `$resultPath = Join-Path $evidence 'restore-resul` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
Docker·PostgreSQL 실행 환경이 필요하다
129줄F06-L129 $temporary = "$resultPath.tmp" 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer에서 `$temporary = "$resultPath.tmp"` field·값 또는 assignment를 다음 단계에 전달한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `cleanup=1` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
130줄F06-L130 $body | ConvertTo-Json -Depth 5 | Set-Content -Encoding utf8 -LiteralPath $temporary 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 정본 W22 disposable restore evidence producer의 130번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `W22_RESTORE_GREEN` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
run-w42-restore-drill.ps1에 transitive 의존한다
131줄F06-L131 Move-Item -LiteralPath $temporary -Destination $resultPath -Force 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 완성된 temporary evidence를 final path로 원자적으로 교체한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `row_count=3` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
허용 target DB 이름만 쓴다
133줄F06-L133 "W22_RESTORE_GREEN row_count=3 ledger_sum=120 mismatch=0 rto_seconds=$($body.rto_seconds) cleanup=1 native_exit=0" 감독이 임시 원본 창고와 복구 창고를 만들고 3개 상자의 합계 120·불일치 0을 확인한 뒤 두 창고를 모두 철거하고 영수증을 원자적으로 교체하는 훈련 복구된 고정 fixture가 정확히 3행인지 기록하거나 검사한다.
입력
Compose 또는 caller container·W42 restore tool·evidence directory
결과·효과
이 줄 뒤에는 항목 전체의 `mismatch=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production RPO/RTO 보장이 아니다
Green 범위
  1. marker나 파일이 보이면 전부 성공이야?

  2. 아니. source가 직접 검증한 범위만 말해야 해.

  3. 직접 연결되는 대표 값은 `W22_RESTORE_GREEN`이야.

  4. `허용 target DB 이름만 쓴다`는 별도 증거가 필요해.

05

STEP 05 / 13

원본 코드 조각

원본을 12개 의미 조각으로 나누어 그대로 확인합니다.

파일을 한꺼번에 외우지 않고 실행 의미가 이어지는 작은 조각으로 봅니다. 아래 코드는 hash로 고정한 native 정본 source에서 그대로 잘랐습니다.

F06-C01 · 원문 1–12줄1–12줄
1–12줄 원본
param(
    [ValidateSet('Compose','Container')][string]$Mode = 'Compose',
    [string]$ComposeProject = 'w22-restore-lab',
    [string]$ContainerName = '',
    [string]$EvidenceDir = 'evidence/w22',
    [string]$TargetDb = 'financial_core_restore'
)

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

if ($TargetDb -cne 'financial_core_restore') {
F06-C02 · 원문 13–24줄13–24줄
13–24줄 원본
    throw 'W22 disposable target allowlist violation'
}

$root = Split-Path -Parent $PSScriptRoot
$evidence = if ([IO.Path]::IsPathRooted($EvidenceDir)) {
    [IO.Path]::GetFullPath($EvidenceDir)
} else {
    [IO.Path]::GetFullPath((Join-Path $root $EvidenceDir))
}
$tool = Join-Path $PSScriptRoot 'run-w42-restore-drill.ps1'
$compose = Join-Path $root 'compose.yaml'
$ownedCompose = $false
F06-C03 · 원문 25–36줄25–36줄
25–36줄 원본
$composeCleanup = $false
$failure = $null
$body = $null

if (!(Test-Path -LiteralPath $tool -PathType Leaf)) {
    throw 'W22 transitive W42 tool missing'
}

try {
    if ($Mode -ceq 'Compose') {
        if ($ContainerName) { throw 'W22 Compose mode rejects ContainerName' }
        if ([string]::IsNullOrWhiteSpace($env:FCL_DB_PASSWORD)) {
F06-C04 · 원문 37–48줄37–48줄
37–48줄 원본
            $env:FCL_DB_PASSWORD = 'w22-disposable-password'
        }
        # Own the unique Compose project before startup so a partial `up`
        # failure still reaches finally/down and cannot leak resources.
        $ownedCompose = $true
        & docker compose -f $compose -p $ComposeProject up -d --wait db
        if ($LASTEXITCODE -ne 0) { throw "W22 compose up exit=$LASTEXITCODE" }
        $ContainerName = (& docker compose -f $compose -p $ComposeProject ps -q db).Trim()
    } elseif ([string]::IsNullOrWhiteSpace($ContainerName)) {
        throw 'W22 Container mode requires ContainerName'
    }
    if ([string]::IsNullOrWhiteSpace($ContainerName)) {
F06-C05 · 원문 49–60줄49–60줄
49–60줄 원본
        throw 'W22 container resolution failed'
    }

    $output = @(
        & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $tool `
            -Mode Container `
            -ContainerName $ContainerName `
            -AdminDatabase financial_core `
            -Username app `
            -TargetDb $TargetDb `
            -EvidenceDir $evidence 2>&1
    )
F06-C06 · 원문 61–72줄61–72줄
61–72줄 원본
    $nativeExit = $LASTEXITCODE
    if ($nativeExit -ne 0) {
        throw "W22 restore native exit=$nativeExit`n$($output -join "`n")"
    }
    $line = $output | Where-Object { $_ -match '^PASS W42_RESTORE ' } | Select-Object -Last 1
    if (!$line -or $line -cnotmatch 'row_count=3 ledger_sum=120 mismatch=0 rto_seconds=([0-9]+(?:\.[0-9]+)?) source_dropped=1 target_dropped=1') {
        throw "W22 transcript mismatch: $output"
    }

    $innerPath = Join-Path $evidence '5-restore-result.json'
    if (!(Test-Path -LiteralPath $innerPath -PathType Leaf)) {
        throw 'W22 inner restore result missing'
F06-C07 · 원문 73–84줄73–84줄
73–84줄 원본
    }
    $inner = Get-Content -Raw -LiteralPath $innerPath | ConvertFrom-Json
    if ([int]$inner.row_count -ne 3 -or [long]$inner.ledger_sum -ne 120 -or
        [int]$inner.mismatch_count -ne 0 -or [long]$inner.dump_bytes -le 0) {
        throw 'W22 inner restore invariant mismatch'
    }
    $start = [DateTimeOffset]::MinValue
    $end = [DateTimeOffset]::MinValue
    if (![DateTimeOffset]::TryParse([string]$inner.start_utc, [ref]$start) -or
        ![DateTimeOffset]::TryParse([string]$inner.end_utc, [ref]$end) -or $end -lt $start) {
        throw 'W22 inner restore timestamps invalid'
    }
F06-C08 · 원문 85–96줄85–96줄
85–96줄 원본

    $body = [ordered]@{
        owner = 'W22'
        run_id = [guid]::NewGuid().ToString('N')
        started_at_utc = $start.ToString('o')
        completed_at_utc = $end.ToString('o')
        source_db = 'financial_core_restore_source'
        target_db = $TargetDb
        fixture_schema = 'restore_probe_v1'
        row_count = 3
        ledger_sum = 120
        mismatch = 0
F06-C09 · 원문 97–108줄97–108줄
97–108줄 원본
        rto_seconds = [double]$inner.rto_seconds
        dump_bytes = [long]$inner.dump_bytes
        source_dropped = 1
        target_dropped = 1
        cleanup = 1
        native_exit = 0
        inner_result_path = 'evidence/w22/5-restore-result.json'
        inner_result_sha256 = (Get-FileHash -LiteralPath $innerPath -Algorithm SHA256).Hash.ToLowerInvariant()
    }
} catch {
    $failure = $_
} finally {
F06-C10 · 원문 109–120줄109–120줄
109–120줄 원본
    if ($ownedCompose) {
        & docker compose -f $compose -p $ComposeProject down -v --remove-orphans | Out-Null
        $composeCleanup = ($LASTEXITCODE -eq 0)
    } else {
        $composeCleanup = $true
    }
}

if (!$composeCleanup) {
    if ($null -ne $failure) {
        throw "W22 restore failed and owned Compose cleanup failed: $($failure.Exception.Message)"
    }
F06-C11 · 원문 121–132줄121–132줄
121–132줄 원본
    throw 'W22 owned Compose cleanup failed'
}
if ($null -ne $failure) { throw $failure }
if ($null -eq $body) { throw 'W22 restore produced no canonical result' }

$body['compose_cleanup'] = if ($ownedCompose) { 1 } else { 'not-owned' }
New-Item -ItemType Directory -Force $evidence | Out-Null
$resultPath = Join-Path $evidence 'restore-result.json'
$temporary = "$resultPath.tmp"
$body | ConvertTo-Json -Depth 5 | Set-Content -Encoding utf8 -LiteralPath $temporary
Move-Item -LiteralPath $temporary -Destination $resultPath -Force
F06-C12 · 원문 133–133줄133–133줄
133–133줄 원본
"W22_RESTORE_GREEN row_count=3 ledger_sum=120 mismatch=0 rto_seconds=$($body.rto_seconds) cleanup=1 native_exit=0"
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

비어 있지 않은 122줄을 모두 한국어로 옮깁니다.

전체 번역 122 / 122

비어 있지 않은 원본 줄은 하나도 생략하지 않습니다.

원본한국어 번역
1param(W22 restore runner의 호출 parameter 계약을 연다.
2 [ValidateSet('Compose','Container')][string]$Mode = 'Compose',허용 실행 mode를 Compose와 Container 두 값으로 제한한다.
3 [string]$ComposeProject = 'w22-restore-lab',정본 W22 disposable restore evidence producer에서 `[string]$ComposeProject = 'w22-restore-lab',` field·값 또는 assignment를 다음 단계에 전달한다.
4 [string]$ContainerName = '',정본 W22 disposable restore evidence producer에서 `[string]$ContainerName = '',` field·값 또는 assignment를 다음 단계에 전달한다.
5 [string]$EvidenceDir = 'evidence/w22',정본 W22 disposable restore evidence producer에서 `[string]$EvidenceDir = 'evidence/w22',` field·값 또는 assignment를 다음 단계에 전달한다.
6 [string]$TargetDb = 'financial_core_restore'disposable restore target 이름과 exact allowlist를 다룬다.
7)현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
9Set-StrictMode -Version Latest미정의 변수 등 PowerShell 오류를 조기에 드러낸다.
10$ErrorActionPreference = 'Stop'PowerShell cmdlet 오류를 terminating error로 처리한다.
12if ($TargetDb -cne 'financial_core_restore') {disposable restore target 이름과 exact allowlist를 다룬다.
13 throw 'W22 disposable target allowlist violation'정본 W22 disposable restore evidence producer의 13번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
14}현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
16$root = Split-Path -Parent $PSScriptRoot정본 W22 disposable restore evidence producer에서 `$root = Split-Path -Parent $PSScriptRoot` field·값 또는 assignment를 다음 단계에 전달한다.
17$evidence = if ([IO.Path]::IsPathRooted($EvidenceDir)) {정본 W22 disposable restore evidence producer에서 `$evidence = if ([IO.Path]::IsPathRooted($Evidenc` field·값 또는 assignment를 다음 단계에 전달한다.
18 [IO.Path]::GetFullPath($EvidenceDir)정본 W22 disposable restore evidence producer에서 `[IO.Path]::GetFullPath($EvidenceDir)` field·값 또는 assignment를 다음 단계에 전달한다.
19} else {정본 W22 disposable restore evidence producer의 19번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
20 [IO.Path]::GetFullPath((Join-Path $root $EvidenceDir))정본 W22 disposable restore evidence producer에서 `[IO.Path]::GetFullPath((Join-Path $root $Evidenc` field·값 또는 assignment를 다음 단계에 전달한다.
21}현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
22$tool = Join-Path $PSScriptRoot 'run-w42-restore-drill.ps1'완전한 restore 수행을 맡는 packaged W42 transitive tool을 찾는다.
23$compose = Join-Path $root 'compose.yaml'정본 W22 disposable restore evidence producer에서 `$compose = Join-Path $root 'compose.yaml'` field·값 또는 assignment를 다음 단계에 전달한다.
24$ownedCompose = $false정본 W22 disposable restore evidence producer에서 `$ownedCompose = $false` field·값 또는 assignment를 다음 단계에 전달한다.
25$composeCleanup = $falsesource/target DB와 소유 resource 정리 결과를 evidence에 묶는다.
26$failure = $null정본 W22 disposable restore evidence producer에서 `$failure = $null` field·값 또는 assignment를 다음 단계에 전달한다.
27$body = $null정본 W22 disposable restore evidence producer에서 `$body = $null` field·값 또는 assignment를 다음 단계에 전달한다.
29if (!(Test-Path -LiteralPath $tool -PathType Leaf)) {선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
30 throw 'W22 transitive W42 tool missing'정본 W22 disposable restore evidence producer의 30번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
31}현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
33try {정본 W22 disposable restore evidence producer의 33번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
34 if ($Mode -ceq 'Compose') {선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
35 if ($ContainerName) { throw 'W22 Compose mode rejects ContainerName' }선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
36 if ([string]::IsNullOrWhiteSpace($env:FCL_DB_PASSWORD)) {선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
37 $env:FCL_DB_PASSWORD = 'w22-disposable-password'정본 W22 disposable restore evidence producer에서 `$env:FCL_DB_PASSWORD = 'w22-disposable-password'` field·값 또는 assignment를 다음 단계에 전달한다.
38 }현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
39 # Own the unique Compose project before startup so a partial `up`이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
40 # failure still reaches finally/down and cannot leak resources.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
41 $ownedCompose = $true정본 W22 disposable restore evidence producer에서 `$ownedCompose = $true` field·값 또는 assignment를 다음 단계에 전달한다.
42 & docker compose -f $compose -p $ComposeProject up -d --wait dbW22가 소유한 DB Compose project를 시작하거나 finally에서 정리한다.
43 if ($LASTEXITCODE -ne 0) { throw "W22 compose up exit=$LASTEXITCODE" }선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
44 $ContainerName = (& docker compose -f $compose -p $ComposeProject ps -q db).Trim()W22가 소유한 DB Compose project를 시작하거나 finally에서 정리한다.
45 } elseif ([string]::IsNullOrWhiteSpace($ContainerName)) {정본 W22 disposable restore evidence producer에서 `} elseif ([string]::IsNullOrWhiteSpace($Containe` field·값 또는 assignment를 다음 단계에 전달한다.
46 throw 'W22 Container mode requires ContainerName'정본 W22 disposable restore evidence producer의 46번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
47 }현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
48 if ([string]::IsNullOrWhiteSpace($ContainerName)) {선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
49 throw 'W22 container resolution failed'정본 W22 disposable restore evidence producer의 49번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
50 }현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
52 $output = @(정본 W22 disposable restore evidence producer에서 `$output = @(` field·값 또는 assignment를 다음 단계에 전달한다.
53 & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $tool `정본 W22 disposable restore evidence producer의 53번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
54 -Mode Container `정본 W22 disposable restore evidence producer의 54번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
55 -ContainerName $ContainerName `정본 W22 disposable restore evidence producer의 55번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
56 -AdminDatabase financial_core `정본 W22 disposable restore evidence producer의 56번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
57 -Username app `정본 W22 disposable restore evidence producer의 57번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
58 -TargetDb $TargetDb `disposable restore target 이름과 exact allowlist를 다룬다.
59 -EvidenceDir $evidence 2>&1정본 W22 disposable restore evidence producer의 59번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
60 )현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
61 $nativeExit = $LASTEXITCODE정본 W22 disposable restore evidence producer에서 `$nativeExit = $LASTEXITCODE` field·값 또는 assignment를 다음 단계에 전달한다.
62 if ($nativeExit -ne 0) {선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
63 throw "W22 restore native exit=$nativeExit`n$($output -join "`n")"정본 W22 disposable restore evidence producer에서 `throw "W22 restore native exit=$nativeExit`n$($o` field·값 또는 assignment를 다음 단계에 전달한다.
64 }현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
65 $line = $output | Where-Object { $_ -match '^PASS W42_RESTORE ' } | Select-Object -Last 1inner restore transcript의 exact success marker를 선택한다.
66 if (!$line -or $line -cnotmatch 'row_count=3 ledger_sum=120 mismatch=0 rto_seconds=([0-9]+(?:\.[0-9]+)?) source_dropped=1 target_dropped=1') {복구된 고정 fixture가 정확히 3행인지 기록하거나 검사한다.
67 throw "W22 transcript mismatch: $output"source와 restore 비교 불일치가 정확히 0인지 기록하거나 검사한다.
68 }현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
70 $innerPath = Join-Path $evidence '5-restore-result.json'정본 W22 disposable restore evidence producer에서 `$innerPath = Join-Path $evidence '5-restore-resu` field·값 또는 assignment를 다음 단계에 전달한다.
71 if (!(Test-Path -LiteralPath $innerPath -PathType Leaf)) {선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
72 throw 'W22 inner restore result missing'정본 W22 disposable restore evidence producer의 72번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
73 }현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
74 $inner = Get-Content -Raw -LiteralPath $innerPath | ConvertFrom-Json정본 W22 disposable restore evidence producer에서 `$inner = Get-Content -Raw -LiteralPath $innerPat` field·값 또는 assignment를 다음 단계에 전달한다.
75 if ([int]$inner.row_count -ne 3 -or [long]$inner.ledger_sum -ne 120 -or복구된 고정 fixture가 정확히 3행인지 기록하거나 검사한다.
76 [int]$inner.mismatch_count -ne 0 -or [long]$inner.dump_bytes -le 0) {source와 restore 비교 불일치가 정확히 0인지 기록하거나 검사한다.
77 throw 'W22 inner restore invariant mismatch'source와 restore 비교 불일치가 정확히 0인지 기록하거나 검사한다.
78 }현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
79 $start = [DateTimeOffset]::MinValue정본 W22 disposable restore evidence producer에서 `$start = [DateTimeOffset]::MinValue` field·값 또는 assignment를 다음 단계에 전달한다.
80 $end = [DateTimeOffset]::MinValue정본 W22 disposable restore evidence producer에서 `$end = [DateTimeOffset]::MinValue` field·값 또는 assignment를 다음 단계에 전달한다.
81 if (![DateTimeOffset]::TryParse([string]$inner.start_utc, [ref]$start) -or선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
82 ![DateTimeOffset]::TryParse([string]$inner.end_utc, [ref]$end) -or $end -lt $start) {정본 W22 disposable restore evidence producer에서 `![DateTimeOffset]::TryParse([string]$inner.end_u` field·값 또는 assignment를 다음 단계에 전달한다.
83 throw 'W22 inner restore timestamps invalid'정본 W22 disposable restore evidence producer의 83번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
84 }현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
86 $body = [ordered]@{정본 W22 disposable restore evidence producer에서 `$body = [ordered]@{` field·값 또는 assignment를 다음 단계에 전달한다.
87 owner = 'W22'정본 W22 disposable restore evidence producer에서 `owner = 'W22'` field·값 또는 assignment를 다음 단계에 전달한다.
88 run_id = [guid]::NewGuid().ToString('N')정본 W22 disposable restore evidence producer에서 `run_id = [guid]::NewGuid().ToString('N')` field·값 또는 assignment를 다음 단계에 전달한다.
89 started_at_utc = $start.ToString('o')정본 W22 disposable restore evidence producer에서 `started_at_utc = $start.ToString('o')` field·값 또는 assignment를 다음 단계에 전달한다.
90 completed_at_utc = $end.ToString('o')정본 W22 disposable restore evidence producer에서 `completed_at_utc = $end.ToString('o')` field·값 또는 assignment를 다음 단계에 전달한다.
91 source_db = 'financial_core_restore_source'정본 W22 disposable restore evidence producer에서 `source_db = 'financial_core_restore_source'` field·값 또는 assignment를 다음 단계에 전달한다.
92 target_db = $TargetDbdisposable restore target 이름과 exact allowlist를 다룬다.
93 fixture_schema = 'restore_probe_v1'정본 W22 disposable restore evidence producer에서 `fixture_schema = 'restore_probe_v1'` field·값 또는 assignment를 다음 단계에 전달한다.
94 row_count = 3복구된 고정 fixture가 정확히 3행인지 기록하거나 검사한다.
95 ledger_sum = 120복구된 signed amount 합계가 정확히 120인지 기록하거나 검사한다.
96 mismatch = 0source와 restore 비교 불일치가 정확히 0인지 기록하거나 검사한다.
97 rto_seconds = [double]$inner.rto_secondsdisposable drill의 실측 restore 시간을 기록하되 production RTO로 확대하지 않는다.
98 dump_bytes = [long]$inner.dump_bytes정본 W22 disposable restore evidence producer에서 `dump_bytes = [long]$inner.dump_bytes` field·값 또는 assignment를 다음 단계에 전달한다.
99 source_dropped = 1정본 W22 disposable restore evidence producer에서 `source_dropped = 1` field·값 또는 assignment를 다음 단계에 전달한다.
100 target_dropped = 1정본 W22 disposable restore evidence producer에서 `target_dropped = 1` field·값 또는 assignment를 다음 단계에 전달한다.
101 cleanup = 1source/target DB와 소유 resource 정리 결과를 evidence에 묶는다.
102 native_exit = 0정본 W22 disposable restore evidence producer에서 `native_exit = 0` field·값 또는 assignment를 다음 단계에 전달한다.
103 inner_result_path = 'evidence/w22/5-restore-result.json'정본 W22 disposable restore evidence producer에서 `inner_result_path = 'evidence/w22/5-restore-resu` field·값 또는 assignment를 다음 단계에 전달한다.
104 inner_result_sha256 = (Get-FileHash -LiteralPath $innerPath -Algorithm SHA256).Hash.ToLowerInvariant()현재 file bytes를 64-hex SHA-256 값과 결박하는 field 또는 검사를 다룬다.
105 }현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
106} catch {정본 W22 disposable restore evidence producer의 106번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
107 $failure = $_정본 W22 disposable restore evidence producer에서 `$failure = $_` field·값 또는 assignment를 다음 단계에 전달한다.
108} finally {정본 W22 disposable restore evidence producer의 108번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
109 if ($ownedCompose) {선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
110 & docker compose -f $compose -p $ComposeProject down -v --remove-orphans | Out-NullW22가 소유한 DB Compose project를 시작하거나 finally에서 정리한다.
111 $composeCleanup = ($LASTEXITCODE -eq 0)source/target DB와 소유 resource 정리 결과를 evidence에 묶는다.
112 } else {정본 W22 disposable restore evidence producer의 112번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
113 $composeCleanup = $truesource/target DB와 소유 resource 정리 결과를 evidence에 묶는다.
114 }현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
115}현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
117if (!$composeCleanup) {source/target DB와 소유 resource 정리 결과를 evidence에 묶는다.
118 if ($null -ne $failure) {선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
119 throw "W22 restore failed and owned Compose cleanup failed: $($failure.Exception.Message)"source/target DB와 소유 resource 정리 결과를 evidence에 묶는다.
120 }현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
121 throw 'W22 owned Compose cleanup failed'source/target DB와 소유 resource 정리 결과를 evidence에 묶는다.
122}현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
123if ($null -ne $failure) { throw $failure }선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
124if ($null -eq $body) { throw 'W22 restore produced no canonical result' }선행 invariant가 깨졌을 때 다음 단계로 진행하지 않도록 fail-closed guard를 적용한다.
126$body['compose_cleanup'] = if ($ownedCompose) { 1 } else { 'not-owned' }source/target DB와 소유 resource 정리 결과를 evidence에 묶는다.
127New-Item -ItemType Directory -Force $evidence | Out-Null정본 W22 disposable restore evidence producer의 127번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
128$resultPath = Join-Path $evidence 'restore-result.json'정본 W22 disposable restore evidence producer에서 `$resultPath = Join-Path $evidence 'restore-resul` field·값 또는 assignment를 다음 단계에 전달한다.
129$temporary = "$resultPath.tmp"정본 W22 disposable restore evidence producer에서 `$temporary = "$resultPath.tmp"` field·값 또는 assignment를 다음 단계에 전달한다.
130$body | ConvertTo-Json -Depth 5 | Set-Content -Encoding utf8 -LiteralPath $temporary정본 W22 disposable restore evidence producer의 130번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
131Move-Item -LiteralPath $temporary -Destination $resultPath -Force완성된 temporary evidence를 final path로 원자적으로 교체한다.
133"W22_RESTORE_GREEN row_count=3 ledger_sum=120 mismatch=0 rto_seconds=$($body.rto_seconds) cleanup=1 native_exit=0"복구된 고정 fixture가 정확히 3행인지 기록하거나 검사한다.
07

STEP 07 / 13

기존 수준의 한 줄 읽기·문법 해부

쉬운 설명 다음에 문법과 실행 순서를 정밀하게 읽습니다.

한 줄로 읽기

고정 3행을 별도 DB에 dump/restore해 3·120·0과 cleanup을 검증하고 canonical restore-result.json을 atomic publish하는 W22 packaged owner다. 다만 production RPO/RTO 보장이 아니다

문법 해부

  • `try/catch/finally`는 실패 여부와 무관하게 소유한 Compose cleanup을 수행한다.
  • native command 뒤 `$LASTEXITCODE`와 transcript regex·inner JSON을 함께 검증한다.

실행 순서

  1. allowlist와 transitive tool을 검사한다.
  2. Compose 또는 caller container를 선택한다.
  3. W42 restore 결과 3·120·0을 재검증한다.
  4. cleanup 뒤 restore-result.json을 atomic publish한다.

W22 조각별 정밀 해설

F06-C01 · 원문 1–12줄
문법 해부
1~12줄의 `원문 1–12줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `row_count=3`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `row_count=3`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: production RPO/RTO 보장이 아니다.
착각 방지
`원문 1–12줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: production RPO/RTO 보장이 아니다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F06-C02 · 원문 13–24줄
문법 해부
13~24줄의 `원문 13–24줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `ledger_sum=120`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `ledger_sum=120`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: run-w42-restore-drill.ps1에 transitive 의존한다.
착각 방지
`원문 13–24줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: run-w42-restore-drill.ps1에 transitive 의존한다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F06-C03 · 원문 25–36줄
문법 해부
25~36줄의 `원문 25–36줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `mismatch=0`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `mismatch=0`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: 허용 target DB 이름만 쓴다.
착각 방지
`원문 25–36줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: 허용 target DB 이름만 쓴다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F06-C04 · 원문 37–48줄
문법 해부
37~48줄의 `원문 37–48줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `cleanup=1`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `cleanup=1`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: Docker·PostgreSQL 실행 환경이 필요하다.
착각 방지
`원문 37–48줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: Docker·PostgreSQL 실행 환경이 필요하다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F06-C05 · 원문 49–60줄
문법 해부
49~60줄의 `원문 49–60줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `W22_RESTORE_GREEN`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `W22_RESTORE_GREEN`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: production RPO/RTO 보장이 아니다.
착각 방지
`원문 49–60줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: production RPO/RTO 보장이 아니다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F06-C06 · 원문 61–72줄
문법 해부
61~72줄의 `원문 61–72줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `row_count=3`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `row_count=3`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: run-w42-restore-drill.ps1에 transitive 의존한다.
착각 방지
`원문 61–72줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: run-w42-restore-drill.ps1에 transitive 의존한다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F06-C07 · 원문 73–84줄
문법 해부
73~84줄의 `원문 73–84줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `ledger_sum=120`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `ledger_sum=120`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: 허용 target DB 이름만 쓴다.
착각 방지
`원문 73–84줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: 허용 target DB 이름만 쓴다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F06-C08 · 원문 85–96줄
문법 해부
85~96줄의 `원문 85–96줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `mismatch=0`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `mismatch=0`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: Docker·PostgreSQL 실행 환경이 필요하다.
착각 방지
`원문 85–96줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: Docker·PostgreSQL 실행 환경이 필요하다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F06-C09 · 원문 97–108줄
문법 해부
97~108줄의 `원문 97–108줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `cleanup=1`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `cleanup=1`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: production RPO/RTO 보장이 아니다.
착각 방지
`원문 97–108줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: production RPO/RTO 보장이 아니다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F06-C10 · 원문 109–120줄
문법 해부
109~120줄의 `원문 109–120줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `W22_RESTORE_GREEN`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `W22_RESTORE_GREEN`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: run-w42-restore-drill.ps1에 transitive 의존한다.
착각 방지
`원문 109–120줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: run-w42-restore-drill.ps1에 transitive 의존한다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F06-C11 · 원문 121–132줄
문법 해부
121~132줄의 `원문 121–132줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `row_count=3`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `row_count=3`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: 허용 target DB 이름만 쓴다.
착각 방지
`원문 121–132줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: 허용 target DB 이름만 쓴다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F06-C12 · 원문 133–133줄
문법 해부
133~133줄의 `원문 133–133줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `ledger_sum=120`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `ledger_sum=120`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: Docker·PostgreSQL 실행 환경이 필요하다.
착각 방지
`원문 133–133줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: Docker·PostgreSQL 실행 환경이 필요하다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
반례
  1. 겉보기에는 맞지만 깨지는 예는?

  2. backup 파일 존재만으로 복구 가능이라 한다

  3. 그 상태는 owner·입력·관찰 중 한 칸이 비어 있어.

  4. 수정한 뒤 같은 source와 hash로 다시 대조해.

08

STEP 08 / 13

실제 값 따라가기

같은 입력값이 어느 줄을 지나 어떤 결과가 되는지 추적합니다.

순서들어온 값코드가 하는 일나온 값·상태경계
F06-T01 startupCompose modeup --wait dbcontainer id부분 up도 finally 대상
F06-T02 restoreW42 transcript+JSONdouble validation3/120/0+rtoproduction RTO 아님
F06-T03 publishcleaned lifecycletmp→moveW22_RESTORE_GREENContainer mode container는 caller 소유
책임 경계
  1. 이 항목의 마지막 책임선은?

  2. 직접 역할은 `정본 W22 disposable restore evidence producer`이야.

  3. 대표 경계는 `Docker·PostgreSQL 실행 환경이 필요하다`이야.

  4. 정본/비정본 label과 evidence owner까지 확인하면 끝이야.

09

STEP 09 / 13

GitHub·AWS·PowerShell·PostgreSQL 내부에서 벌어지는 일

GitHub·AWS·PowerShell·PostgreSQL에서 실제로 일어나는 일과 증명 범위를 구분합니다.

PowerShell owner

Compose mode에서 project ownership을 startup 전에 잡는다.

Container mode는 전달받은 container를 지우지 않는다.
PostgreSQL drill

별도 source/target DB와 custom dump를 사용한다.

실서비스 backup 정책을 대신하지 않는다.
evidence

inner result hash·timestamps·dump bytes를 outer JSON에 묶는다.

marker 한 줄만 저장하면 부족하다.
10

STEP 10 / 13

흔한 착각과 틀린 예

그럴듯하지만 틀린 해석을 반례로 고칩니다.

❌ backup 파일 존재만으로 복구 가능이라 한다

왜 틀리나 정본 W22 disposable restore evidence producer의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 allowlist와 transitive tool을 검사한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `production RPO/RTO 보장이 아니다` 상태인데도 Green을 주장하게 된다.

❌ target DB allowlist를 넓힌다

왜 틀리나 정본 W22 disposable restore evidence producer의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 Compose 또는 caller container를 선택한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `run-w42-restore-drill.ps1에 transitive 의존한다` 상태인데도 Green을 주장하게 된다.

❌ W42 transcript만 보고 inner JSON을 생략한다

왜 틀리나 정본 W22 disposable restore evidence producer의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 W42 restore 결과 3·120·0을 재검증한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `허용 target DB 이름만 쓴다` 상태인데도 Green을 주장하게 된다.

❌ finally cleanup 전에 Green JSON을 발급한다

왜 틀리나 정본 W22 disposable restore evidence producer의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 cleanup 뒤 restore-result.json을 atomic publish한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `Docker·PostgreSQL 실행 환경이 필요하다` 상태인데도 Green을 주장하게 된다.

❌ 실측 초를 production RTO 보장으로 부른다

왜 틀리나 정본 W22 disposable restore evidence producer의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 cleanup 뒤 restore-result.json을 atomic publish한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `production RPO/RTO 보장이 아니다` 상태인데도 Green을 주장하게 된다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

이 코드가 책임지지 않는 일을 분리합니다.

직접 미보장

production RPO/RTO 보장이 아니다

이 책임을 맡는 곳: 별도 외부/selector 실행
직접 미보장

run-w42-restore-drill.ps1에 transitive 의존한다

이 책임을 맡는 곳: secret·운영 정책
직접 미보장

허용 target DB 이름만 쓴다

이 책임을 맡는 곳: infrastructure·사람 검토
직접 미보장

Docker·PostgreSQL 실행 환경이 필요하다

이 책임을 맡는 곳: owner lifecycle
12

STEP 12 / 13

직접 다시 써보기

뜻 → 조각 → 전체 코드 순서로 다시 씁니다.

1단계 · 뜻부터 복원

다음 역할을 고정값과 미보장 경계까지 말한다: 고정 3행을 별도 DB에 dump/restore해 3·120·0과 cleanup을 검증하고 canonical restore-result.json을 atomic publish하는 W22 packaged owner다.

2단계 · 코드 조각 재조립

  1. 원문 1–12줄
  2. 원문 13–24줄
  3. 원문 25–36줄
  4. 원문 37–48줄
  5. 원문 49–60줄
  6. 원문 61–72줄
  7. 원문 73–84줄
  8. 원문 85–96줄
  9. 원문 97–108줄
  10. 원문 109–120줄
  11. 원문 121–132줄
  12. 원문 133–133줄

3단계 · 파일 전체 다시 쓰기

133개 물리 줄을 원본 순서로 복원하고 SHA-256 eb8cd1d71eeac0f1359441deaba4e0c596938f9d6dc3fc93a0319cf2594f6a25와 대조한다.

자가 점검
  • 원본 source/template bytes를 바꾸지 않았는가?
  • 외부 미실행과 local restore Green을 구분했는가?
  • secret 원문을 evidence에 남기지 않았는가?
  • D7 checked_at 충돌과 사람 검토 경계를 보았는가?
  • Q35/Q36을 workbook 정본 답안이라고 부르지 않았는가?
13

STEP 13 / 13

전체 원본 source

감사로 고정한 전체 source를 가감 없이 확인합니다.

원문 정본 전체 source 확인하기
원문 정본 · 완전한 packaged PowerShell sourcescripts/run-w22-restore.ps1SHA-256 eb8cd1d71eeac0f1359441deaba4e0c596938f9d6dc3fc93a0319cf2594f6a25
run-w22-restore.ps1 — disposable restore 3·120·0 owner 전체
param(
    [ValidateSet('Compose','Container')][string]$Mode = 'Compose',
    [string]$ComposeProject = 'w22-restore-lab',
    [string]$ContainerName = '',
    [string]$EvidenceDir = 'evidence/w22',
    [string]$TargetDb = 'financial_core_restore'
)

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

if ($TargetDb -cne 'financial_core_restore') {
    throw 'W22 disposable target allowlist violation'
}

$root = Split-Path -Parent $PSScriptRoot
$evidence = if ([IO.Path]::IsPathRooted($EvidenceDir)) {
    [IO.Path]::GetFullPath($EvidenceDir)
} else {
    [IO.Path]::GetFullPath((Join-Path $root $EvidenceDir))
}
$tool = Join-Path $PSScriptRoot 'run-w42-restore-drill.ps1'
$compose = Join-Path $root 'compose.yaml'
$ownedCompose = $false
$composeCleanup = $false
$failure = $null
$body = $null

if (!(Test-Path -LiteralPath $tool -PathType Leaf)) {
    throw 'W22 transitive W42 tool missing'
}

try {
    if ($Mode -ceq 'Compose') {
        if ($ContainerName) { throw 'W22 Compose mode rejects ContainerName' }
        if ([string]::IsNullOrWhiteSpace($env:FCL_DB_PASSWORD)) {
            $env:FCL_DB_PASSWORD = 'w22-disposable-password'
        }
        # Own the unique Compose project before startup so a partial `up`
        # failure still reaches finally/down and cannot leak resources.
        $ownedCompose = $true
        & docker compose -f $compose -p $ComposeProject up -d --wait db
        if ($LASTEXITCODE -ne 0) { throw "W22 compose up exit=$LASTEXITCODE" }
        $ContainerName = (& docker compose -f $compose -p $ComposeProject ps -q db).Trim()
    } elseif ([string]::IsNullOrWhiteSpace($ContainerName)) {
        throw 'W22 Container mode requires ContainerName'
    }
    if ([string]::IsNullOrWhiteSpace($ContainerName)) {
        throw 'W22 container resolution failed'
    }

    $output = @(
        & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $tool `
            -Mode Container `
            -ContainerName $ContainerName `
            -AdminDatabase financial_core `
            -Username app `
            -TargetDb $TargetDb `
            -EvidenceDir $evidence 2>&1
    )
    $nativeExit = $LASTEXITCODE
    if ($nativeExit -ne 0) {
        throw "W22 restore native exit=$nativeExit`n$($output -join "`n")"
    }
    $line = $output | Where-Object { $_ -match '^PASS W42_RESTORE ' } | Select-Object -Last 1
    if (!$line -or $line -cnotmatch 'row_count=3 ledger_sum=120 mismatch=0 rto_seconds=([0-9]+(?:\.[0-9]+)?) source_dropped=1 target_dropped=1') {
        throw "W22 transcript mismatch: $output"
    }

    $innerPath = Join-Path $evidence '5-restore-result.json'
    if (!(Test-Path -LiteralPath $innerPath -PathType Leaf)) {
        throw 'W22 inner restore result missing'
    }
    $inner = Get-Content -Raw -LiteralPath $innerPath | ConvertFrom-Json
    if ([int]$inner.row_count -ne 3 -or [long]$inner.ledger_sum -ne 120 -or
        [int]$inner.mismatch_count -ne 0 -or [long]$inner.dump_bytes -le 0) {
        throw 'W22 inner restore invariant mismatch'
    }
    $start = [DateTimeOffset]::MinValue
    $end = [DateTimeOffset]::MinValue
    if (![DateTimeOffset]::TryParse([string]$inner.start_utc, [ref]$start) -or
        ![DateTimeOffset]::TryParse([string]$inner.end_utc, [ref]$end) -or $end -lt $start) {
        throw 'W22 inner restore timestamps invalid'
    }

    $body = [ordered]@{
        owner = 'W22'
        run_id = [guid]::NewGuid().ToString('N')
        started_at_utc = $start.ToString('o')
        completed_at_utc = $end.ToString('o')
        source_db = 'financial_core_restore_source'
        target_db = $TargetDb
        fixture_schema = 'restore_probe_v1'
        row_count = 3
        ledger_sum = 120
        mismatch = 0
        rto_seconds = [double]$inner.rto_seconds
        dump_bytes = [long]$inner.dump_bytes
        source_dropped = 1
        target_dropped = 1
        cleanup = 1
        native_exit = 0
        inner_result_path = 'evidence/w22/5-restore-result.json'
        inner_result_sha256 = (Get-FileHash -LiteralPath $innerPath -Algorithm SHA256).Hash.ToLowerInvariant()
    }
} catch {
    $failure = $_
} finally {
    if ($ownedCompose) {
        & docker compose -f $compose -p $ComposeProject down -v --remove-orphans | Out-Null
        $composeCleanup = ($LASTEXITCODE -eq 0)
    } else {
        $composeCleanup = $true
    }
}

if (!$composeCleanup) {
    if ($null -ne $failure) {
        throw "W22 restore failed and owned Compose cleanup failed: $($failure.Exception.Message)"
    }
    throw 'W22 owned Compose cleanup failed'
}
if ($null -ne $failure) { throw $failure }
if ($null -eq $body) { throw 'W22 restore produced no canonical result' }

$body['compose_cleanup'] = if ($ownedCompose) { 1 } else { 'not-owned' }
New-Item -ItemType Directory -Force $evidence | Out-Null
$resultPath = Join-Path $evidence 'restore-result.json'
$temporary = "$resultPath.tmp"
$body | ConvertTo-Json -Depth 5 | Set-Content -Encoding utf8 -LiteralPath $temporary
Move-Item -LiteralPath $temporary -Destination $resultPath -Force

"W22_RESTORE_GREEN row_count=3 ledger_sum=120 mismatch=0 rto_seconds=$($body.rto_seconds) cleanup=1 native_exit=0"
07

비용·teardown inventory — checked_at 계약까지 닫기

illustrative/json/W22-D7-resource-inventory.json

학습용 예시 · PDF JSON schema/worksheet · 정본 답안 아님 · 비실행 · 학습용 예시 · 정본 답안 아님 · W22-F07
34줄 연결34줄 번역4 chunks
01

STEP 01 / 13

오늘 이 코드에서 해결할 문제

무엇을 이해해야 하는지 질문부터 잡습니다.

오늘의 한 문장

EC2/ECS·RDS·ECR·NAT와 budget alarm을 teardown 뒤 다시 inventory하는 D7 worksheet 보완 예시다.

  1. `MANUAL_REVIEW_REQUIRED`은 어느 줄에서 생길까?
  2. 입력→guard→관찰→cleanup 순서는 무엇인가?
  3. local owner와 external human review는 누구인가?
  4. 직접 관찰하지 않은 Green은 무엇인가?
  5. 반례는 `example 값이 남으면 실제 inventory가 아니다`이라는 경계와 어떻게 연결되는가?
이 파일에서 끝까지 다시 쓰는 값MANUAL_REVIEW_REQUIREDap-northeast-2resourceschecked_atbudget_alarm
02

STEP 02 / 13

아주 짧게: 이 코드는 왜 필요할까?

웹소설 대신 이 코드가 필요한 이유만 두 문단으로 쉽게 봅니다.

STARRY가 GitHub run표·AWS 출입증·DB 복구 영수증·SQL 결과표를 서로 다른 칸에 놓는다.

비용·teardown inventory — checked_at 계약까지 닫기 ― 증거 흐름으로 바꾸기

EC2/ECS·RDS·ECR·NAT와 budget alarm을 teardown 뒤 다시 inventory하는 D7 worksheet 보완 예시다.

핵심값 MANUAL_REVIEW_REQUIRED, ap-northeast-2, resources, checked_at, budget_alarm을 원본 줄로 따라가되, `example 값이 남으면 실제 inventory가 아니다`까지 함께 표시해 Green 범위를 부풀리지 않는다.

딱 여기까지만 비유는 owner와 순서를 기억하게 할 뿐 외부 실행·AWS 계정 상태·PostgreSQL restore·SQL 결과를 자동 증명하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

생활 비유와 실제 코드의 경계를 함께 확인합니다.

원문 1–10줄

1~10줄을 한 덩어리로 읽어 1번째 움직임을 본다. EC2/ECS·RDS·ECR·NAT와 budget alarm을 teardown 뒤 다시 inventory하는 D7 worksheet 보완 예시다.

코드 연결
1~10줄
비유
여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부
비유의 끝
example 값이 남으면 실제 inventory가 아니다

원문 11–20줄

11~20줄을 한 덩어리로 읽어 2번째 움직임을 본다. EC2/ECS·RDS·ECR·NAT와 budget alarm을 teardown 뒤 다시 inventory하는 D7 worksheet 보완 예시다.

코드 연결
11~20줄
비유
여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부
비유의 끝
PDF worksheet에는 validator 필수 checked_at이 빠져 있다

원문 21–30줄

21~30줄을 한 덩어리로 읽어 3번째 움직임을 본다. EC2/ECS·RDS·ECR·NAT와 budget alarm을 teardown 뒤 다시 inventory하는 D7 worksheet 보완 예시다.

코드 연결
21~30줄
비유
여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부
비유의 끝
의도적 보존 resource는 이유와 만료일이 필요하다
문제의 첫 장면
  1. 첫 고정값은 `MANUAL_REVIEW_REQUIRED` 맞아?

  2. EC2/ECS·RDS·ECR·NAT와 budget alarm을 teardown 뒤 다시 inventory하는 D7 worksheet 보완 예시다.

  3. 원문에서 `MANUAL_REVIEW_REQUIRED`이 생기는 위치를 찾자.

  4. 그리고 `example 값이 남으면 실제 inventory가 아니다`도 같이 적어.

입력에서 결과까지
  1. `ap-northeast-2`은 언제 생겨?

  2. budget·owner·expiresAt을 먼저 만든다. → 생성 전 inventory를 저장한다.

  3. 실습 뒤 resource를 삭제·보존 판정한다. → checked_at과 screenshot hash로 teardown 후 상태를 묶는다.

  4. 관찰값과 `PDF worksheet에는 validator 필수 checked_at이 빠져 있다`을 분리하면 돼.

04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

감사 규칙상 연결 대상인 원본 34줄을 빠짐없이 연결합니다.

단어 몇 개만 뽑은 표가 아닙니다.학습용 예시 · PDF JSON schema/worksheet · 정본 답안 아님 · 비실행에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.34 / 34 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F07-L01 { 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `MANUAL_REVIEW_REQUIRED` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
example 값이 남으면 실제 inventory가 아니다
2줄F07-L02 "_provenance": "학습용 예시 · PDF 비용·teardown worksheet 보완본 · 정본 답안 아님 · 비실행", 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 비용·resource teardown worksheet에서 `"_provenance": "학습용 예시 · PDF 비용·teardown workshe` field·값 또는 assignment를 다음 단계에 전달한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `ap-northeast-2` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
PDF worksheet에는 validator 필수 checked_at이 빠져 있다
3줄F07-L03 "status": "MANUAL_REVIEW_REQUIRED", 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 자동 shape/hash 검사 뒤에도 사람의 의미 검토가 남았음을 고정한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `resources` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
의도적 보존 resource는 이유와 만료일이 필요하다
4줄F07-L04 "region": "ap-northeast-2", 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 비용·resource teardown worksheet에서 `"region": "ap-northeast-2",` field·값 또는 assignment를 다음 단계에 전달한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `checked_at` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
console 화면은 exact screenshot hash와 묶어야 한다
5줄F07-L05 "checked_at": "EXAMPLE_UTC_TIMESTAMP_REQUIRED_BY_D7_VALIDATOR", 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 D7 validator와 호환되도록 inventory 관찰 시각 field를 둔다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `budget_alarm` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
example 값이 남으면 실제 inventory가 아니다
6줄F07-L06 "resources": [ 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 teardown 전후 대조할 AWS resource 목록 배열을 연다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `MANUAL_REVIEW_REQUIRED` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
PDF worksheet에는 validator 필수 checked_at이 빠져 있다
7줄F07-L07 { 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `ap-northeast-2` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
의도적 보존 resource는 이유와 만료일이 필요하다
8줄F07-L08 "type": "EC2_OR_ECS", 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 비용·resource teardown worksheet에서 `"type": "EC2_OR_ECS",` field·값 또는 assignment를 다음 단계에 전달한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `resources` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
console 화면은 exact screenshot hash와 묶어야 한다
9줄F07-L09 "id": "EXAMPLE_RESOURCE_ID", 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 비용·resource teardown worksheet에서 `"id": "EXAMPLE_RESOURCE_ID",` field·값 또는 assignment를 다음 단계에 전달한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `checked_at` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
example 값이 남으면 실제 inventory가 아니다
10줄F07-L10 "state": "terminated-or-zero-tasks" 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 비용·resource teardown worksheet에서 `"state": "terminated-or-zero-tasks"` field·값 또는 assignment를 다음 단계에 전달한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `budget_alarm` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
PDF worksheet에는 validator 필수 checked_at이 빠져 있다
11줄F07-L11 }, 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `MANUAL_REVIEW_REQUIRED` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
의도적 보존 resource는 이유와 만료일이 필요하다
12줄F07-L12 { 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `ap-northeast-2` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
console 화면은 exact screenshot hash와 묶어야 한다
13줄F07-L13 "type": "RDS", 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 private PostgreSQL 5432와 application SG 사이의 DB 경계를 표현한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `resources` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
example 값이 남으면 실제 inventory가 아니다
14줄F07-L14 "id": "EXAMPLE_RESOURCE_ID", 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 비용·resource teardown worksheet에서 `"id": "EXAMPLE_RESOURCE_ID",` field·값 또는 assignment를 다음 단계에 전달한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `checked_at` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
PDF worksheet에는 validator 필수 checked_at이 빠져 있다
15줄F07-L15 "state": "deleted-or-approved-retained" 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 비용·resource teardown worksheet에서 `"state": "deleted-or-approved-retained"` field·값 또는 assignment를 다음 단계에 전달한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `budget_alarm` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
의도적 보존 resource는 이유와 만료일이 필요하다
16줄F07-L16 }, 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `MANUAL_REVIEW_REQUIRED` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
console 화면은 exact screenshot hash와 묶어야 한다
17줄F07-L17 { 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `ap-northeast-2` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
example 값이 남으면 실제 inventory가 아니다
18줄F07-L18 "type": "ECR", 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 비용·resource teardown worksheet에서 `"type": "ECR",` field·값 또는 assignment를 다음 단계에 전달한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `resources` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
PDF worksheet에는 validator 필수 checked_at이 빠져 있다
19줄F07-L19 "id": "EXAMPLE_REPOSITORY", 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 비용·resource teardown worksheet에서 `"id": "EXAMPLE_REPOSITORY",` field·값 또는 assignment를 다음 단계에 전달한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `checked_at` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
의도적 보존 resource는 이유와 만료일이 필요하다
20줄F07-L20 "digest": "sha256:EXAMPLE_DIGEST" 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 현재 file bytes를 64-hex SHA-256 값과 결박하는 field 또는 검사를 다룬다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `budget_alarm` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
console 화면은 exact screenshot hash와 묶어야 한다
21줄F07-L21 }, 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `MANUAL_REVIEW_REQUIRED` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
example 값이 남으면 실제 inventory가 아니다
22줄F07-L22 { 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `ap-northeast-2` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
PDF worksheet에는 validator 필수 checked_at이 빠져 있다
23줄F07-L23 "type": "NAT_GATEWAY", 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 비용·resource teardown worksheet에서 `"type": "NAT_GATEWAY",` field·값 또는 assignment를 다음 단계에 전달한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `resources` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
의도적 보존 resource는 이유와 만료일이 필요하다
24줄F07-L24 "id": "EXAMPLE_IF_CREATED", 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 비용·resource teardown worksheet에서 `"id": "EXAMPLE_IF_CREATED",` field·값 또는 assignment를 다음 단계에 전달한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `checked_at` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
console 화면은 exact screenshot hash와 묶어야 한다
25줄F07-L25 "state": "deleted" 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 비용·resource teardown worksheet에서 `"state": "deleted"` field·값 또는 assignment를 다음 단계에 전달한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `budget_alarm` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
example 값이 남으면 실제 inventory가 아니다
26줄F07-L26 } 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `MANUAL_REVIEW_REQUIRED` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
PDF worksheet에는 validator 필수 checked_at이 빠져 있다
27줄F07-L27 ], 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `ap-northeast-2` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
의도적 보존 resource는 이유와 만료일이 필요하다
28줄F07-L28 "budget_alarm": { 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 resource 생성 전 비용 경계와 알림 상태를 기록한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `resources` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
console 화면은 exact screenshot hash와 묶어야 한다
29줄F07-L29 "currency": "USD", 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 비용·resource teardown worksheet에서 `"currency": "USD",` field·값 또는 assignment를 다음 단계에 전달한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `checked_at` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
example 값이 남으면 실제 inventory가 아니다
30줄F07-L30 "threshold": "EXAMPLE_LIMIT", 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 비용·resource teardown worksheet에서 `"threshold": "EXAMPLE_LIMIT",` field·값 또는 assignment를 다음 단계에 전달한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `budget_alarm` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
PDF worksheet에는 validator 필수 checked_at이 빠져 있다
31줄F07-L31 "notification_tested": false 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 비용·resource teardown worksheet에서 `"notification_tested": false` field·값 또는 assignment를 다음 단계에 전달한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `MANUAL_REVIEW_REQUIRED` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
의도적 보존 resource는 이유와 만료일이 필요하다
32줄F07-L32 }, 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `ap-northeast-2` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
console 화면은 exact screenshot hash와 묶어야 한다
33줄F07-L33 "official_console_screenshot_sha256": "EXAMPLE_AFTER_REAL_EXTERNAL_RUN" 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 현재 file bytes를 64-hex SHA-256 값과 결박하는 field 또는 검사를 다룬다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `resources` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
example 값이 남으면 실제 inventory가 아니다
34줄F07-L34 } 여행 전 예산 봉투를 만들고, 돌아온 뒤 대여품 목록과 반납 시각을 다시 적어 남은 비용을 확인하는 teardown 장부 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
tagged AWS resource·budget alarm·teardown 시각
결과·효과
이 줄 뒤에는 항목 전체의 `checked_at` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
PDF worksheet에는 validator 필수 checked_at이 빠져 있다
Green 범위
  1. marker나 파일이 보이면 전부 성공이야?

  2. 아니. source가 직접 검증한 범위만 말해야 해.

  3. 직접 연결되는 대표 값은 `budget_alarm`이야.

  4. `의도적 보존 resource는 이유와 만료일이 필요하다`는 별도 증거가 필요해.

05

STEP 05 / 13

원본 코드 조각

원본을 4개 의미 조각으로 나누어 그대로 확인합니다.

파일을 한꺼번에 외우지 않고 실행 의미가 이어지는 작은 조각으로 봅니다. 아래 코드는 prompt·fixture·가정을 밝힌 학습용 예시 source이며, 제공 정본 답안이 아닙니다.

F07-C01 · 원문 1–10줄1–10줄
1–10줄 원본
{
  "_provenance": "학습용 예시 · PDF 비용·teardown worksheet 보완본 · 정본 답안 아님 · 비실행",
  "status": "MANUAL_REVIEW_REQUIRED",
  "region": "ap-northeast-2",
  "checked_at": "EXAMPLE_UTC_TIMESTAMP_REQUIRED_BY_D7_VALIDATOR",
  "resources": [
    {
      "type": "EC2_OR_ECS",
      "id": "EXAMPLE_RESOURCE_ID",
      "state": "terminated-or-zero-tasks"
F07-C02 · 원문 11–20줄11–20줄
11–20줄 원본
    },
    {
      "type": "RDS",
      "id": "EXAMPLE_RESOURCE_ID",
      "state": "deleted-or-approved-retained"
    },
    {
      "type": "ECR",
      "id": "EXAMPLE_REPOSITORY",
      "digest": "sha256:EXAMPLE_DIGEST"
F07-C03 · 원문 21–30줄21–30줄
21–30줄 원본
    },
    {
      "type": "NAT_GATEWAY",
      "id": "EXAMPLE_IF_CREATED",
      "state": "deleted"
    }
  ],
  "budget_alarm": {
    "currency": "USD",
    "threshold": "EXAMPLE_LIMIT",
F07-C04 · 원문 31–34줄31–34줄
31–34줄 원본
    "notification_tested": false
  },
  "official_console_screenshot_sha256": "EXAMPLE_AFTER_REAL_EXTERNAL_RUN"
}
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

비어 있지 않은 34줄을 모두 한국어로 옮깁니다.

전체 번역 34 / 34

비어 있지 않은 원본 줄은 하나도 생략하지 않습니다.

원본한국어 번역
1{현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
2 "_provenance": "학습용 예시 · PDF 비용·teardown worksheet 보완본 · 정본 답안 아님 · 비실행",비용·resource teardown worksheet에서 `"_provenance": "학습용 예시 · PDF 비용·teardown workshe` field·값 또는 assignment를 다음 단계에 전달한다.
3 "status": "MANUAL_REVIEW_REQUIRED",자동 shape/hash 검사 뒤에도 사람의 의미 검토가 남았음을 고정한다.
4 "region": "ap-northeast-2",비용·resource teardown worksheet에서 `"region": "ap-northeast-2",` field·값 또는 assignment를 다음 단계에 전달한다.
5 "checked_at": "EXAMPLE_UTC_TIMESTAMP_REQUIRED_BY_D7_VALIDATOR",D7 validator와 호환되도록 inventory 관찰 시각 field를 둔다.
6 "resources": [teardown 전후 대조할 AWS resource 목록 배열을 연다.
7 {현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
8 "type": "EC2_OR_ECS",비용·resource teardown worksheet에서 `"type": "EC2_OR_ECS",` field·값 또는 assignment를 다음 단계에 전달한다.
9 "id": "EXAMPLE_RESOURCE_ID",비용·resource teardown worksheet에서 `"id": "EXAMPLE_RESOURCE_ID",` field·값 또는 assignment를 다음 단계에 전달한다.
10 "state": "terminated-or-zero-tasks"비용·resource teardown worksheet에서 `"state": "terminated-or-zero-tasks"` field·값 또는 assignment를 다음 단계에 전달한다.
11 },현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
12 {현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
13 "type": "RDS",private PostgreSQL 5432와 application SG 사이의 DB 경계를 표현한다.
14 "id": "EXAMPLE_RESOURCE_ID",비용·resource teardown worksheet에서 `"id": "EXAMPLE_RESOURCE_ID",` field·값 또는 assignment를 다음 단계에 전달한다.
15 "state": "deleted-or-approved-retained"비용·resource teardown worksheet에서 `"state": "deleted-or-approved-retained"` field·값 또는 assignment를 다음 단계에 전달한다.
16 },현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
17 {현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
18 "type": "ECR",비용·resource teardown worksheet에서 `"type": "ECR",` field·값 또는 assignment를 다음 단계에 전달한다.
19 "id": "EXAMPLE_REPOSITORY",비용·resource teardown worksheet에서 `"id": "EXAMPLE_REPOSITORY",` field·값 또는 assignment를 다음 단계에 전달한다.
20 "digest": "sha256:EXAMPLE_DIGEST"현재 file bytes를 64-hex SHA-256 값과 결박하는 field 또는 검사를 다룬다.
21 },현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
22 {현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
23 "type": "NAT_GATEWAY",비용·resource teardown worksheet에서 `"type": "NAT_GATEWAY",` field·값 또는 assignment를 다음 단계에 전달한다.
24 "id": "EXAMPLE_IF_CREATED",비용·resource teardown worksheet에서 `"id": "EXAMPLE_IF_CREATED",` field·값 또는 assignment를 다음 단계에 전달한다.
25 "state": "deleted"비용·resource teardown worksheet에서 `"state": "deleted"` field·값 또는 assignment를 다음 단계에 전달한다.
26 }현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
27 ],현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
28 "budget_alarm": {resource 생성 전 비용 경계와 알림 상태를 기록한다.
29 "currency": "USD",비용·resource teardown worksheet에서 `"currency": "USD",` field·값 또는 assignment를 다음 단계에 전달한다.
30 "threshold": "EXAMPLE_LIMIT",비용·resource teardown worksheet에서 `"threshold": "EXAMPLE_LIMIT",` field·값 또는 assignment를 다음 단계에 전달한다.
31 "notification_tested": false비용·resource teardown worksheet에서 `"notification_tested": false` field·값 또는 assignment를 다음 단계에 전달한다.
32 },현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
33 "official_console_screenshot_sha256": "EXAMPLE_AFTER_REAL_EXTERNAL_RUN"현재 file bytes를 64-hex SHA-256 값과 결박하는 field 또는 검사를 다룬다.
34}현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
07

STEP 07 / 13

기존 수준의 한 줄 읽기·문법 해부

쉬운 설명 다음에 문법과 실행 순서를 정밀하게 읽습니다.

한 줄로 읽기

EC2/ECS·RDS·ECR·NAT와 budget alarm을 teardown 뒤 다시 inventory하는 D7 worksheet 보완 예시다. 다만 example 값이 남으면 실제 inventory가 아니다

문법 해부

  • JSON `resources` 배열이 resource type·id·state를 한 행씩 기록한다.
  • 인접 D7 validator가 `resources`뿐 아니라 top-level `checked_at`도 요구한다.

실행 순서

  1. budget·owner·expiresAt을 먼저 만든다.
  2. 생성 전 inventory를 저장한다.
  3. 실습 뒤 resource를 삭제·보존 판정한다.
  4. checked_at과 screenshot hash로 teardown 후 상태를 묶는다.

W22 조각별 정밀 해설

F07-C01 · 원문 1–10줄
문법 해부
1~10줄의 `원문 1–10줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `MANUAL_REVIEW_REQUIRED`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `MANUAL_REVIEW_REQUIRED`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: example 값이 남으면 실제 inventory가 아니다.
착각 방지
`원문 1–10줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: example 값이 남으면 실제 inventory가 아니다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F07-C02 · 원문 11–20줄
문법 해부
11~20줄의 `원문 11–20줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `ap-northeast-2`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `ap-northeast-2`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: PDF worksheet에는 validator 필수 checked_at이 빠져 있다.
착각 방지
`원문 11–20줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: PDF worksheet에는 validator 필수 checked_at이 빠져 있다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F07-C03 · 원문 21–30줄
문법 해부
21~30줄의 `원문 21–30줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `resources`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `resources`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: 의도적 보존 resource는 이유와 만료일이 필요하다.
착각 방지
`원문 21–30줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: 의도적 보존 resource는 이유와 만료일이 필요하다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F07-C04 · 원문 31–34줄
문법 해부
31~34줄의 `원문 31–34줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `checked_at`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `checked_at`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: console 화면은 exact screenshot hash와 묶어야 한다.
착각 방지
`원문 31–34줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: console 화면은 exact screenshot hash와 묶어야 한다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
반례
  1. 겉보기에는 맞지만 깨지는 예는?

  2. resource를 만든 뒤 budget을 설정한다

  3. 그 상태는 owner·입력·관찰 중 한 칸이 비어 있어.

  4. 수정한 뒤 같은 source와 hash로 다시 대조해.

08

STEP 08 / 13

실제 값 따라가기

같은 입력값이 어느 줄을 지나 어떤 결과가 되는지 추적합니다.

순서들어온 값코드가 하는 일나온 값·상태경계
F07-T01 beforetagged accountinventoryplanned resourcescost gate 먼저
F07-T02 afterALB/RDS/NAT/EIPdelete/recheckretained only보존 이유·만료일
F07-T03 bindingconsole captureSHA-256manual reviewworksheet 자체는 외부 실행 아님
책임 경계
  1. 이 항목의 마지막 책임선은?

  2. 직접 역할은 `비용·resource teardown worksheet`이야.

  3. 대표 경계는 `console 화면은 exact screenshot hash와 묶어야 한다`이야.

  4. 정본/비정본 label과 evidence owner까지 확인하면 끝이야.

09

STEP 09 / 13

GitHub·AWS·PowerShell·PostgreSQL 내부에서 벌어지는 일

GitHub·AWS·PowerShell·PostgreSQL에서 실제로 일어나는 일과 증명 범위를 구분합니다.

tagging API

project tag 기준 resource 목록을 찾는다.

모든 untagged 비용 resource를 보장하지 않는다.
billing

budget alarm이 비용 guardrail을 제공한다.

실시간 hard stop은 아니다.
validator

resources와 checked_at shape를 검사한다.

PDF p746 예시는 checked_at이 빠져 보완이 필요하다.
10

STEP 10 / 13

흔한 착각과 틀린 예

그럴듯하지만 틀린 해석을 반례로 고칩니다.

❌ resource를 만든 뒤 budget을 설정한다

왜 틀리나 비용·resource teardown worksheet의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 budget·owner·expiresAt을 먼저 만든다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `example 값이 남으면 실제 inventory가 아니다` 상태인데도 Green을 주장하게 된다.

❌ NAT Gateway·EIP를 inventory에서 뺀다

왜 틀리나 비용·resource teardown worksheet의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 생성 전 inventory를 저장한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `PDF worksheet에는 validator 필수 checked_at이 빠져 있다` 상태인데도 Green을 주장하게 된다.

❌ retained resource 이유와 만료일을 비운다

왜 틀리나 비용·resource teardown worksheet의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 실습 뒤 resource를 삭제·보존 판정한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `의도적 보존 resource는 이유와 만료일이 필요하다` 상태인데도 Green을 주장하게 된다.

❌ p746 JSON을 그대로 복사해 checked_at을 누락한다

왜 틀리나 비용·resource teardown worksheet의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 checked_at과 screenshot hash로 teardown 후 상태를 묶는다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `console 화면은 exact screenshot hash와 묶어야 한다` 상태인데도 Green을 주장하게 된다.

❌ tag 결과가 비면 계정 전체 비용이 0이라고 단정한다

왜 틀리나 비용·resource teardown worksheet의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 checked_at과 screenshot hash로 teardown 후 상태를 묶는다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `example 값이 남으면 실제 inventory가 아니다` 상태인데도 Green을 주장하게 된다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

이 코드가 책임지지 않는 일을 분리합니다.

직접 미보장

example 값이 남으면 실제 inventory가 아니다

이 책임을 맡는 곳: 별도 외부/selector 실행
직접 미보장

PDF worksheet에는 validator 필수 checked_at이 빠져 있다

이 책임을 맡는 곳: secret·운영 정책
직접 미보장

의도적 보존 resource는 이유와 만료일이 필요하다

이 책임을 맡는 곳: infrastructure·사람 검토
직접 미보장

console 화면은 exact screenshot hash와 묶어야 한다

이 책임을 맡는 곳: owner lifecycle
12

STEP 12 / 13

직접 다시 써보기

뜻 → 조각 → 전체 코드 순서로 다시 씁니다.

1단계 · 뜻부터 복원

다음 역할을 고정값과 미보장 경계까지 말한다: EC2/ECS·RDS·ECR·NAT와 budget alarm을 teardown 뒤 다시 inventory하는 D7 worksheet 보완 예시다.

2단계 · 코드 조각 재조립

  1. 원문 1–10줄
  2. 원문 11–20줄
  3. 원문 21–30줄
  4. 원문 31–34줄

3단계 · 파일 전체 다시 쓰기

34개 물리 줄을 원본 순서로 복원하고 SHA-256 a2d8f62245a5a60285538dfd624b95f13181ce16fc447632f8942c235de92ce4와 대조한다.

자가 점검
  • 원본 source/template bytes를 바꾸지 않았는가?
  • 외부 미실행과 local restore Green을 구분했는가?
  • secret 원문을 evidence에 남기지 않았는가?
  • D7 checked_at 충돌과 사람 검토 경계를 보았는가?
  • Q35/Q36을 workbook 정본 답안이라고 부르지 않았는가?
13

STEP 13 / 13

전체 원본 source

감사로 고정한 전체 source를 가감 없이 확인합니다.

학습용 예시 전체 확인하기 · 정본 답안 아님
학습용 예시 · PDF JSON schema/worksheet · 정본 답안 아님 · 비실행illustrative/json/W22-D7-resource-inventory.jsonSHA-256 a2d8f62245a5a60285538dfd624b95f13181ce16fc447632f8942c235de92ce4
비용·teardown inventory — checked_at 계약까지 닫기 전체
{
  "_provenance": "학습용 예시 · PDF 비용·teardown worksheet 보완본 · 정본 답안 아님 · 비실행",
  "status": "MANUAL_REVIEW_REQUIRED",
  "region": "ap-northeast-2",
  "checked_at": "EXAMPLE_UTC_TIMESTAMP_REQUIRED_BY_D7_VALIDATOR",
  "resources": [
    {
      "type": "EC2_OR_ECS",
      "id": "EXAMPLE_RESOURCE_ID",
      "state": "terminated-or-zero-tasks"
    },
    {
      "type": "RDS",
      "id": "EXAMPLE_RESOURCE_ID",
      "state": "deleted-or-approved-retained"
    },
    {
      "type": "ECR",
      "id": "EXAMPLE_REPOSITORY",
      "digest": "sha256:EXAMPLE_DIGEST"
    },
    {
      "type": "NAT_GATEWAY",
      "id": "EXAMPLE_IF_CREATED",
      "state": "deleted"
    }
  ],
  "budget_alarm": {
    "currency": "USD",
    "threshold": "EXAMPLE_LIMIT",
    "notification_tested": false
  },
  "official_console_screenshot_sha256": "EXAMPLE_AFTER_REAL_EXTERNAL_RUN"
}
08

D7 primary evidence — URL·commit·두 파일 hash의 수동 closure

illustrative/text/W22-D7-primary-evidence-contract.txt

학습용 예시 · PDF contract/template · 정본 답안 아님 · 학습용 예시 · 정본 답안 아님 · W22-F08
18줄 연결18줄 번역2 chunks
01

STEP 01 / 13

오늘 이 코드에서 해결할 문제

무엇을 이해해야 하는지 질문부터 잡습니다.

오늘의 한 문장

공식 GitHub run과 screenshot·resource inventory hash, budget·teardown 상태를 같은 D7 primary evidence에 묶는 수동 계약이다.

  1. `official_run_url`은 어느 줄에서 생길까?
  2. 입력→guard→관찰→cleanup 순서는 무엇인가?
  3. local owner와 external human review는 누구인가?
  4. 직접 관찰하지 않은 Green은 무엇인가?
  5. 반례는 `예시 URL·0 hash는 실제 증거가 아니다`이라는 경계와 어떻게 연결되는가?
이 파일에서 끝까지 다시 쓰는 값official_run_url40-hex committwo SHA-256 bindingsteardown_verifiedMANUAL_REVIEW_REQUIRED
02

STEP 02 / 13

아주 짧게: 이 코드는 왜 필요할까?

웹소설 대신 이 코드가 필요한 이유만 두 문단으로 쉽게 봅니다.

STARRY가 GitHub run표·AWS 출입증·DB 복구 영수증·SQL 결과표를 서로 다른 칸에 놓는다.

D7 primary evidence — URL·commit·두 파일 hash의 수동 closure ― 증거 흐름으로 바꾸기

공식 GitHub run과 screenshot·resource inventory hash, budget·teardown 상태를 같은 D7 primary evidence에 묶는 수동 계약이다.

핵심값 official_run_url, 40-hex commit, two SHA-256 bindings, teardown_verified, MANUAL_REVIEW_REQUIRED을 원본 줄로 따라가되, `예시 URL·0 hash는 실제 증거가 아니다`까지 함께 표시해 Green 범위를 부풀리지 않는다.

딱 여기까지만 비유는 owner와 순서를 기억하게 할 뿐 외부 실행·AWS 계정 상태·PostgreSQL restore·SQL 결과를 자동 증명하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

생활 비유와 실제 코드의 경계를 함께 확인합니다.

원문 1–10줄

1~10줄을 한 덩어리로 읽어 1번째 움직임을 본다. 공식 GitHub run과 screenshot·resource inventory hash, budget·teardown 상태를 같은 D7 primary evidence에 묶는 수동 계약이다.

코드 연결
1~10줄
비유
공식 경기 URL, 선수 번호 commit, 현장 사진과 반납 목록의 봉인 hash를 한 장의 수동 폐장 확인서에 묶는 절차
비유의 끝
예시 URL·0 hash는 실제 증거가 아니다

원문 11–18줄

11~18줄을 한 덩어리로 읽어 2번째 움직임을 본다. 공식 GitHub run과 screenshot·resource inventory hash, budget·teardown 상태를 같은 D7 primary evidence에 묶는 수동 계약이다.

코드 연결
11~18줄
비유
공식 경기 URL, 선수 번호 commit, 현장 사진과 반납 목록의 봉인 hash를 한 장의 수동 폐장 확인서에 묶는 절차
비유의 끝
다른 날짜 evidence가 Gate를 대신하지 않는다
문제의 첫 장면
  1. 첫 고정값은 `official_run_url` 맞아?

  2. 공식 GitHub run과 screenshot·resource inventory hash, budget·teardown 상태를 같은 D7 primary evidence에 묶는 수동 계약이다.

  3. 원문에서 `official_run_url`이 생기는 위치를 찾자.

  4. 그리고 `예시 URL·0 hash는 실제 증거가 아니다`도 같이 적어.

입력에서 결과까지
  1. `40-hex commit`은 언제 생겨?

  2. 공식 run URL과 run_id를 묶는다. → 40-hex commit과 conclusion을 확인한다.

  3. screenshot·inventory 파일 hash를 재계산한다. → budget·teardown을 사람이 확인한 뒤 closure 상태를 갱신한다.

  4. 관찰값과 `다른 날짜 evidence가 Gate를 대신하지 않는다`을 분리하면 돼.

04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

감사 규칙상 연결 대상인 원본 18줄을 빠짐없이 연결합니다.

단어 몇 개만 뽑은 표가 아닙니다.학습용 예시 · PDF contract/template · 정본 답안 아님에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.18 / 18 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F08-L01 학습용 예시 · PDF 외부 primary evidence schema · 정본 답안 아님 공식 경기 URL, 선수 번호 commit, 현장 사진과 반납 목록의 봉인 hash를 한 장의 수동 폐장 확인서에 묶는 절차 수동 external primary evidence closure 계약의 1번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
official run·screenshot·resource inventory·control review
결과·효과
이 줄 뒤에는 항목 전체의 `official_run_url` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
예시 URL·0 hash는 실제 증거가 아니다
2줄F08-L02 execution: NOT_RUN_EXTERNAL 공식 경기 URL, 선수 번호 commit, 현장 사진과 반납 목록의 봉인 hash를 한 장의 수동 폐장 확인서에 묶는 절차 실제 외부 실행을 아직 수행·증명하지 않았다는 상태를 명시한다.
입력
official run·screenshot·resource inventory·control review
결과·효과
이 줄 뒤에는 항목 전체의 `40-hex commit` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
다른 날짜 evidence가 Gate를 대신하지 않는다
3줄F08-L03 review_status: MANUAL_REVIEW_REQUIRED 공식 경기 URL, 선수 번호 commit, 현장 사진과 반납 목록의 봉인 hash를 한 장의 수동 폐장 확인서에 묶는 절차 자동 shape/hash 검사 뒤에도 사람의 의미 검토가 남았음을 고정한다.
입력
official run·screenshot·resource inventory·control review
결과·효과
이 줄 뒤에는 항목 전체의 `two SHA-256 bindings` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
predecessor index 성공은 D7 성공이 아니다
4줄F08-L04 official_run_url: https://github.com/example-owner/example-repo/actions/runs/1234567890 공식 경기 URL, 선수 번호 commit, 현장 사진과 반납 목록의 봉인 hash를 한 장의 수동 폐장 확인서에 묶는 절차 공식 GitHub Actions run을 가리키는 URL field를 선언한다.
입력
official run·screenshot·resource inventory·control review
결과·효과
이 줄 뒤에는 항목 전체의 `teardown_verified` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
사람 의미 검토 전 Green이 아니다
5줄F08-L05 run_id: 1234567890 공식 경기 URL, 선수 번호 commit, 현장 사진과 반납 목록의 봉인 hash를 한 장의 수동 폐장 확인서에 묶는 절차 수동 external primary evidence closure 계약에서 `run_id: 1234567890` field·값 또는 assignment를 다음 단계에 전달한다.
입력
official run·screenshot·resource inventory·control review
결과·효과
이 줄 뒤에는 항목 전체의 `MANUAL_REVIEW_REQUIRED` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
예시 URL·0 hash는 실제 증거가 아니다
6줄F08-L06 commit_sha: 0000000000000000000000000000000000000000 공식 경기 URL, 선수 번호 commit, 현장 사진과 반납 목록의 봉인 hash를 한 장의 수동 폐장 확인서에 묶는 절차 수동 external primary evidence closure 계약에서 `commit_sha: 000000000000000000000000000000000000` field·값 또는 assignment를 다음 단계에 전달한다.
입력
official run·screenshot·resource inventory·control review
결과·효과
이 줄 뒤에는 항목 전체의 `official_run_url` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
다른 날짜 evidence가 Gate를 대신하지 않는다
7줄F08-L07 workflow_name: example-workflow-name 공식 경기 URL, 선수 번호 commit, 현장 사진과 반납 목록의 봉인 hash를 한 장의 수동 폐장 확인서에 묶는 절차 수동 external primary evidence closure 계약에서 `workflow_name: example-workflow-name` field·값 또는 assignment를 다음 단계에 전달한다.
입력
official run·screenshot·resource inventory·control review
결과·효과
이 줄 뒤에는 항목 전체의 `40-hex commit` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
predecessor index 성공은 D7 성공이 아니다
8줄F08-L08 conclusion: success 공식 경기 URL, 선수 번호 commit, 현장 사진과 반납 목록의 봉인 hash를 한 장의 수동 폐장 확인서에 묶는 절차 수동 external primary evidence closure 계약에서 `conclusion: success` field·값 또는 assignment를 다음 단계에 전달한다.
입력
official run·screenshot·resource inventory·control review
결과·효과
이 줄 뒤에는 항목 전체의 `two SHA-256 bindings` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
사람 의미 검토 전 Green이 아니다
9줄F08-L09 screenshot_path: evidence/w22/aws-console.png 공식 경기 URL, 선수 번호 commit, 현장 사진과 반납 목록의 봉인 hash를 한 장의 수동 폐장 확인서에 묶는 절차 수동 external primary evidence closure 계약에서 `screenshot_path: evidence/w22/aws-console.png` field·값 또는 assignment를 다음 단계에 전달한다.
입력
official run·screenshot·resource inventory·control review
결과·효과
이 줄 뒤에는 항목 전체의 `teardown_verified` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
예시 URL·0 hash는 실제 증거가 아니다
10줄F08-L10 screenshot_sha256: 0000000000000000000000000000000000000000000000000000000000000000 공식 경기 URL, 선수 번호 commit, 현장 사진과 반납 목록의 봉인 hash를 한 장의 수동 폐장 확인서에 묶는 절차 현재 file bytes를 64-hex SHA-256 값과 결박하는 field 또는 검사를 다룬다.
입력
official run·screenshot·resource inventory·control review
결과·효과
이 줄 뒤에는 항목 전체의 `MANUAL_REVIEW_REQUIRED` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
다른 날짜 evidence가 Gate를 대신하지 않는다
11줄F08-L11 resource_inventory_path: evidence/w22/aws-resource-inventory.json 공식 경기 URL, 선수 번호 commit, 현장 사진과 반납 목록의 봉인 hash를 한 장의 수동 폐장 확인서에 묶는 절차 수동 external primary evidence closure 계약에서 `resource_inventory_path: evidence/w22/aws-resour` field·값 또는 assignment를 다음 단계에 전달한다.
입력
official run·screenshot·resource inventory·control review
결과·효과
이 줄 뒤에는 항목 전체의 `official_run_url` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
predecessor index 성공은 D7 성공이 아니다
12줄F08-L12 resource_inventory_sha256: 0000000000000000000000000000000000000000000000000000000000000000 공식 경기 URL, 선수 번호 commit, 현장 사진과 반납 목록의 봉인 hash를 한 장의 수동 폐장 확인서에 묶는 절차 현재 file bytes를 64-hex SHA-256 값과 결박하는 field 또는 검사를 다룬다.
입력
official run·screenshot·resource inventory·control review
결과·효과
이 줄 뒤에는 항목 전체의 `40-hex commit` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
사람 의미 검토 전 Green이 아니다
13줄F08-L13 teardown_verified: false 공식 경기 URL, 선수 번호 commit, 현장 사진과 반납 목록의 봉인 hash를 한 장의 수동 폐장 확인서에 묶는 절차 수동 external primary evidence closure 계약에서 `teardown_verified: false` field·값 또는 assignment를 다음 단계에 전달한다.
입력
official run·screenshot·resource inventory·control review
결과·효과
이 줄 뒤에는 항목 전체의 `two SHA-256 bindings` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
예시 URL·0 hash는 실제 증거가 아니다
14줄F08-L14 budget_alarm_verified: false 공식 경기 URL, 선수 번호 commit, 현장 사진과 반납 목록의 봉인 hash를 한 장의 수동 폐장 확인서에 묶는 절차 resource 생성 전 비용 경계와 알림 상태를 기록한다.
입력
official run·screenshot·resource inventory·control review
결과·효과
이 줄 뒤에는 항목 전체의 `teardown_verified` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
다른 날짜 evidence가 Gate를 대신하지 않는다
15줄F08-L15 retained_resources: EXAMPLE_NONE_OR_ID_REASON_EXPIRY 공식 경기 URL, 선수 번호 commit, 현장 사진과 반납 목록의 봉인 hash를 한 장의 수동 폐장 확인서에 묶는 절차 수동 external primary evidence closure 계약에서 `retained_resources: EXAMPLE_NONE_OR_ID_REASON_EX` field·값 또는 assignment를 다음 단계에 전달한다.
입력
official run·screenshot·resource inventory·control review
결과·효과
이 줄 뒤에는 항목 전체의 `MANUAL_REVIEW_REQUIRED` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
predecessor index 성공은 D7 성공이 아니다
16줄F08-L16 closure_marker: W22D7_PRIMARY_EVIDENCE_MANUAL_REVIEW_REQUIRED 공식 경기 URL, 선수 번호 commit, 현장 사진과 반납 목록의 봉인 hash를 한 장의 수동 폐장 확인서에 묶는 절차 자동 shape/hash 검사 뒤에도 사람의 의미 검토가 남았음을 고정한다.
입력
official run·screenshot·resource inventory·control review
결과·효과
이 줄 뒤에는 항목 전체의 `official_run_url` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
사람 의미 검토 전 Green이 아니다
17줄F08-L17 boundary: 실제 URL·commit·두 파일 hash·teardown·budget을 사람이 대조하기 전 Green이 아니다. 공식 경기 URL, 선수 번호 commit, 현장 사진과 반납 목록의 봉인 hash를 한 장의 수동 폐장 확인서에 묶는 절차 수동 external primary evidence closure 계약에서 `boundary: 실제 URL·commit·두 파일 hash·teardown·budge` field·값 또는 assignment를 다음 단계에 전달한다.
입력
official run·screenshot·resource inventory·control review
결과·효과
이 줄 뒤에는 항목 전체의 `40-hex commit` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
예시 URL·0 hash는 실제 증거가 아니다
18줄F08-L18 precedessor_rule: 이전 주 index 또는 다른 날짜 evidence는 이 Gate를 대신할 수 없다. 공식 경기 URL, 선수 번호 commit, 현장 사진과 반납 목록의 봉인 hash를 한 장의 수동 폐장 확인서에 묶는 절차 수동 external primary evidence closure 계약에서 `precedessor_rule: 이전 주 index 또는 다른 날짜 evidence는 ` field·값 또는 assignment를 다음 단계에 전달한다.
입력
official run·screenshot·resource inventory·control review
결과·효과
이 줄 뒤에는 항목 전체의 `two SHA-256 bindings` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
다른 날짜 evidence가 Gate를 대신하지 않는다
Green 범위
  1. marker나 파일이 보이면 전부 성공이야?

  2. 아니. source가 직접 검증한 범위만 말해야 해.

  3. 직접 연결되는 대표 값은 `MANUAL_REVIEW_REQUIRED`이야.

  4. `predecessor index 성공은 D7 성공이 아니다`는 별도 증거가 필요해.

05

STEP 05 / 13

원본 코드 조각

원본을 2개 의미 조각으로 나누어 그대로 확인합니다.

파일을 한꺼번에 외우지 않고 실행 의미가 이어지는 작은 조각으로 봅니다. 아래 코드는 prompt·fixture·가정을 밝힌 학습용 예시 source이며, 제공 정본 답안이 아닙니다.

F08-C01 · 원문 1–10줄1–10줄
1–10줄 원본
학습용 예시 · PDF 외부 primary evidence schema · 정본 답안 아님
execution: NOT_RUN_EXTERNAL
review_status: MANUAL_REVIEW_REQUIRED
official_run_url: https://github.com/example-owner/example-repo/actions/runs/1234567890
run_id: 1234567890
commit_sha: 0000000000000000000000000000000000000000
workflow_name: example-workflow-name
conclusion: success
screenshot_path: evidence/w22/aws-console.png
screenshot_sha256: 0000000000000000000000000000000000000000000000000000000000000000
F08-C02 · 원문 11–18줄11–18줄
11–18줄 원본
resource_inventory_path: evidence/w22/aws-resource-inventory.json
resource_inventory_sha256: 0000000000000000000000000000000000000000000000000000000000000000
teardown_verified: false
budget_alarm_verified: false
retained_resources: EXAMPLE_NONE_OR_ID_REASON_EXPIRY
closure_marker: W22D7_PRIMARY_EVIDENCE_MANUAL_REVIEW_REQUIRED
boundary: 실제 URL·commit·두 파일 hash·teardown·budget을 사람이 대조하기 전 Green이 아니다.
precedessor_rule: 이전 주 index 또는 다른 날짜 evidence는 이 Gate를 대신할 수 없다.
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

비어 있지 않은 18줄을 모두 한국어로 옮깁니다.

전체 번역 18 / 18

비어 있지 않은 원본 줄은 하나도 생략하지 않습니다.

원본한국어 번역
1학습용 예시 · PDF 외부 primary evidence schema · 정본 답안 아님수동 external primary evidence closure 계약의 1번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
2execution: NOT_RUN_EXTERNAL실제 외부 실행을 아직 수행·증명하지 않았다는 상태를 명시한다.
3review_status: MANUAL_REVIEW_REQUIRED자동 shape/hash 검사 뒤에도 사람의 의미 검토가 남았음을 고정한다.
4official_run_url: https://github.com/example-owner/example-repo/actions/runs/1234567890공식 GitHub Actions run을 가리키는 URL field를 선언한다.
5run_id: 1234567890수동 external primary evidence closure 계약에서 `run_id: 1234567890` field·값 또는 assignment를 다음 단계에 전달한다.
6commit_sha: 0000000000000000000000000000000000000000수동 external primary evidence closure 계약에서 `commit_sha: 000000000000000000000000000000000000` field·값 또는 assignment를 다음 단계에 전달한다.
7workflow_name: example-workflow-name수동 external primary evidence closure 계약에서 `workflow_name: example-workflow-name` field·값 또는 assignment를 다음 단계에 전달한다.
8conclusion: success수동 external primary evidence closure 계약에서 `conclusion: success` field·값 또는 assignment를 다음 단계에 전달한다.
9screenshot_path: evidence/w22/aws-console.png수동 external primary evidence closure 계약에서 `screenshot_path: evidence/w22/aws-console.png` field·값 또는 assignment를 다음 단계에 전달한다.
10screenshot_sha256: 0000000000000000000000000000000000000000000000000000000000000000현재 file bytes를 64-hex SHA-256 값과 결박하는 field 또는 검사를 다룬다.
11resource_inventory_path: evidence/w22/aws-resource-inventory.json수동 external primary evidence closure 계약에서 `resource_inventory_path: evidence/w22/aws-resour` field·값 또는 assignment를 다음 단계에 전달한다.
12resource_inventory_sha256: 0000000000000000000000000000000000000000000000000000000000000000현재 file bytes를 64-hex SHA-256 값과 결박하는 field 또는 검사를 다룬다.
13teardown_verified: false수동 external primary evidence closure 계약에서 `teardown_verified: false` field·값 또는 assignment를 다음 단계에 전달한다.
14budget_alarm_verified: falseresource 생성 전 비용 경계와 알림 상태를 기록한다.
15retained_resources: EXAMPLE_NONE_OR_ID_REASON_EXPIRY수동 external primary evidence closure 계약에서 `retained_resources: EXAMPLE_NONE_OR_ID_REASON_EX` field·값 또는 assignment를 다음 단계에 전달한다.
16closure_marker: W22D7_PRIMARY_EVIDENCE_MANUAL_REVIEW_REQUIRED자동 shape/hash 검사 뒤에도 사람의 의미 검토가 남았음을 고정한다.
17boundary: 실제 URL·commit·두 파일 hash·teardown·budget을 사람이 대조하기 전 Green이 아니다.수동 external primary evidence closure 계약에서 `boundary: 실제 URL·commit·두 파일 hash·teardown·budge` field·값 또는 assignment를 다음 단계에 전달한다.
18precedessor_rule: 이전 주 index 또는 다른 날짜 evidence는 이 Gate를 대신할 수 없다.수동 external primary evidence closure 계약에서 `precedessor_rule: 이전 주 index 또는 다른 날짜 evidence는 ` field·값 또는 assignment를 다음 단계에 전달한다.
07

STEP 07 / 13

기존 수준의 한 줄 읽기·문법 해부

쉬운 설명 다음에 문법과 실행 순서를 정밀하게 읽습니다.

한 줄로 읽기

공식 GitHub run과 screenshot·resource inventory hash, budget·teardown 상태를 같은 D7 primary evidence에 묶는 수동 계약이다. 다만 예시 URL·0 hash는 실제 증거가 아니다

문법 해부

  • field 이름과 값은 D7 validator가 찾는 exact evidence schema를 나타낸다.
  • example URL·0 hash·false control은 실제값이 아니라 미실행을 드러내는 비정본 표식이다.

실행 순서

  1. 공식 run URL과 run_id를 묶는다.
  2. 40-hex commit과 conclusion을 확인한다.
  3. screenshot·inventory 파일 hash를 재계산한다.
  4. budget·teardown을 사람이 확인한 뒤 closure 상태를 갱신한다.

W22 조각별 정밀 해설

F08-C01 · 원문 1–10줄
문법 해부
1~10줄의 `원문 1–10줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `official_run_url`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `official_run_url`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: 예시 URL·0 hash는 실제 증거가 아니다.
착각 방지
`원문 1–10줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: 예시 URL·0 hash는 실제 증거가 아니다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F08-C02 · 원문 11–18줄
문법 해부
11~18줄의 `원문 11–18줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `40-hex commit`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `40-hex commit`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: 다른 날짜 evidence가 Gate를 대신하지 않는다.
착각 방지
`원문 11–18줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: 다른 날짜 evidence가 Gate를 대신하지 않는다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
반례
  1. 겉보기에는 맞지만 깨지는 예는?

  2. 예시 URL과 0 hash를 실제 증거로 둔다

  3. 그 상태는 owner·입력·관찰 중 한 칸이 비어 있어.

  4. 수정한 뒤 같은 source와 hash로 다시 대조해.

08

STEP 08 / 13

실제 값 따라가기

같은 입력값이 어느 줄을 지나 어떤 결과가 되는지 추적합니다.

순서들어온 값코드가 하는 일나온 값·상태경계
F08-T01 runofficial URLnumeric id matchbound runexample URL은 무효
F08-T02 filestwo learner filesSHA-256exact bindings경로 존재도 필요
F08-T03 controlsbudget+teardownmanual reviewprimary markerpredecessor가 대신 못함
책임 경계
  1. 이 항목의 마지막 책임선은?

  2. 직접 역할은 `수동 external primary evidence closure 계약`이야.

  3. 대표 경계는 `사람 의미 검토 전 Green이 아니다`이야.

  4. 정본/비정본 label과 evidence owner까지 확인하면 끝이야.

09

STEP 09 / 13

GitHub·AWS·PowerShell·PostgreSQL 내부에서 벌어지는 일

GitHub·AWS·PowerShell·PostgreSQL에서 실제로 일어나는 일과 증명 범위를 구분합니다.

regex contract

URL/run ID와 40-hex commit shape를 검사한다.

형식 검사는 source 의미를 보장하지 않는다.
hash binding

현재 두 파일 byte를 evidence field와 비교한다.

screenshot 내용은 사람이 읽는다.
primary closure

PRIMARY_PRODUCER=0인 manual external Gate다.

다른 주 restore-result가 aws-gate를 대신하지 않는다.
10

STEP 10 / 13

흔한 착각과 틀린 예

그럴듯하지만 틀린 해석을 반례로 고칩니다.

❌ 예시 URL과 0 hash를 실제 증거로 둔다

왜 틀리나 수동 external primary evidence closure 계약의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 공식 run URL과 run_id를 묶는다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `예시 URL·0 hash는 실제 증거가 아니다` 상태인데도 Green을 주장하게 된다.

❌ run URL의 numeric id와 run_id가 다르다

왜 틀리나 수동 external primary evidence closure 계약의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 40-hex commit과 conclusion을 확인한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `다른 날짜 evidence가 Gate를 대신하지 않는다` 상태인데도 Green을 주장하게 된다.

❌ screenshot만 있고 inventory 파일이 없다

왜 틀리나 수동 external primary evidence closure 계약의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 screenshot·inventory 파일 hash를 재계산한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `predecessor index 성공은 D7 성공이 아니다` 상태인데도 Green을 주장하게 된다.

❌ budget·teardown false인데 success라 쓴다

왜 틀리나 수동 external primary evidence closure 계약의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 budget·teardown을 사람이 확인한 뒤 closure 상태를 갱신한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `사람 의미 검토 전 Green이 아니다` 상태인데도 Green을 주장하게 된다.

❌ predecessor index 성공으로 D7을 대체한다

왜 틀리나 수동 external primary evidence closure 계약의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 budget·teardown을 사람이 확인한 뒤 closure 상태를 갱신한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `예시 URL·0 hash는 실제 증거가 아니다` 상태인데도 Green을 주장하게 된다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

이 코드가 책임지지 않는 일을 분리합니다.

직접 미보장

예시 URL·0 hash는 실제 증거가 아니다

이 책임을 맡는 곳: 별도 외부/selector 실행
직접 미보장

다른 날짜 evidence가 Gate를 대신하지 않는다

이 책임을 맡는 곳: secret·운영 정책
직접 미보장

predecessor index 성공은 D7 성공이 아니다

이 책임을 맡는 곳: infrastructure·사람 검토
직접 미보장

사람 의미 검토 전 Green이 아니다

이 책임을 맡는 곳: owner lifecycle
12

STEP 12 / 13

직접 다시 써보기

뜻 → 조각 → 전체 코드 순서로 다시 씁니다.

1단계 · 뜻부터 복원

다음 역할을 고정값과 미보장 경계까지 말한다: 공식 GitHub run과 screenshot·resource inventory hash, budget·teardown 상태를 같은 D7 primary evidence에 묶는 수동 계약이다.

2단계 · 코드 조각 재조립

  1. 원문 1–10줄
  2. 원문 11–18줄

3단계 · 파일 전체 다시 쓰기

18개 물리 줄을 원본 순서로 복원하고 SHA-256 5177fe33fb2445565eccaf1060eaf440ac8516fb82d331ea0b6e0ef2ff20bc6b와 대조한다.

자가 점검
  • 원본 source/template bytes를 바꾸지 않았는가?
  • 외부 미실행과 local restore Green을 구분했는가?
  • secret 원문을 evidence에 남기지 않았는가?
  • D7 checked_at 충돌과 사람 검토 경계를 보았는가?
  • Q35/Q36을 workbook 정본 답안이라고 부르지 않았는가?
13

STEP 13 / 13

전체 원본 source

감사로 고정한 전체 source를 가감 없이 확인합니다.

학습용 예시 전체 확인하기 · 정본 답안 아님
학습용 예시 · PDF contract/template · 정본 답안 아님illustrative/text/W22-D7-primary-evidence-contract.txtSHA-256 5177fe33fb2445565eccaf1060eaf440ac8516fb82d331ea0b6e0ef2ff20bc6b
D7 primary evidence — URL·commit·두 파일 hash의 수동 closure 전체
학습용 예시 · PDF 외부 primary evidence schema · 정본 답안 아님
execution: NOT_RUN_EXTERNAL
review_status: MANUAL_REVIEW_REQUIRED
official_run_url: https://github.com/example-owner/example-repo/actions/runs/1234567890
run_id: 1234567890
commit_sha: 0000000000000000000000000000000000000000
workflow_name: example-workflow-name
conclusion: success
screenshot_path: evidence/w22/aws-console.png
screenshot_sha256: 0000000000000000000000000000000000000000000000000000000000000000
resource_inventory_path: evidence/w22/aws-resource-inventory.json
resource_inventory_sha256: 0000000000000000000000000000000000000000000000000000000000000000
teardown_verified: false
budget_alarm_verified: false
retained_resources: EXAMPLE_NONE_OR_ID_REASON_EXPIRY
closure_marker: W22D7_PRIMARY_EVIDENCE_MANUAL_REVIEW_REQUIRED
boundary: 실제 URL·commit·두 파일 hash·teardown·budget을 사람이 대조하기 전 Green이 아니다.
precedessor_rule: 이전 주 index 또는 다른 날짜 evidence는 이 Gate를 대신할 수 없다.
09

W22-SQL-Q35 — 날짜별 선집계 뒤 calendar 7일 RANGE

illustrative/sql/W22-SQL-Q35.sql

학습용 예시 · 정본 답안 아님 · 학습용 예시 · 정본 답안 아님 · W22-F09
25줄 연결25줄 번역3 chunks
01

STEP 01 / 13

오늘 이 코드에서 해결할 문제

무엇을 이해해야 하는지 질문부터 잡습니다.

오늘의 한 문장

business_date별 합계를 먼저 만들고 calendar 7일 범위를 RANGE window frame으로 계산하는 비정본 Q35 예시다.

  1. `daily grain`은 어느 줄에서 생길까?
  2. 입력→guard→관찰→cleanup 순서는 무엇인가?
  3. local owner와 external human review는 누구인가?
  4. 직접 관찰하지 않은 Green은 무엇인가?
  5. 반례는 `workbook 제공 정답이 아니다`이라는 경계와 어떻게 연결되는가?
이 파일에서 끝까지 다시 쓰는 값daily grainRANGE 6 days precedingfixture rows=92027-01-02 daily=4200moving=1205002
02

STEP 02 / 13

아주 짧게: 이 코드는 왜 필요할까?

웹소설 대신 이 코드가 필요한 이유만 두 문단으로 쉽게 봅니다.

STARRY가 GitHub run표·AWS 출입증·DB 복구 영수증·SQL 결과표를 서로 다른 칸에 놓는다.

W22-SQL-Q35 — 날짜별 선집계 뒤 calendar 7일 RANGE ― 증거 흐름으로 바꾸기

business_date별 합계를 먼저 만들고 calendar 7일 범위를 RANGE window frame으로 계산하는 비정본 Q35 예시다.

핵심값 daily grain, RANGE 6 days preceding, fixture rows=9, 2027-01-02 daily=4200, moving=1205002을 원본 줄로 따라가되, `workbook 제공 정답이 아니다`까지 함께 표시해 Green 범위를 부풀리지 않는다.

딱 여기까지만 비유는 owner와 순서를 기억하게 할 뿐 외부 실행·AWS 계정 상태·PostgreSQL restore·SQL 결과를 자동 증명하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

생활 비유와 실제 코드의 경계를 함께 확인합니다.

원문 1–10줄

1~10줄을 한 덩어리로 읽어 1번째 움직임을 본다. business_date별 합계를 먼저 만들고 calendar 7일 범위를 RANGE window frame으로 계산하는 비정본 Q35 예시다.

코드 연결
1~10줄
비유
날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표
비유의 끝
workbook 제공 정답이 아니다

원문 11–20줄

11~20줄을 한 덩어리로 읽어 2번째 움직임을 본다. business_date별 합계를 먼저 만들고 calendar 7일 범위를 RANGE window frame으로 계산하는 비정본 Q35 예시다.

코드 연결
11~20줄
비유
날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표
비유의 끝
모든 status 포함은 명시한 학습 가정이다

원문 21–27줄

21~27줄을 한 덩어리로 읽어 3번째 움직임을 본다. business_date별 합계를 먼저 만들고 calendar 7일 범위를 RANGE window frame으로 계산하는 비정본 Q35 예시다.

코드 연결
21~27줄
비유
날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표
비유의 끝
누락일 자체를 0행으로 생성하지 않는다
문제의 첫 장면
  1. 첫 고정값은 `daily grain` 맞아?

  2. business_date별 합계를 먼저 만들고 calendar 7일 범위를 RANGE window frame으로 계산하는 비정본 Q35 예시다.

  3. 원문에서 `daily grain`이 생기는 위치를 찾자.

  4. 그리고 `workbook 제공 정답이 아니다`도 같이 적어.

입력에서 결과까지
  1. `RANGE 6 days preceding`은 언제 생겨?

  2. business_tx를 날짜별 SUM한다. → 한 날짜 한 행을 만든다.

  3. calendar range window를 적용한다. → 누락일·ROWS 반례와 fixture oracle을 대조한다.

  4. 관찰값과 `모든 status 포함은 명시한 학습 가정이다`을 분리하면 돼.

04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

감사 규칙상 연결 대상인 원본 25줄을 빠짐없이 연결합니다.

단어 몇 개만 뽑은 표가 아닙니다.학습용 예시 · 정본 답안 아님에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.25 / 25 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F09-L01 -- 학습용 예시 · 정본 답안 아님: workbook은 W22-SQL-Q35 답안을 제공하지 않는다. 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `daily grain` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
workbook 제공 정답이 아니다
2줄F09-L02 -- 입력 grain: business_tx 한 행 = 거래 한 건. 출력 grain: business_date 한 행 = 그 날짜의 합계와 7일 이동합계. 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `RANGE 6 days preceding` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
모든 status 포함은 명시한 학습 가정이다
3줄F09-L03 -- 학습 가정: prompt에 status filter가 없으므로 SUCCESS·FAILED·UNKNOWN·PROCESSING을 모두 포함한다. 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `fixture rows=9` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
누락일 자체를 0행으로 생성하지 않는다
4줄F09-L04 -- 핵심 반례: 누락일이 많아도 ROWS 6 PRECEDING은 최근 7개 '행'을 세므로 7개 달력일과 다르다. 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `2027-01-02 daily=4200` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
ROWS 6 PRECEDING과 의미가 다르다
5줄F09-L05 SET search_path TO workbook_schema, public; 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 비정본 calendar-window SQL 예시의 5번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `moving=1205002` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
workbook 제공 정답이 아니다
7줄F09-L07 WITH daily AS ( 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 날짜별 합계를 만드는 daily CTE를 연다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `RANGE 6 days preceding` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
누락일 자체를 0행으로 생성하지 않는다
8줄F09-L08 SELECT 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 SQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `fixture rows=9` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
ROWS 6 PRECEDING과 의미가 다르다
9줄F09-L09 business_date, 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 비정본 calendar-window SQL 예시의 9번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `2027-01-02 daily=4200` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
workbook 제공 정답이 아니다
10줄F09-L10 SUM(amount) AS daily_amount 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 같은 business_date의 거래 amount를 하루 합계로 줄인다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `moving=1205002` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
모든 status 포함은 명시한 학습 가정이다
11줄F09-L11 FROM business_tx 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 SQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `daily grain` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
누락일 자체를 0행으로 생성하지 않는다
12줄F09-L12 GROUP BY business_date 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 SQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `RANGE 6 days preceding` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
ROWS 6 PRECEDING과 의미가 다르다
13줄F09-L13 ) 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `fixture rows=9` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
workbook 제공 정답이 아니다
14줄F09-L14 SELECT 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 SQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `2027-01-02 daily=4200` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
모든 status 포함은 명시한 학습 가정이다
15줄F09-L15 business_date, 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 비정본 calendar-window SQL 예시의 15번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `moving=1205002` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
누락일 자체를 0행으로 생성하지 않는다
16줄F09-L16 daily_amount, 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 비정본 calendar-window SQL 예시의 16번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `daily grain` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
ROWS 6 PRECEDING과 의미가 다르다
17줄F09-L17 SUM(daily_amount) OVER ( 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 비정본 calendar-window SQL 예시의 17번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `RANGE 6 days preceding` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
workbook 제공 정답이 아니다
18줄F09-L18 ORDER BY business_date::timestamp 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 SQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `fixture rows=9` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
모든 status 포함은 명시한 학습 가정이다
19줄F09-L19 RANGE BETWEEN INTERVAL '6 days' PRECEDING AND CURRENT ROW 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 현재 날짜를 포함한 앞 6일, 즉 7 calendar days window frame을 지정한다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `2027-01-02 daily=4200` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
누락일 자체를 0행으로 생성하지 않는다
20줄F09-L20 ) AS moving_7_calendar_days 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 비정본 calendar-window SQL 예시의 20번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `moving=1205002` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
ROWS 6 PRECEDING과 의미가 다르다
21줄F09-L21 FROM daily 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 SQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `daily grain` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
workbook 제공 정답이 아니다
22줄F09-L22 ORDER BY business_date; 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 SQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `RANGE 6 days preceding` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
모든 status 포함은 명시한 학습 가정이다
24줄F09-L24 -- fixture oracle: 9행. 2026-06-30=2129999, 2026-07-01 이동합계=2132199. 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `2027-01-02 daily=4200` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
ROWS 6 PRECEDING과 의미가 다르다
25줄F09-L25 -- fixture oracle: 긴 누락 뒤 2026-12-28 이동합계는 303으로 다시 시작한다. 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `moving=1205002` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
workbook 제공 정답이 아니다
26줄F09-L26 -- fixture oracle: 2027-01-02 daily_amount=4200, moving_7_calendar_days=1205002. 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `daily grain` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
모든 status 포함은 명시한 학습 가정이다
27줄F09-L27 -- 누락일도 0행으로 출력해야 한다면 generate_series 달력과 LEFT JOIN을 추가해야 한다. 날짜별 영수증을 먼저 한 장으로 합친 뒤, 오늘을 포함한 최근 7칸의 달력 범위만 투명 자로 덮어 더하는 표 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
business_tx 21행의 business_date와 amount
결과·효과
이 줄 뒤에는 항목 전체의 `RANGE 6 days preceding` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
누락일 자체를 0행으로 생성하지 않는다
Green 범위
  1. marker나 파일이 보이면 전부 성공이야?

  2. 아니. source가 직접 검증한 범위만 말해야 해.

  3. 직접 연결되는 대표 값은 `moving=1205002`이야.

  4. `누락일 자체를 0행으로 생성하지 않는다`는 별도 증거가 필요해.

05

STEP 05 / 13

원본 코드 조각

원본을 3개 의미 조각으로 나누어 그대로 확인합니다.

파일을 한꺼번에 외우지 않고 실행 의미가 이어지는 작은 조각으로 봅니다. 아래 코드는 prompt·fixture·가정을 밝힌 학습용 예시 source이며, 제공 정본 답안이 아닙니다.

F09-C01 · 원문 1–10줄1–10줄
1–10줄 원본
-- 학습용 예시 · 정본 답안 아님: workbook은 W22-SQL-Q35 답안을 제공하지 않는다.
-- 입력 grain: business_tx 한 행 = 거래 한 건. 출력 grain: business_date 한 행 = 그 날짜의 합계와 7일 이동합계.
-- 학습 가정: prompt에 status filter가 없으므로 SUCCESS·FAILED·UNKNOWN·PROCESSING을 모두 포함한다.
-- 핵심 반례: 누락일이 많아도 ROWS 6 PRECEDING은 최근 7개 '행'을 세므로 7개 달력일과 다르다.
SET search_path TO workbook_schema, public;

WITH daily AS (
    SELECT
        business_date,
        SUM(amount) AS daily_amount
F09-C02 · 원문 11–20줄11–20줄
11–20줄 원본
    FROM business_tx
    GROUP BY business_date
)
SELECT
    business_date,
    daily_amount,
    SUM(daily_amount) OVER (
        ORDER BY business_date::timestamp
        RANGE BETWEEN INTERVAL '6 days' PRECEDING AND CURRENT ROW
    ) AS moving_7_calendar_days
F09-C03 · 원문 21–27줄21–27줄
21–27줄 원본
FROM daily
ORDER BY business_date;

-- fixture oracle: 9행. 2026-06-30=2129999, 2026-07-01 이동합계=2132199.
-- fixture oracle: 긴 누락 뒤 2026-12-28 이동합계는 303으로 다시 시작한다.
-- fixture oracle: 2027-01-02 daily_amount=4200, moving_7_calendar_days=1205002.
-- 누락일도 0행으로 출력해야 한다면 generate_series 달력과 LEFT JOIN을 추가해야 한다.
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

비어 있지 않은 25줄을 모두 한국어로 옮깁니다.

전체 번역 25 / 25

비어 있지 않은 원본 줄은 하나도 생략하지 않습니다.

원본한국어 번역
1-- 학습용 예시 · 정본 답안 아님: workbook은 W22-SQL-Q35 답안을 제공하지 않는다.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
2-- 입력 grain: business_tx 한 행 = 거래 한 건. 출력 grain: business_date 한 행 = 그 날짜의 합계와 7일 이동합계.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
3-- 학습 가정: prompt에 status filter가 없으므로 SUCCESS·FAILED·UNKNOWN·PROCESSING을 모두 포함한다.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
4-- 핵심 반례: 누락일이 많아도 ROWS 6 PRECEDING은 최근 7개 '행'을 세므로 7개 달력일과 다르다.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
5SET search_path TO workbook_schema, public;비정본 calendar-window SQL 예시의 5번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
7WITH daily AS (날짜별 합계를 만드는 daily CTE를 연다.
8 SELECTSQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
9 business_date,비정본 calendar-window SQL 예시의 9번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
10 SUM(amount) AS daily_amount같은 business_date의 거래 amount를 하루 합계로 줄인다.
11 FROM business_txSQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
12 GROUP BY business_dateSQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
13)현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
14SELECTSQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
15 business_date,비정본 calendar-window SQL 예시의 15번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
16 daily_amount,비정본 calendar-window SQL 예시의 16번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
17 SUM(daily_amount) OVER (비정본 calendar-window SQL 예시의 17번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
18 ORDER BY business_date::timestampSQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
19 RANGE BETWEEN INTERVAL '6 days' PRECEDING AND CURRENT ROW현재 날짜를 포함한 앞 6일, 즉 7 calendar days window frame을 지정한다.
20 ) AS moving_7_calendar_days비정본 calendar-window SQL 예시의 20번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
21FROM dailySQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
22ORDER BY business_date;SQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
24-- fixture oracle: 9행. 2026-06-30=2129999, 2026-07-01 이동합계=2132199.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
25-- fixture oracle: 긴 누락 뒤 2026-12-28 이동합계는 303으로 다시 시작한다.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
26-- fixture oracle: 2027-01-02 daily_amount=4200, moving_7_calendar_days=1205002.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
27-- 누락일도 0행으로 출력해야 한다면 generate_series 달력과 LEFT JOIN을 추가해야 한다.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
07

STEP 07 / 13

기존 수준의 한 줄 읽기·문법 해부

쉬운 설명 다음에 문법과 실행 순서를 정밀하게 읽습니다.

한 줄로 읽기

business_date별 합계를 먼저 만들고 calendar 7일 범위를 RANGE window frame으로 계산하는 비정본 Q35 예시다. 다만 workbook 제공 정답이 아니다

문법 해부

  • CTE `daily`가 거래 grain을 날짜 grain으로 먼저 줄인다.
  • timestamp ORDER BY의 `RANGE INTERVAL '6 days' PRECEDING`이 현재일 포함 7 calendar days를 뜻한다.

실행 순서

  1. business_tx를 날짜별 SUM한다.
  2. 한 날짜 한 행을 만든다.
  3. calendar range window를 적용한다.
  4. 누락일·ROWS 반례와 fixture oracle을 대조한다.

W22 조각별 정밀 해설

F09-C01 · 원문 1–10줄
문법 해부
1~10줄의 `원문 1–10줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `daily grain`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `daily grain`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: workbook 제공 정답이 아니다.
착각 방지
`원문 1–10줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: workbook 제공 정답이 아니다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F09-C02 · 원문 11–20줄
문법 해부
11~20줄의 `원문 11–20줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `RANGE 6 days preceding`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `RANGE 6 days preceding`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: 모든 status 포함은 명시한 학습 가정이다.
착각 방지
`원문 11–20줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: 모든 status 포함은 명시한 학습 가정이다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F09-C03 · 원문 21–27줄
문법 해부
21~27줄의 `원문 21–27줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `fixture rows=9`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `fixture rows=9`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: 누락일 자체를 0행으로 생성하지 않는다.
착각 방지
`원문 21–27줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: 누락일 자체를 0행으로 생성하지 않는다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
반례
  1. 겉보기에는 맞지만 깨지는 예는?

  2. SUM(amount)를 거래 row에 바로 window한다

  3. 그 상태는 owner·입력·관찰 중 한 칸이 비어 있어.

  4. 수정한 뒤 같은 source와 hash로 다시 대조해.

08

STEP 08 / 13

실제 값 따라가기

같은 입력값이 어느 줄을 지나 어떤 결과가 되는지 추적합니다.

순서들어온 값코드가 하는 일나온 값·상태경계
F09-T01 초기2026-06-30daily SUM2129999모든 status 포함 가정
F09-T02 누락 뒤2026-12-286-day range3037행 frame이면 옛 7월행 포함
F09-T03 마지막2027-01-02range sumdaily4200/moving1205002누락일 0행은 생성 안 함
책임 경계
  1. 이 항목의 마지막 책임선은?

  2. 직접 역할은 `비정본 calendar-window SQL 예시`이야.

  3. 대표 경계는 `ROWS 6 PRECEDING과 의미가 다르다`이야.

  4. 정본/비정본 label과 evidence owner까지 확인하면 끝이야.

09

STEP 09 / 13

GitHub·AWS·PowerShell·PostgreSQL 내부에서 벌어지는 일

GitHub·AWS·PowerShell·PostgreSQL에서 실제로 일어나는 일과 증명 범위를 구분합니다.

aggregate

21개 거래를 9개 observed date row로 만든다.

status filter 정책은 prompt에 없어 가정이다.
window frame

값 기준 날짜 범위를 현재 row마다 정한다.

ROWS는 물리 행 수 기준이다.
calendar spine

generate_series가 있어야 누락일도 0행으로 출력된다.

현재 query는 관찰된 날짜만 낸다.
10

STEP 10 / 13

흔한 착각과 틀린 예

그럴듯하지만 틀린 해석을 반례로 고칩니다.

❌ SUM(amount)를 거래 row에 바로 window한다

왜 틀리나 비정본 calendar-window SQL 예시의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 business_tx를 날짜별 SUM한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `workbook 제공 정답이 아니다` 상태인데도 Green을 주장하게 된다.

❌ ROWS 6 PRECEDING을 7일이라고 부른다

왜 틀리나 비정본 calendar-window SQL 예시의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 한 날짜 한 행을 만든다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `모든 status 포함은 명시한 학습 가정이다` 상태인데도 Green을 주장하게 된다.

❌ 누락일이 자동 0행으로 생긴다고 본다

왜 틀리나 비정본 calendar-window SQL 예시의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 calendar range window를 적용한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `누락일 자체를 0행으로 생성하지 않는다` 상태인데도 Green을 주장하게 된다.

❌ status filter를 설명 없이 추가한다

왜 틀리나 비정본 calendar-window SQL 예시의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 누락일·ROWS 반례와 fixture oracle을 대조한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `ROWS 6 PRECEDING과 의미가 다르다` 상태인데도 Green을 주장하게 된다.

❌ Q35를 workbook 정본 답안이라 부른다

왜 틀리나 비정본 calendar-window SQL 예시의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 누락일·ROWS 반례와 fixture oracle을 대조한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `workbook 제공 정답이 아니다` 상태인데도 Green을 주장하게 된다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

이 코드가 책임지지 않는 일을 분리합니다.

직접 미보장

workbook 제공 정답이 아니다

이 책임을 맡는 곳: 별도 외부/selector 실행
직접 미보장

모든 status 포함은 명시한 학습 가정이다

이 책임을 맡는 곳: secret·운영 정책
직접 미보장

누락일 자체를 0행으로 생성하지 않는다

이 책임을 맡는 곳: infrastructure·사람 검토
직접 미보장

ROWS 6 PRECEDING과 의미가 다르다

이 책임을 맡는 곳: owner lifecycle
12

STEP 12 / 13

직접 다시 써보기

뜻 → 조각 → 전체 코드 순서로 다시 씁니다.

1단계 · 뜻부터 복원

다음 역할을 고정값과 미보장 경계까지 말한다: business_date별 합계를 먼저 만들고 calendar 7일 범위를 RANGE window frame으로 계산하는 비정본 Q35 예시다.

2단계 · 코드 조각 재조립

  1. 원문 1–10줄
  2. 원문 11–20줄
  3. 원문 21–27줄

3단계 · 파일 전체 다시 쓰기

27개 물리 줄을 원본 순서로 복원하고 SHA-256 a8602cb326d8e4cc237b1401ea736490489a74f6a5bb62636f9c55665d4cc773와 대조한다.

자가 점검
  • 원본 source/template bytes를 바꾸지 않았는가?
  • 외부 미실행과 local restore Green을 구분했는가?
  • secret 원문을 evidence에 남기지 않았는가?
  • D7 checked_at 충돌과 사람 검토 경계를 보았는가?
  • Q35/Q36을 workbook 정본 답안이라고 부르지 않았는가?
13

STEP 13 / 13

전체 원본 source

감사로 고정한 전체 source를 가감 없이 확인합니다.

학습용 예시 전체 확인하기 · 정본 답안 아님
학습용 예시 · 정본 답안 아님illustrative/sql/W22-SQL-Q35.sqlSHA-256 a8602cb326d8e4cc237b1401ea736490489a74f6a5bb62636f9c55665d4cc773
W22-SQL-Q35 — 날짜별 선집계 뒤 calendar 7일 RANGE 전체
-- 학습용 예시 · 정본 답안 아님: workbook은 W22-SQL-Q35 답안을 제공하지 않는다.
-- 입력 grain: business_tx 한 행 = 거래 한 건. 출력 grain: business_date 한 행 = 그 날짜의 합계와 7일 이동합계.
-- 학습 가정: prompt에 status filter가 없으므로 SUCCESS·FAILED·UNKNOWN·PROCESSING을 모두 포함한다.
-- 핵심 반례: 누락일이 많아도 ROWS 6 PRECEDING은 최근 7개 '행'을 세므로 7개 달력일과 다르다.
SET search_path TO workbook_schema, public;

WITH daily AS (
    SELECT
        business_date,
        SUM(amount) AS daily_amount
    FROM business_tx
    GROUP BY business_date
)
SELECT
    business_date,
    daily_amount,
    SUM(daily_amount) OVER (
        ORDER BY business_date::timestamp
        RANGE BETWEEN INTERVAL '6 days' PRECEDING AND CURRENT ROW
    ) AS moving_7_calendar_days
FROM daily
ORDER BY business_date;

-- fixture oracle: 9행. 2026-06-30=2129999, 2026-07-01 이동합계=2132199.
-- fixture oracle: 긴 누락 뒤 2026-12-28 이동합계는 303으로 다시 시작한다.
-- fixture oracle: 2027-01-02 daily_amount=4200, moving_7_calendar_days=1205002.
-- 누락일도 0행으로 출력해야 한다면 generate_series 달력과 LEFT JOIN을 추가해야 한다.
10

W22-SQL-Q36 — NOT EXISTS와 FK 정상계의 0행 oracle

illustrative/sql/W22-SQL-Q36.sql

학습용 예시 · 정본 답안 아님 · 학습용 예시 · 정본 답안 아님 · W22-F10
23줄 연결23줄 번역3 chunks
01

STEP 01 / 13

오늘 이 코드에서 해결할 문제

무엇을 이해해야 하는지 질문부터 잡습니다.

오늘의 한 문장

ledger_entry를 시작으로 NOT EXISTS anti join을 써서 business_tx가 없는 고아 원장을 찾는 비정본 Q36 예시다.

  1. `NOT EXISTS`은 어느 줄에서 생길까?
  2. 입력→guard→관찰→cleanup 순서는 무엇인가?
  3. local owner와 external human review는 누구인가?
  4. 직접 관찰하지 않은 Green은 무엇인가?
  5. 반례는 `workbook 제공 정답이 아니다`이라는 경계와 어떻게 연결되는가?
이 파일에서 끝까지 다시 쓰는 값NOT EXISTSledger grainfixture rows=0NOT NULL FKisolated broken-table counterexample
02

STEP 02 / 13

아주 짧게: 이 코드는 왜 필요할까?

웹소설 대신 이 코드가 필요한 이유만 두 문단으로 쉽게 봅니다.

STARRY가 GitHub run표·AWS 출입증·DB 복구 영수증·SQL 결과표를 서로 다른 칸에 놓는다.

W22-SQL-Q36 — NOT EXISTS와 FK 정상계의 0행 oracle ― 증거 흐름으로 바꾸기

ledger_entry를 시작으로 NOT EXISTS anti join을 써서 business_tx가 없는 고아 원장을 찾는 비정본 Q36 예시다.

핵심값 NOT EXISTS, ledger grain, fixture rows=0, NOT NULL FK, isolated broken-table counterexample을 원본 줄로 따라가되, `workbook 제공 정답이 아니다`까지 함께 표시해 Green 범위를 부풀리지 않는다.

딱 여기까지만 비유는 owner와 순서를 기억하게 할 뿐 외부 실행·AWS 계정 상태·PostgreSQL restore·SQL 결과를 자동 증명하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

생활 비유와 실제 코드의 경계를 함께 확인합니다.

원문 1–10줄

1~10줄을 한 덩어리로 읽어 1번째 움직임을 본다. ledger_entry를 시작으로 NOT EXISTS anti join을 써서 business_tx가 없는 고아 원장을 찾는 비정본 Q36 예시다.

코드 연결
1~10줄
비유
원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사
비유의 끝
workbook 제공 정답이 아니다

원문 11–20줄

11~20줄을 한 덩어리로 읽어 2번째 움직임을 본다. ledger_entry를 시작으로 NOT EXISTS anti join을 써서 business_tx가 없는 고아 원장을 찾는 비정본 Q36 예시다.

코드 연결
11~20줄
비유
원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사
비유의 끝
정상 fixture에서는 FK 때문에 0행이다

원문 21–25줄

21~25줄을 한 덩어리로 읽어 3번째 움직임을 본다. ledger_entry를 시작으로 NOT EXISTS anti join을 써서 business_tx가 없는 고아 원장을 찾는 비정본 Q36 예시다.

코드 연결
21~25줄
비유
원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사
비유의 끝
production FK를 제거하지 않는다
문제의 첫 장면
  1. 첫 고정값은 `NOT EXISTS` 맞아?

  2. ledger_entry를 시작으로 NOT EXISTS anti join을 써서 business_tx가 없는 고아 원장을 찾는 비정본 Q36 예시다.

  3. 원문에서 `NOT EXISTS`이 생기는 위치를 찾자.

  4. 그리고 `workbook 제공 정답이 아니다`도 같이 적어.

입력에서 결과까지
  1. `ledger grain`은 언제 생겨?

  2. ledger_entry를 시작 grain으로 읽는다. → 각 tx_id의 business_tx 존재를 찾는다.

  3. 존재하지 않는 원장만 남긴다. → FK 정상 fixture의 0행 이유를 설명한다.

  4. 관찰값과 `정상 fixture에서는 FK 때문에 0행이다`을 분리하면 돼.

04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

감사 규칙상 연결 대상인 원본 23줄을 빠짐없이 연결합니다.

단어 몇 개만 뽑은 표가 아닙니다.학습용 예시 · 정본 답안 아님에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.23 / 23 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F10-L01 -- 학습용 예시 · 정본 답안 아님: workbook은 W22-SQL-Q36 답안을 제공하지 않는다. 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `NOT EXISTS` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
workbook 제공 정답이 아니다
2줄F10-L02 -- 입력 grain: ledger_entry 한 행 = 원장 entry. 출력 grain: 참조 business_tx가 없는 원장 entry 한 행. 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `ledger grain` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
정상 fixture에서는 FK 때문에 0행이다
3줄F10-L03 -- 핵심 도구: NOT EXISTS anti join. NULL 비교 함정이 있는 NOT IN보다 의도가 직접적이다. 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 matching business_tx가 없는 ledger row만 남기는 anti join 조건을 연다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `fixture rows=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production FK를 제거하지 않는다
4줄F10-L04 SET search_path TO workbook_schema, public; 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 비정본 anti-join SQL 예시의 4번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `NOT NULL FK` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
0행은 query 실패가 아니라 제약이 지켜진 결과다
6줄F10-L06 SELECT 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 SQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `NOT EXISTS` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
정상 fixture에서는 FK 때문에 0행이다
7줄F10-L07 le.entry_id, 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 비정본 anti-join SQL 예시의 7번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `ledger grain` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production FK를 제거하지 않는다
8줄F10-L08 le.tx_id, 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 비정본 anti-join SQL 예시의 8번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `fixture rows=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
0행은 query 실패가 아니라 제약이 지켜진 결과다
9줄F10-L09 le.request_id, 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 비정본 anti-join SQL 예시의 9번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `NOT NULL FK` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
workbook 제공 정답이 아니다
10줄F10-L10 le.account_id, 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 비정본 anti-join SQL 예시의 10번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `isolated broken-table counterexample` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
정상 fixture에서는 FK 때문에 0행이다
11줄F10-L11 le.entry_type, 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 비정본 anti-join SQL 예시의 11번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `NOT EXISTS` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production FK를 제거하지 않는다
12줄F10-L12 le.signed_amount, 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 비정본 anti-join SQL 예시의 12번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `ledger grain` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
0행은 query 실패가 아니라 제약이 지켜진 결과다
13줄F10-L13 le.occurred_at 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 비정본 anti-join SQL 예시의 13번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `fixture rows=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
workbook 제공 정답이 아니다
14줄F10-L14 FROM ledger_entry AS le 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 SQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `NOT NULL FK` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
정상 fixture에서는 FK 때문에 0행이다
15줄F10-L15 WHERE NOT EXISTS ( 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 matching business_tx가 없는 ledger row만 남기는 anti join 조건을 연다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `isolated broken-table counterexample` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production FK를 제거하지 않는다
16줄F10-L16 SELECT 1 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 SQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `NOT EXISTS` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
0행은 query 실패가 아니라 제약이 지켜진 결과다
17줄F10-L17 FROM business_tx AS tx 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 SQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `ledger grain` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
workbook 제공 정답이 아니다
18줄F10-L18 WHERE tx.tx_id = le.tx_id 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 outer ledger tx_id와 inner transaction tx_id를 상관 equality로 연결한다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `fixture rows=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
정상 fixture에서는 FK 때문에 0행이다
19줄F10-L19 ) 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `NOT NULL FK` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production FK를 제거하지 않는다
20줄F10-L20 ORDER BY le.entry_id; 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 SQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `isolated broken-table counterexample` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
0행은 query 실패가 아니라 제약이 지켜진 결과다
22줄F10-L22 -- canonical fixture oracle: 0행. 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `ledger grain` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
정상 fixture에서는 FK 때문에 0행이다
23줄F10-L23 -- 이유: ledger_entry.tx_id는 NOT NULL이면서 business_tx(tx_id)를 참조하는 즉시 FK다. 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `fixture rows=0` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
production FK를 제거하지 않는다
24줄F10-L24 -- 따라서 정상 제약을 켠 채로는 '원장은 있으나 거래가 없는' 고아 행을 INSERT할 수 없다. 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `NOT NULL FK` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
0행은 query 실패가 아니라 제약이 지켜진 결과다
25줄F10-L25 -- 반례는 FK를 제거한 격리 복제 table 또는 제약이 깨진 import snapshot에서만 만들고 production table은 바꾸지 않는다. 원장 카드마다 거래 원본 보관함을 찾아보고, 짝이 하나도 없는 카드만 남기는 분실물 검사 이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
입력
ledger_entry와 business_tx의 tx_id 관계
결과·효과
이 줄 뒤에는 항목 전체의 `isolated broken-table counterexample` 대조에 필요한 중간 상태가 생긴다. 이 한 줄만으로 Green이 되지는 않는다.
비유의 한계
workbook 제공 정답이 아니다
Green 범위
  1. marker나 파일이 보이면 전부 성공이야?

  2. 아니. source가 직접 검증한 범위만 말해야 해.

  3. 직접 연결되는 대표 값은 `isolated broken-table counterexample`이야.

  4. `production FK를 제거하지 않는다`는 별도 증거가 필요해.

05

STEP 05 / 13

원본 코드 조각

원본을 3개 의미 조각으로 나누어 그대로 확인합니다.

파일을 한꺼번에 외우지 않고 실행 의미가 이어지는 작은 조각으로 봅니다. 아래 코드는 prompt·fixture·가정을 밝힌 학습용 예시 source이며, 제공 정본 답안이 아닙니다.

F10-C01 · 원문 1–10줄1–10줄
1–10줄 원본
-- 학습용 예시 · 정본 답안 아님: workbook은 W22-SQL-Q36 답안을 제공하지 않는다.
-- 입력 grain: ledger_entry 한 행 = 원장 entry. 출력 grain: 참조 business_tx가 없는 원장 entry 한 행.
-- 핵심 도구: NOT EXISTS anti join. NULL 비교 함정이 있는 NOT IN보다 의도가 직접적이다.
SET search_path TO workbook_schema, public;

SELECT
    le.entry_id,
    le.tx_id,
    le.request_id,
    le.account_id,
F10-C02 · 원문 11–20줄11–20줄
11–20줄 원본
    le.entry_type,
    le.signed_amount,
    le.occurred_at
FROM ledger_entry AS le
WHERE NOT EXISTS (
    SELECT 1
    FROM business_tx AS tx
    WHERE tx.tx_id = le.tx_id
)
ORDER BY le.entry_id;
F10-C03 · 원문 21–25줄21–25줄
21–25줄 원본

-- canonical fixture oracle: 0행.
-- 이유: ledger_entry.tx_id는 NOT NULL이면서 business_tx(tx_id)를 참조하는 즉시 FK다.
-- 따라서 정상 제약을 켠 채로는 '원장은 있으나 거래가 없는' 고아 행을 INSERT할 수 없다.
-- 반례는 FK를 제거한 격리 복제 table 또는 제약이 깨진 import snapshot에서만 만들고 production table은 바꾸지 않는다.
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

비어 있지 않은 23줄을 모두 한국어로 옮깁니다.

전체 번역 23 / 23

비어 있지 않은 원본 줄은 하나도 생략하지 않습니다.

원본한국어 번역
1-- 학습용 예시 · 정본 답안 아님: workbook은 W22-SQL-Q36 답안을 제공하지 않는다.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
2-- 입력 grain: ledger_entry 한 행 = 원장 entry. 출력 grain: 참조 business_tx가 없는 원장 entry 한 행.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
3-- 핵심 도구: NOT EXISTS anti join. NULL 비교 함정이 있는 NOT IN보다 의도가 직접적이다.matching business_tx가 없는 ledger row만 남기는 anti join 조건을 연다.
4SET search_path TO workbook_schema, public;비정본 anti-join SQL 예시의 4번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
6SELECTSQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
7 le.entry_id,비정본 anti-join SQL 예시의 7번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
8 le.tx_id,비정본 anti-join SQL 예시의 8번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
9 le.request_id,비정본 anti-join SQL 예시의 9번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
10 le.account_id,비정본 anti-join SQL 예시의 10번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
11 le.entry_type,비정본 anti-join SQL 예시의 11번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
12 le.signed_amount,비정본 anti-join SQL 예시의 12번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
13 le.occurred_at비정본 anti-join SQL 예시의 13번째 원문을 앞 guard와 뒤 관찰값 사이에 연결한다.
14FROM ledger_entry AS leSQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
15WHERE NOT EXISTS (matching business_tx가 없는 ledger row만 남기는 anti join 조건을 연다.
16 SELECT 1SQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
17 FROM business_tx AS txSQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
18 WHERE tx.tx_id = le.tx_idouter ledger tx_id와 inner transaction tx_id를 상관 equality로 연결한다.
19)현재 object·array·block 또는 query 범위를 열거나 닫아 구조를 유지한다.
20ORDER BY le.entry_id;SQL의 입력 grain·필터·집계·stable 출력 순서를 구성하는 절이다.
22-- canonical fixture oracle: 0행.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
23-- 이유: ledger_entry.tx_id는 NOT NULL이면서 business_tx(tx_id)를 참조하는 즉시 FK다.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
24-- 따라서 정상 제약을 켠 채로는 '원장은 있으나 거래가 없는' 고아 행을 INSERT할 수 없다.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
25-- 반례는 FK를 제거한 격리 복제 table 또는 제약이 깨진 import snapshot에서만 만들고 production table은 바꾸지 않는다.이 source의 비정본 provenance, 가정, 반례, 또는 실행 경계를 사람이 확인할 주석이다.
07

STEP 07 / 13

기존 수준의 한 줄 읽기·문법 해부

쉬운 설명 다음에 문법과 실행 순서를 정밀하게 읽습니다.

한 줄로 읽기

ledger_entry를 시작으로 NOT EXISTS anti join을 써서 business_tx가 없는 고아 원장을 찾는 비정본 Q36 예시다. 다만 workbook 제공 정답이 아니다

문법 해부

  • `NOT EXISTS`는 현재 ledger row와 같은 tx_id의 business_tx가 하나라도 있는지 반대로 검사한다.
  • 상관 subquery의 equality가 outer `le.tx_id`를 inner `tx.tx_id`와 연결한다.

실행 순서

  1. ledger_entry를 시작 grain으로 읽는다.
  2. 각 tx_id의 business_tx 존재를 찾는다.
  3. 존재하지 않는 원장만 남긴다.
  4. FK 정상 fixture의 0행 이유를 설명한다.

W22 조각별 정밀 해설

F10-C01 · 원문 1–10줄
문법 해부
1~10줄의 `원문 1–10줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `NOT EXISTS`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `NOT EXISTS`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: workbook 제공 정답이 아니다.
착각 방지
`원문 1–10줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: workbook 제공 정답이 아니다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F10-C02 · 원문 11–20줄
문법 해부
11~20줄의 `원문 11–20줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `ledger grain`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `ledger grain`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: 정상 fixture에서는 FK 때문에 0행이다.
착각 방지
`원문 11–20줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: 정상 fixture에서는 FK 때문에 0행이다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
F10-C03 · 원문 21–25줄
문법 해부
21~25줄의 `원문 21–25줄`을 입력·guard·관찰·cleanup 단계로 나눈다.
실제 값 추적
항목 전체 흐름에 연결해 `fixture rows=0`을 대조한다. 이 값이 chunk 단독 산출이라는 뜻은 아니다.
정상 예
정상 예에서는 source 순서와 owner 계약이 일치해 `fixture rows=0`을 관찰한다.
틀린 예·반례
반례에서는 선행 guard·stable order·cleanup을 생략한다. 동결 경계: production FK를 제거하지 않는다.
착각 방지
`원문 21–25줄`이 항목 전체 Green을 단독 증명한다고 읽지 않는다.
하지 않는 일
이 chunk가 책임지지 않는 범위: production FK를 제거하지 않는다.
다음 연결
다음 source chunk의 입력 또는 최종 marker/SQL oracle로 결과를 넘긴다.
반례
  1. 겉보기에는 맞지만 깨지는 예는?

  2. FROM business_tx로 시작해 고아 ledger를 잃는다

  3. 그 상태는 owner·입력·관찰 중 한 칸이 비어 있어.

  4. 수정한 뒤 같은 source와 hash로 다시 대조해.

08

STEP 08 / 13

실제 값 따라가기

같은 입력값이 어느 줄을 지나 어떤 결과가 되는지 추적합니다.

순서들어온 값코드가 하는 일나온 값·상태경계
F10-T01 normal16 ledger rowsanti join0 orphanquery 실패가 아님
F10-T02 constraintNOT NULL FKinsert guardorphan 생성 거절immediate FK
F10-T03 counterexampleisolated broken copysame NOT EXISTSorphan 발견production FK 제거 금지
책임 경계
  1. 이 항목의 마지막 책임선은?

  2. 직접 역할은 `비정본 anti-join SQL 예시`이야.

  3. 대표 경계는 `0행은 query 실패가 아니라 제약이 지켜진 결과다`이야.

  4. 정본/비정본 label과 evidence owner까지 확인하면 끝이야.

09

STEP 09 / 13

GitHub·AWS·PowerShell·PostgreSQL 내부에서 벌어지는 일

GitHub·AWS·PowerShell·PostgreSQL에서 실제로 일어나는 일과 증명 범위를 구분합니다.

anti join

각 outer row에 matching inner row가 없을 때만 출력한다.

NOT IN의 NULL 의미와 다르다.
foreign key

ledger tx_id가 존재하는 business_tx를 참조하게 한다.

disable/import corruption 상황은 별도다.
optimizer

PostgreSQL이 NOT EXISTS를 anti-join plan으로 바꿀 수 있다.

plan 형태보다 결과 grain이 우선이다.
10

STEP 10 / 13

흔한 착각과 틀린 예

그럴듯하지만 틀린 해석을 반례로 고칩니다.

❌ FROM business_tx로 시작해 고아 ledger를 잃는다

왜 틀리나 비정본 anti-join SQL 예시의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 ledger_entry를 시작 grain으로 읽는다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `workbook 제공 정답이 아니다` 상태인데도 Green을 주장하게 된다.

❌ NOT IN NULL 함정을 설명하지 않는다

왜 틀리나 비정본 anti-join SQL 예시의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 각 tx_id의 business_tx 존재를 찾는다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `정상 fixture에서는 FK 때문에 0행이다` 상태인데도 Green을 주장하게 된다.

❌ 0행이면 SQL이 틀렸다고 본다

왜 틀리나 비정본 anti-join SQL 예시의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 존재하지 않는 원장만 남긴다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `production FK를 제거하지 않는다` 상태인데도 Green을 주장하게 된다.

❌ 반례를 위해 production FK를 제거한다

왜 틀리나 비정본 anti-join SQL 예시의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 FK 정상 fixture의 0행 이유를 설명한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `0행은 query 실패가 아니라 제약이 지켜진 결과다` 상태인데도 Green을 주장하게 된다.

❌ Q36을 workbook 정본 답안이라 부른다

왜 틀리나 비정본 anti-join SQL 예시의 owner·관찰·경계 중 적어도 하나를 건너뛴다.

바르게 읽기 FK 정상 fixture의 0행 이유를 설명한다. 그리고 source의 실제 값과 hash를 다시 대조한다.

반례 반례에서는 `workbook 제공 정답이 아니다` 상태인데도 Green을 주장하게 된다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

이 코드가 책임지지 않는 일을 분리합니다.

직접 미보장

workbook 제공 정답이 아니다

이 책임을 맡는 곳: 별도 외부/selector 실행
직접 미보장

정상 fixture에서는 FK 때문에 0행이다

이 책임을 맡는 곳: secret·운영 정책
직접 미보장

production FK를 제거하지 않는다

이 책임을 맡는 곳: infrastructure·사람 검토
직접 미보장

0행은 query 실패가 아니라 제약이 지켜진 결과다

이 책임을 맡는 곳: owner lifecycle
12

STEP 12 / 13

직접 다시 써보기

뜻 → 조각 → 전체 코드 순서로 다시 씁니다.

1단계 · 뜻부터 복원

다음 역할을 고정값과 미보장 경계까지 말한다: ledger_entry를 시작으로 NOT EXISTS anti join을 써서 business_tx가 없는 고아 원장을 찾는 비정본 Q36 예시다.

2단계 · 코드 조각 재조립

  1. 원문 1–10줄
  2. 원문 11–20줄
  3. 원문 21–25줄

3단계 · 파일 전체 다시 쓰기

25개 물리 줄을 원본 순서로 복원하고 SHA-256 4b5386b1980438dd71e7733124a273ada398a924cd0ad4e5beb6e4f35010c12e와 대조한다.

자가 점검
  • 원본 source/template bytes를 바꾸지 않았는가?
  • 외부 미실행과 local restore Green을 구분했는가?
  • secret 원문을 evidence에 남기지 않았는가?
  • D7 checked_at 충돌과 사람 검토 경계를 보았는가?
  • Q35/Q36을 workbook 정본 답안이라고 부르지 않았는가?
13

STEP 13 / 13

전체 원본 source

감사로 고정한 전체 source를 가감 없이 확인합니다.

학습용 예시 전체 확인하기 · 정본 답안 아님
학습용 예시 · 정본 답안 아님illustrative/sql/W22-SQL-Q36.sqlSHA-256 4b5386b1980438dd71e7733124a273ada398a924cd0ad4e5beb6e4f35010c12e
W22-SQL-Q36 — NOT EXISTS와 FK 정상계의 0행 oracle 전체
-- 학습용 예시 · 정본 답안 아님: workbook은 W22-SQL-Q36 답안을 제공하지 않는다.
-- 입력 grain: ledger_entry 한 행 = 원장 entry. 출력 grain: 참조 business_tx가 없는 원장 entry 한 행.
-- 핵심 도구: NOT EXISTS anti join. NULL 비교 함정이 있는 NOT IN보다 의도가 직접적이다.
SET search_path TO workbook_schema, public;

SELECT
    le.entry_id,
    le.tx_id,
    le.request_id,
    le.account_id,
    le.entry_type,
    le.signed_amount,
    le.occurred_at
FROM ledger_entry AS le
WHERE NOT EXISTS (
    SELECT 1
    FROM business_tx AS tx
    WHERE tx.tx_id = le.tx_id
)
ORDER BY le.entry_id;

-- canonical fixture oracle: 0행.
-- 이유: ledger_entry.tx_id는 NOT NULL이면서 business_tx(tx_id)를 참조하는 즉시 FK다.
-- 따라서 정상 제약을 켠 채로는 '원장은 있으나 거래가 없는' 고아 행을 INSERT할 수 없다.
-- 반례는 FK를 제거한 격리 복제 table 또는 제약이 깨진 import snapshot에서만 만들고 production table은 바꾸지 않는다.