W24 · 공통 거래 코어 v1 동결

24주차 코드 뒤풀이: exact test Gate부터 데모·리뷰·트랙·릴리스까지

37개 class·66개 test의 exact inventory와 43개 selector를 읽고, numeric accountId demo의 201→200→409→대사0 흐름, architecture·README·external review·track 선택의 사람 검토 경계, DB·host JVM cleanup까지 하나의 release evidence 사슬로 연결합니다. PDF 전문 정본 7개, ZIP 보조 계약 2개, 비정본 학습 예시 8개를 구분하며 실제 Gradle·Docker·HTTP·PostgreSQL·외부 review 실행 성공은 주장하지 않습니다.

패키지 정본 보조 계약 · exact JSON bytes 1개패키지 정본 보조 계약 · exact Gradle gate bytes 1개PDF 전문 정본 · packaged PowerShell source 7개학습용 예시 · PDF inline PowerShell · 정본 답안 아님 · 비실행 2개학습용 예시 · PDF template/validator · 정본 답안 아님 4개학습용 예시 · Q39/Q40 prompt 기반 SQL · 정본 답안 아님 · workbook 제공 정답 아님 2개항목마다 13단계연결 640줄번역 640줄원문 PDF 785–819쪽
01

core-v1-expected.json — 37개 class·66개 test의 exact 계약

learning_stages/w24/overlay/core-v1-expected.json

패키지 정본 보조 계약 · exact JSON bytes · 정본 · W24-F01
1줄 연결1줄 번역1 chunks
01

STEP 01 / 13

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

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

오늘의 한 문장

coreV1Gate가 받아야 할 37개 JUnit class와 class별 test 수, selector 합계 43을 한 JSON 계약으로 고정한다.

  1. selectors=43은 어느 source와 실제 결과에서 확인해야 할까?
  2. 첫 실패를 만드는 조건과 fail-closed 지점은 어디일까?
  3. 왜 ‘목록 자체는 test 실행 결과가 아니다’를 별도 경계로 남겨야 할까?
이 파일에서 끝까지 다시 쓰는 값selectors=43classes=37tests=66minified one-line JSON
왜 필요한가 — core-v1-expected.json — 37개 class·66개 test의 exact 계약히토리 → 니지카 → 료 → 키타
  1. 히토리

    selectors=43가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 coreV1Gate가 받아야 할 37개 JUnit class와 class별 test 수, selector 합계 43을 한 JSON 계약으로 고정한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘목록 자체는 test 실행 결과가 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 selectors=43와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

02

STEP 02 / 13

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

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

새 기능을 멈춘 팀이 코드·test·문서·demo를 같은 release 후보에 묶어 하나씩 검수한다.

검수 도장이 붙은 공통 거래 코어 출고 상자

이 파일은 coreV1Gate가 받아야 할 37개 JUnit class와 class별 test 수, selector 합계 43을 한 JSON 계약으로 고정한다. 눈으로 읽을 때는 각 줄을 검수표 한 칸처럼 보고, 입력과 다음 상태를 놓치지 않는다.

마지막 도장은 source shape와 실제 runtime·사람 검토를 구분한 뒤에만 찍는다. 특히 목록 자체는 test 실행 결과가 아니다

딱 여기까지만 비유는 실행 순서를 돕지만 실제 Gradle·Docker·DB·사람 review를 대신하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

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

값 1: selectors=43

이 파일에서 계속 확인할 고정 단서가 selectors=43다.

코드 연결
F01 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
목록 자체는 test 실행 결과가 아니다

값 2: classes=37

이 파일에서 계속 확인할 고정 단서가 classes=37다.

코드 연결
F01 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
unexpected class도 별도 검출해야 한다

값 3: tests=66

이 파일에서 계속 확인할 고정 단서가 tests=66다.

코드 연결
F01 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
skip은 성공으로 세지 않는다

값 4: minified one-line JSON

이 파일에서 계속 확인할 고정 단서가 minified one-line JSON다.

코드 연결
F01 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
목록 자체는 test 실행 결과가 아니다
04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

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

단어 몇 개만 뽑은 표가 아닙니다.패키지 정본 보조 계약 · exact JSON bytes에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.1 / 1 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F01-L01 {"selectors":43,"classes":{"com.example.financialcore.account.AccountJpaMappingTest":1,"com.example.financialcore.account.AccountServiceTest":1,"com.example.financialcore.account.AccountTest":5,"com.example.financialcore.account.api.AccountControllerHappyPathTest":1,"com.example.financialcore.account.api.AccountControllerPersistenceIT":1,"com.example.financialcore.account.api.AccountControllerTest":4,"com.example.financialcore.account.api.CreateAccountRequestValidationTest":1,"com.example.financialcore.account.ConcurrentWithdraw20IT":1,"com.example.financialcore.account.LostUpdateBaselineIT":2,"com.example.financialcore.account.OpeningIntegrationTest":1,"com.example.financialcore.account.OptimisticAccountIT":1,"com.example.financialcore.api.ApiExceptionHandlerTest":1,"com.example.financialcore.api.RequestIdFilterTest":2,"com.example.financialcore.ApplicationContextTest":1,"com.example.financialcore.audit.AuditPropagationIT":1,"com.example.financialcore.ConcurrencyHarnessTest":4,"com.example.financialcore.CoreSchemaIT":1,"com.example.financialcore.idempotency.AtomicClaim50IT":2,"com.example.financialcore.idempotency.IdempotencySchemaIT":1,"com.example.financialcore.idempotency.RequestHasherTest":2,"com.example.financialcore.ledger.LedgerQueryIT":2,"com.example.financialcore.ledger.LedgerQueryLimitTest":1,"com.example.financialcore.security.CloudFailClosedSecurityIT":1,"com.example.financialcore.security.MaskingTest":2,"com.example.financialcore.security.ObjectAuthorizationIT":2,"com.example.financialcore.security.SecurityStatusContractTest":1,"com.example.financialcore.transfer.api.TransferControllerHappyPathTest":1,"com.example.financialcore.transfer.api.TransferControllerReplayTest":1,"com.example.financialcore.transfer.api.TransferControllerTest":4,"com.example.financialcore.transfer.api.TransferRequestValidationTest":1,"com.example.financialcore.transfer.SortedLockTransferIT":1,"com.example.financialcore.transfer.TransactionPropagationIT":1,"com.example.financialcore.transfer.TransactionProxyIT":1,"com.example.financialcore.transfer.TransferBalanceIT":1,"com.example.financialcore.transfer.TransferFailurePointIT":2,"com.example.financialcore.transfer.TransferIdempotencyIT":1,"com.example.financialcore.transfer.TransferIntegrationTest":9}} 출고표 1번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 selector 총수를 JSON 계약에 고정한다.
입력
"selectors", 43, "classes"
결과·효과
관찰 상태 F01-001가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
목록 자체는 test 실행 결과가 아니다
05

STEP 05 / 13

원본 코드 조각

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

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

F01-C01 · 원문 1–1줄1–1줄
1–1줄 원본
{"selectors":43,"classes":{"com.example.financialcore.account.AccountJpaMappingTest":1,"com.example.financialcore.account.AccountServiceTest":1,"com.example.financialcore.account.AccountTest":5,"com.example.financialcore.account.api.AccountControllerHappyPathTest":1,"com.example.financialcore.account.api.AccountControllerPersistenceIT":1,"com.example.financialcore.account.api.AccountControllerTest":4,"com.example.financialcore.account.api.CreateAccountRequestValidationTest":1,"com.example.financialcore.account.ConcurrentWithdraw20IT":1,"com.example.financialcore.account.LostUpdateBaselineIT":2,"com.example.financialcore.account.OpeningIntegrationTest":1,"com.example.financialcore.account.OptimisticAccountIT":1,"com.example.financialcore.api.ApiExceptionHandlerTest":1,"com.example.financialcore.api.RequestIdFilterTest":2,"com.example.financialcore.ApplicationContextTest":1,"com.example.financialcore.audit.AuditPropagationIT":1,"com.example.financialcore.ConcurrencyHarnessTest":4,"com.example.financialcore.CoreSchemaIT":1,"com.example.financialcore.idempotency.AtomicClaim50IT":2,"com.example.financialcore.idempotency.IdempotencySchemaIT":1,"com.example.financialcore.idempotency.RequestHasherTest":2,"com.example.financialcore.ledger.LedgerQueryIT":2,"com.example.financialcore.ledger.LedgerQueryLimitTest":1,"com.example.financialcore.security.CloudFailClosedSecurityIT":1,"com.example.financialcore.security.MaskingTest":2,"com.example.financialcore.security.ObjectAuthorizationIT":2,"com.example.financialcore.security.SecurityStatusContractTest":1,"com.example.financialcore.transfer.api.TransferControllerHappyPathTest":1,"com.example.financialcore.transfer.api.TransferControllerReplayTest":1,"com.example.financialcore.transfer.api.TransferControllerTest":4,"com.example.financialcore.transfer.api.TransferRequestValidationTest":1,"com.example.financialcore.transfer.SortedLockTransferIT":1,"com.example.financialcore.transfer.TransactionPropagationIT":1,"com.example.financialcore.transfer.TransactionProxyIT":1,"com.example.financialcore.transfer.TransferBalanceIT":1,"com.example.financialcore.transfer.TransferFailurePointIT":2,"com.example.financialcore.transfer.TransferIdempotencyIT":1,"com.example.financialcore.transfer.TransferIntegrationTest":9}}
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

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

전체 번역 1 / 1

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

원본한국어 번역
1{"selectors":43,"classes":{"com.example.financialcore.account.AccountJpaMappingTest":1,"com.example.financialcore.account.AccountServiceTest":1,"com.example.financialcore.account.AccountTest":5,"com.example.financialcore.account.api.AccountControllerHappyPathTest":1,"com.example.financialcore.account.api.AccountControllerPersistenceIT":1,"com.example.financialcore.account.api.AccountControllerTest":4,"com.example.financialcore.account.api.CreateAccountRequestValidationTest":1,"com.example.financialcore.account.ConcurrentWithdraw20IT":1,"com.example.financialcore.account.LostUpdateBaselineIT":2,"com.example.financialcore.account.OpeningIntegrationTest":1,"com.example.financialcore.account.OptimisticAccountIT":1,"com.example.financialcore.api.ApiExceptionHandlerTest":1,"com.example.financialcore.api.RequestIdFilterTest":2,"com.example.financialcore.ApplicationContextTest":1,"com.example.financialcore.audit.AuditPropagationIT":1,"com.example.financialcore.ConcurrencyHarnessTest":4,"com.example.financialcore.CoreSchemaIT":1,"com.example.financialcore.idempotency.AtomicClaim50IT":2,"com.example.financialcore.idempotency.IdempotencySchemaIT":1,"com.example.financialcore.idempotency.RequestHasherTest":2,"com.example.financialcore.ledger.LedgerQueryIT":2,"com.example.financialcore.ledger.LedgerQueryLimitTest":1,"com.example.financialcore.security.CloudFailClosedSecurityIT":1,"com.example.financialcore.security.MaskingTest":2,"com.example.financialcore.security.ObjectAuthorizationIT":2,"com.example.financialcore.security.SecurityStatusContractTest":1,"com.example.financialcore.transfer.api.TransferControllerHappyPathTest":1,"com.example.financialcore.transfer.api.TransferControllerReplayTest":1,"com.example.financialcore.transfer.api.TransferControllerTest":4,"com.example.financialcore.transfer.api.TransferRequestValidationTest":1,"com.example.financialcore.transfer.SortedLockTransferIT":1,"com.example.financialcore.transfer.TransactionPropagationIT":1,"com.example.financialcore.transfer.TransactionProxyIT":1,"com.example.financialcore.transfer.TransferBalanceIT":1,"com.example.financialcore.transfer.TransferFailurePointIT":2,"com.example.financialcore.transfer.TransferIdempotencyIT":1,"com.example.financialcore.transfer.TransferIntegrationTest":9}}실행 의미: selector 총수를 JSON 계약에 고정한다.
07

STEP 07 / 13

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

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

한 줄로 읽기

core-v1-expected.json — 37개 class·66개 test의 exact 계약는 coreV1Gate가 받아야 할 37개 JUnit class와 class별 test 수, selector 합계 43을 한 JSON 계약으로 고정한다.

문법 해부

  • .json 문법에서 선언·조건·pipeline·block 경계를 먼저 나눈다.
  • expected 값과 actual 결과를 같은 이름처럼 보여도 서로 다른 source로 읽는다.
  • native exit·row count·hash·사람 판정을 서로 대체하지 않는다.

실행 순서

  1. 입력 경로·fixture·환경변수·expected 계약을 고정한다.
  2. source가 실행하는 native process·HTTP·SQL 또는 형식 검사를 따라간다.
  3. actual 값과 exact marker를 대조하고 실패면 성공 발행 전에 중단한다.
  4. finally cleanup과 비범위를 evidence에 남긴다.

W24 조각별 정밀 해설

F01-C01 · 원문 1–1줄
문법 해부
.json 문법으로 1–1줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
selectors=43, classes=37, tests=66를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
목록 자체는 test 실행 결과가 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
목록 자체는 test 실행 결과가 아니다; unexpected class도 별도 검출해야 한다; skip은 성공으로 세지 않는다
다음 연결
다음 조각 또는 F01 evidence 판정으로 상태를 넘긴다.
실행 순서 — core-v1-expected.json — 37개 class·66개 test의 exact 계약히토리 → 니지카 → 료 → 키타
  1. 히토리

    classes=37가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 coreV1Gate가 받아야 할 37개 JUnit class와 class별 test 수, selector 합계 43을 한 JSON 계약으로 고정한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘unexpected class도 별도 검출해야 한다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 classes=37와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

08

STEP 08 / 13

실제 값 따라가기

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

순서들어온 값코드가 하는 일나온 값·상태경계
입력selectors=43source 계약에 대입F01 실행/설명 시작 상태목록 자체는 test 실행 결과가 아니다
검증classes=37expected와 actual 또는 형식 대조통과 또는 첫 mismatchunexpected class도 별도 검출해야 한다
증거minified one-line JSONmarker·hash·row를 같은 run에 연결범위가 적힌 evidence 후보skip은 성공으로 세지 않는다
실제 값 — core-v1-expected.json — 37개 class·66개 test의 exact 계약히토리 → 니지카 → 료 → 키타
  1. 히토리

    tests=66가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 coreV1Gate가 받아야 할 37개 JUnit class와 class별 test 수, selector 합계 43을 한 JSON 계약으로 고정한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘skip은 성공으로 세지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 tests=66와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

09

STEP 09 / 13

Gradle·PowerShell·HTTP·PostgreSQL 내부에서 벌어지는 일

Gradle·JUnit XML·PowerShell·HTTP·PostgreSQL·Docker에서 실제로 일어나는 일과 증명 범위를 구분합니다.

source/contract

core-v1-expected.json bytes와 expected 값을 읽는다.

파일 존재만으로 runtime 성공은 아니다.
execution/evidence

native exit·HTTP status·JUnit XML·DB row·hash 중 이 파일이 소유한 값을 만든다.

목록 자체는 test 실행 결과가 아니다
release/human

관련 evidence와 사람 의미 검토를 release 후보에 연결한다.

skip은 성공으로 세지 않는다
첫 실패 경계 — core-v1-expected.json — 37개 class·66개 test의 exact 계약히토리 → 니지카 → 료 → 키타
  1. 히토리

    minified one-line JSON가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 coreV1Gate가 받아야 할 37개 JUnit class와 class별 test 수, selector 합계 43을 한 JSON 계약으로 고정한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘목록 자체는 test 실행 결과가 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 minified one-line JSON와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

10

STEP 10 / 13

흔한 착각과 틀린 예

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

❌ selectors=43 문자열이 source에 있으니 실제 실행도 Green이다.

왜 틀리나 source literal과 runtime 관찰값은 다른 증거다.

바르게 읽기 native exit·actual XML/HTTP/DB evidence를 별도로 확인한다.

반례 script가 실행 전 경로 오류로 멈춰도 literal은 그대로 남는다.

❌ 파일 SHA-256이 있으면 내용의 의미와 사실성도 검증됐다.

왜 틀리나 hash는 동일 bytes만 말한다.

바르게 읽기 schema·수치·질문·근거는 별도 자동 또는 사람 판정을 거친다.

반례 빈 review 질문을 가진 CSV도 안정된 hash를 가진다.

❌ LOCAL_ARTIFACT_VALIDATED는 release Green과 같다.

왜 틀리나 generic validator는 파일 shape만 확인한다.

바르게 읽기 HUMAN_SEMANTIC_REVIEW_REQUIRED를 유지한다.

반례 잘못된 track 점수표도 byte 수 조건은 통과할 수 있다.

❌ 이 파일이 W24 전체 lifecycle을 모두 소유한다.

왜 틀리나 각 source는 Gate·demo·cleanup·사람 review 중 일부만 담당한다.

바르게 읽기 owner와 non-responsibility를 release manifest에서 분리한다.

반례 D4 source audit에는 runtime_claim=false가 명시된다.

❌ 이전 주 Green이나 오래된 log를 현재 commit 결과로 재사용한다.

왜 틀리나 source·commit·actual result가 같은 실행에 묶이지 않는다.

바르게 읽기 release 후보에서 새 evidence와 hash를 만든다.

반례 expected JSON이 바뀌면 예전 XML은 exact inventory를 증명하지 못한다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

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

증명 범위

목록 자체는 test 실행 결과가 아니다

이 책임을 맡는 곳: runtime Gate
증명 범위

unexpected class도 별도 검출해야 한다

이 책임을 맡는 곳: external/human review
증명 범위

skip은 성공으로 세지 않는다

이 책임을 맡는 곳: release manifest
증명 범위

목록 자체는 test 실행 결과가 아니다

이 책임을 맡는 곳: 운영 환경
증명하지 않는 범위 — core-v1-expected.json — 37개 class·66개 test의 exact 계약히토리 → 니지카 → 료 → 키타
  1. 히토리

    selectors=43가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 coreV1Gate가 받아야 할 37개 JUnit class와 class별 test 수, selector 합계 43을 한 JSON 계약으로 고정한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘unexpected class도 별도 검출해야 한다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 selectors=43와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

12

STEP 12 / 13

직접 다시 써보기

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

1단계 · 뜻부터 복원

  • coreV1Gate가 받아야 할 37개 JUnit class와 class별 test 수, selector 합계 43을 한 JSON 계약으로 고정한다.
  • 핵심 값은 selectors=43, classes=37, tests=66, minified one-line JSON다.

2단계 · 코드 조각 재조립

  1. 1. selector 총수를 JSON 계약에 고정한다

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

learning_stages/w24/overlay/core-v1-expected.json을 새 파일에 다시 쓰고 expected·actual·실패·cleanup·비범위를 주석으로 표시한다.

자가 점검
  • 비어 있지 않은 모든 source 줄을 한 번씩 읽었나?
  • source shape와 runtime Green을 분리했나?
  • 사람 검토·외부 상태를 자동 성공으로 꾸미지 않았나?
  • 첫 실패와 cleanup 책임을 설명할 수 있나?
13

STEP 13 / 13

전체 원본 source

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

원문 정본 전체 source 확인하기
패키지 정본 보조 계약 · exact JSON byteslearning_stages/w24/overlay/core-v1-expected.jsonSHA-256 5c92d521eca38029ef00e115c9b6a52f26edfa6c647d77edc24ece9a3bafad99
core-v1-expected.json — 37개 class·66개 test의 exact 계약 전체
{"selectors":43,"classes":{"com.example.financialcore.account.AccountJpaMappingTest":1,"com.example.financialcore.account.AccountServiceTest":1,"com.example.financialcore.account.AccountTest":5,"com.example.financialcore.account.api.AccountControllerHappyPathTest":1,"com.example.financialcore.account.api.AccountControllerPersistenceIT":1,"com.example.financialcore.account.api.AccountControllerTest":4,"com.example.financialcore.account.api.CreateAccountRequestValidationTest":1,"com.example.financialcore.account.ConcurrentWithdraw20IT":1,"com.example.financialcore.account.LostUpdateBaselineIT":2,"com.example.financialcore.account.OpeningIntegrationTest":1,"com.example.financialcore.account.OptimisticAccountIT":1,"com.example.financialcore.api.ApiExceptionHandlerTest":1,"com.example.financialcore.api.RequestIdFilterTest":2,"com.example.financialcore.ApplicationContextTest":1,"com.example.financialcore.audit.AuditPropagationIT":1,"com.example.financialcore.ConcurrencyHarnessTest":4,"com.example.financialcore.CoreSchemaIT":1,"com.example.financialcore.idempotency.AtomicClaim50IT":2,"com.example.financialcore.idempotency.IdempotencySchemaIT":1,"com.example.financialcore.idempotency.RequestHasherTest":2,"com.example.financialcore.ledger.LedgerQueryIT":2,"com.example.financialcore.ledger.LedgerQueryLimitTest":1,"com.example.financialcore.security.CloudFailClosedSecurityIT":1,"com.example.financialcore.security.MaskingTest":2,"com.example.financialcore.security.ObjectAuthorizationIT":2,"com.example.financialcore.security.SecurityStatusContractTest":1,"com.example.financialcore.transfer.api.TransferControllerHappyPathTest":1,"com.example.financialcore.transfer.api.TransferControllerReplayTest":1,"com.example.financialcore.transfer.api.TransferControllerTest":4,"com.example.financialcore.transfer.api.TransferRequestValidationTest":1,"com.example.financialcore.transfer.SortedLockTransferIT":1,"com.example.financialcore.transfer.TransactionPropagationIT":1,"com.example.financialcore.transfer.TransactionProxyIT":1,"com.example.financialcore.transfer.TransferBalanceIT":1,"com.example.financialcore.transfer.TransferFailurePointIT":2,"com.example.financialcore.transfer.TransferIdempotencyIT":1,"com.example.financialcore.transfer.TransferIntegrationTest":9}}
02

core-v1-gate.gradle — wildcard 없는 exact Gradle selector

learning_stages/w24/overlay/core-v1-gate.gradle

패키지 정본 보조 계약 · exact Gradle gate bytes · 정본 · W24-F02
55줄 연결55줄 번역5 chunks
01

STEP 01 / 13

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

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

오늘의 한 문장

W5–W12 누적 selector와 W19/W20 production contract를 exact includeTestsMatching 목록으로 coreV1Gate에 연결한다.

  1. failOnNoMatchingTests=true은 어느 source와 실제 결과에서 확인해야 할까?
  2. 첫 실패를 만드는 조건과 fail-closed 지점은 어디일까?
  3. 왜 ‘selector가 보여도 실행 Green은 아니다’를 별도 경계로 남겨야 할까?
이 파일에서 끝까지 다시 쓰는 값failOnNoMatchingTests=true43 selectorsJUnit Platformno wildcard
왜 필요한가 — core-v1-gate.gradle — wildcard 없는 exact Gradle selector히토리 → 니지카 → 료 → 키타
  1. 히토리

    failOnNoMatchingTests=true가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 W5–W12 누적 selector와 W19/W20 production contract를 exact includeTestsMatching 목록으로 coreV1Gate에 연결한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘selector가 보여도 실행 Green은 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 failOnNoMatchingTests=true와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

02

STEP 02 / 13

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

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

새 기능을 멈춘 팀이 코드·test·문서·demo를 같은 release 후보에 묶어 하나씩 검수한다.

검수 도장이 붙은 공통 거래 코어 출고 상자

이 파일은 W5–W12 누적 selector와 W19/W20 production contract를 exact includeTestsMatching 목록으로 coreV1Gate에 연결한다. 눈으로 읽을 때는 각 줄을 검수표 한 칸처럼 보고, 입력과 다음 상태를 놓치지 않는다.

마지막 도장은 source shape와 실제 runtime·사람 검토를 구분한 뒤에만 찍는다. 특히 selector가 보여도 실행 Green은 아니다

딱 여기까지만 비유는 실행 순서를 돕지만 실제 Gradle·Docker·DB·사람 review를 대신하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

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

값 1: failOnNoMatchingTests=true

이 파일에서 계속 확인할 고정 단서가 failOnNoMatchingTests=true다.

코드 연결
F02 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
selector가 보여도 실행 Green은 아니다

값 2: 43 selectors

이 파일에서 계속 확인할 고정 단서가 43 selectors다.

코드 연결
F02 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다

값 3: JUnit Platform

이 파일에서 계속 확인할 고정 단서가 JUnit Platform다.

코드 연결
F02 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다

값 4: no wildcard

이 파일에서 계속 확인할 고정 단서가 no wildcard다.

코드 연결
F02 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
XML inventory 검증은 verifier 책임이다
04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

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

단어 몇 개만 뽑은 표가 아닙니다.패키지 정본 보조 계약 · exact Gradle gate bytes에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.55 / 55 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F02-L01 // W13_W24_LEARNER_CORE_V1_GATE 출고표 1번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 core-v1-gate.gradle의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-001가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
selector가 보여도 실행 Green은 아니다
2줄F02-L02 // Exact union of every W5-W12 staged selector plus six production W19/W20 contracts. 출고표 2번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 core-v1-gate.gradle의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-002가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다
3줄F02-L03 tasks.register('coreV1Gate', Test) { 출고표 3번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 Gradle에 coreV1Gate Test task를 등록한다.
입력
'coreV1Gate'
결과·효과
관찰 상태 F02-003가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다
4줄F02-L04 group = 'verification' 출고표 4번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 core-v1-gate.gradle의 다음 검증 또는 설명 단계를 구성한다.
입력
'verification'
결과·효과
관찰 상태 F02-004가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML inventory 검증은 verifier 책임이다
5줄F02-L05 description = 'Exact progressive core V1 release gate; no final-reference-only tests.' 출고표 5번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 core-v1-gate.gradle의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-005가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
selector가 보여도 실행 Green은 아니다
6줄F02-L06 testClassesDirs = sourceSets.test.output.classesDirs 출고표 6번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 class 이름과 기대 test 수를 exact inventory로 고정한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-006가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다
7줄F02-L07 classpath = sourceSets.test.runtimeClasspath 출고표 7번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 core-v1-gate.gradle의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-007가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다
8줄F02-L08 useJUnitPlatform() 출고표 8번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 core-v1-gate.gradle의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-008가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML inventory 검증은 verifier 책임이다
9줄F02-L09 filter { 출고표 9번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-009가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
selector가 보여도 실행 Green은 아니다
10줄F02-L10 failOnNoMatchingTests = true 출고표 10번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 selector가 0개 test를 찾으면 성공 대신 실패하게 한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-010가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다
11줄F02-L11 includeTestsMatching 'com.example.financialcore.ApplicationContextTest' 출고표 11번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-011가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다
12줄F02-L12 includeTestsMatching 'com.example.financialcore.ConcurrencyHarnessTest' 출고표 12번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-012가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML inventory 검증은 verifier 책임이다
13줄F02-L13 includeTestsMatching 'com.example.financialcore.ConcurrencyHarnessTest.fixed_pool_bounds_observed_activity_and_accounts_for_all_tasks' 출고표 13번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-013가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
selector가 보여도 실행 Green은 아니다
14줄F02-L14 includeTestsMatching 'com.example.financialcore.ConcurrencyHarnessTest.ready_timeout_is_a_failure_and_never_a_green_run' 출고표 14번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-014가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다
15줄F02-L15 includeTestsMatching 'com.example.financialcore.CoreSchemaIT' 출고표 15번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
'com.example.financialcore.CoreSchemaIT'
결과·효과
관찰 상태 F02-015가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다
16줄F02-L16 includeTestsMatching 'com.example.financialcore.account.AccountJpaMappingTest' 출고표 16번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-016가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML inventory 검증은 verifier 책임이다
17줄F02-L17 includeTestsMatching 'com.example.financialcore.account.AccountServiceTest' 출고표 17번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-017가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
selector가 보여도 실행 Green은 아니다
18줄F02-L18 includeTestsMatching 'com.example.financialcore.account.AccountTest' 출고표 18번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-018가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다
19줄F02-L19 includeTestsMatching 'com.example.financialcore.account.ConcurrentWithdraw20IT' 출고표 19번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-019가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다
20줄F02-L20 includeTestsMatching 'com.example.financialcore.account.LostUpdateBaselineIT' 출고표 20번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-020가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML inventory 검증은 verifier 책임이다
21줄F02-L21 includeTestsMatching 'com.example.financialcore.account.LostUpdateBaselineIT.production_pessimistic_lock_path_commits_twice_and_preserves_both_updates' 출고표 21번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-021가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
selector가 보여도 실행 Green은 아니다
22줄F02-L22 includeTestsMatching 'com.example.financialcore.account.LostUpdateBaselineIT.test_only_versionless_unconditional_updates_commit_twice_and_lose_one_update' 출고표 22번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-022가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다
23줄F02-L23 includeTestsMatching 'com.example.financialcore.account.OpeningIntegrationTest' 출고표 23번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-023가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다
24줄F02-L24 includeTestsMatching 'com.example.financialcore.account.OptimisticAccountIT' 출고표 24번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-024가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML inventory 검증은 verifier 책임이다
25줄F02-L25 includeTestsMatching 'com.example.financialcore.account.api.AccountControllerHappyPathTest' 출고표 25번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-025가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
selector가 보여도 실행 Green은 아니다
26줄F02-L26 includeTestsMatching 'com.example.financialcore.account.api.AccountControllerPersistenceIT' 출고표 26번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-026가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다
27줄F02-L27 includeTestsMatching 'com.example.financialcore.account.api.AccountControllerTest' 출고표 27번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-027가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다
28줄F02-L28 includeTestsMatching 'com.example.financialcore.account.api.CreateAccountRequestValidationTest' 출고표 28번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-028가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML inventory 검증은 verifier 책임이다
29줄F02-L29 includeTestsMatching 'com.example.financialcore.api.ApiExceptionHandlerTest' 출고표 29번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-029가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
selector가 보여도 실행 Green은 아니다
30줄F02-L30 includeTestsMatching 'com.example.financialcore.api.RequestIdFilterTest' 출고표 30번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-030가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다
31줄F02-L31 includeTestsMatching 'com.example.financialcore.audit.AuditPropagationIT' 출고표 31번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-031가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다
32줄F02-L32 includeTestsMatching 'com.example.financialcore.idempotency.AtomicClaim50IT' 출고표 32번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-032가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML inventory 검증은 verifier 책임이다
33줄F02-L33 includeTestsMatching 'com.example.financialcore.idempotency.IdempotencySchemaIT' 출고표 33번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-033가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
selector가 보여도 실행 Green은 아니다
34줄F02-L34 includeTestsMatching 'com.example.financialcore.idempotency.RequestHasherTest' 출고표 34번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-034가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다
35줄F02-L35 includeTestsMatching 'com.example.financialcore.ledger.LedgerQueryIT' 출고표 35번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-035가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다
36줄F02-L36 includeTestsMatching 'com.example.financialcore.ledger.LedgerQueryIT.keysetPagesAreStableAndDoNotRepeatTheCursorRow' 출고표 36번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-036가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML inventory 검증은 verifier 책임이다
37줄F02-L37 includeTestsMatching 'com.example.financialcore.ledger.LedgerQueryIT.reconciliationReturnsZeroThenDetectsOneInjectedMismatch' 출고표 37번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-037가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
selector가 보여도 실행 Green은 아니다
38줄F02-L38 includeTestsMatching 'com.example.financialcore.ledger.LedgerQueryLimitTest' 출고표 38번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-038가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다
39줄F02-L39 includeTestsMatching 'com.example.financialcore.security.CloudFailClosedSecurityIT' 출고표 39번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-039가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다
40줄F02-L40 includeTestsMatching 'com.example.financialcore.security.MaskingTest' 출고표 40번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-040가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML inventory 검증은 verifier 책임이다
41줄F02-L41 includeTestsMatching 'com.example.financialcore.security.ObjectAuthorizationIT' 출고표 41번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-041가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
selector가 보여도 실행 Green은 아니다
42줄F02-L42 includeTestsMatching 'com.example.financialcore.security.SecurityStatusContractTest' 출고표 42번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-042가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다
43줄F02-L43 includeTestsMatching 'com.example.financialcore.transfer.SortedLockTransferIT' 출고표 43번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-043가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다
44줄F02-L44 includeTestsMatching 'com.example.financialcore.transfer.TransactionPropagationIT' 출고표 44번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-044가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML inventory 검증은 verifier 책임이다
45줄F02-L45 includeTestsMatching 'com.example.financialcore.transfer.TransactionProxyIT' 출고표 45번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-045가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
selector가 보여도 실행 Green은 아니다
46줄F02-L46 includeTestsMatching 'com.example.financialcore.transfer.TransferBalanceIT' 출고표 46번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-046가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다
47줄F02-L47 includeTestsMatching 'com.example.financialcore.transfer.TransferFailurePointIT' 출고표 47번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-047가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다
48줄F02-L48 includeTestsMatching 'com.example.financialcore.transfer.TransferIdempotencyIT' 출고표 48번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-048가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML inventory 검증은 verifier 책임이다
49줄F02-L49 includeTestsMatching 'com.example.financialcore.transfer.TransferIntegrationTest' 출고표 49번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-049가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
selector가 보여도 실행 Green은 아니다
50줄F02-L50 includeTestsMatching 'com.example.financialcore.transfer.api.TransferControllerHappyPathTest' 출고표 50번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-050가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다
51줄F02-L51 includeTestsMatching 'com.example.financialcore.transfer.api.TransferControllerReplayTest' 출고표 51번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-051가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다
52줄F02-L52 includeTestsMatching 'com.example.financialcore.transfer.api.TransferControllerTest' 출고표 52번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-052가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML inventory 검증은 verifier 책임이다
53줄F02-L53 includeTestsMatching 'com.example.financialcore.transfer.api.TransferRequestValidationTest' 출고표 53번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-053가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
selector가 보여도 실행 Green은 아니다
54줄F02-L54 } 출고표 54번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-054가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다
55줄F02-L55 } 출고표 55번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 failOnNoMatchingTests=true
결과·효과
관찰 상태 F02-055가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다
05

STEP 05 / 13

원본 코드 조각

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

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

F02-C01 · 원문 1–12줄1–12줄
1–12줄 원본
// W13_W24_LEARNER_CORE_V1_GATE
// Exact union of every W5-W12 staged selector plus six production W19/W20 contracts.
tasks.register('coreV1Gate', Test) {
    group = 'verification'
    description = 'Exact progressive core V1 release gate; no final-reference-only tests.'
    testClassesDirs = sourceSets.test.output.classesDirs
    classpath = sourceSets.test.runtimeClasspath
    useJUnitPlatform()
    filter {
        failOnNoMatchingTests = true
        includeTestsMatching 'com.example.financialcore.ApplicationContextTest'
        includeTestsMatching 'com.example.financialcore.ConcurrencyHarnessTest'
F02-C02 · 원문 13–24줄13–24줄
13–24줄 원본
        includeTestsMatching 'com.example.financialcore.ConcurrencyHarnessTest.fixed_pool_bounds_observed_activity_and_accounts_for_all_tasks'
        includeTestsMatching 'com.example.financialcore.ConcurrencyHarnessTest.ready_timeout_is_a_failure_and_never_a_green_run'
        includeTestsMatching 'com.example.financialcore.CoreSchemaIT'
        includeTestsMatching 'com.example.financialcore.account.AccountJpaMappingTest'
        includeTestsMatching 'com.example.financialcore.account.AccountServiceTest'
        includeTestsMatching 'com.example.financialcore.account.AccountTest'
        includeTestsMatching 'com.example.financialcore.account.ConcurrentWithdraw20IT'
        includeTestsMatching 'com.example.financialcore.account.LostUpdateBaselineIT'
        includeTestsMatching 'com.example.financialcore.account.LostUpdateBaselineIT.production_pessimistic_lock_path_commits_twice_and_preserves_both_updates'
        includeTestsMatching 'com.example.financialcore.account.LostUpdateBaselineIT.test_only_versionless_unconditional_updates_commit_twice_and_lose_one_update'
        includeTestsMatching 'com.example.financialcore.account.OpeningIntegrationTest'
        includeTestsMatching 'com.example.financialcore.account.OptimisticAccountIT'
F02-C03 · 원문 25–36줄25–36줄
25–36줄 원본
        includeTestsMatching 'com.example.financialcore.account.api.AccountControllerHappyPathTest'
        includeTestsMatching 'com.example.financialcore.account.api.AccountControllerPersistenceIT'
        includeTestsMatching 'com.example.financialcore.account.api.AccountControllerTest'
        includeTestsMatching 'com.example.financialcore.account.api.CreateAccountRequestValidationTest'
        includeTestsMatching 'com.example.financialcore.api.ApiExceptionHandlerTest'
        includeTestsMatching 'com.example.financialcore.api.RequestIdFilterTest'
        includeTestsMatching 'com.example.financialcore.audit.AuditPropagationIT'
        includeTestsMatching 'com.example.financialcore.idempotency.AtomicClaim50IT'
        includeTestsMatching 'com.example.financialcore.idempotency.IdempotencySchemaIT'
        includeTestsMatching 'com.example.financialcore.idempotency.RequestHasherTest'
        includeTestsMatching 'com.example.financialcore.ledger.LedgerQueryIT'
        includeTestsMatching 'com.example.financialcore.ledger.LedgerQueryIT.keysetPagesAreStableAndDoNotRepeatTheCursorRow'
F02-C04 · 원문 37–48줄37–48줄
37–48줄 원본
        includeTestsMatching 'com.example.financialcore.ledger.LedgerQueryIT.reconciliationReturnsZeroThenDetectsOneInjectedMismatch'
        includeTestsMatching 'com.example.financialcore.ledger.LedgerQueryLimitTest'
        includeTestsMatching 'com.example.financialcore.security.CloudFailClosedSecurityIT'
        includeTestsMatching 'com.example.financialcore.security.MaskingTest'
        includeTestsMatching 'com.example.financialcore.security.ObjectAuthorizationIT'
        includeTestsMatching 'com.example.financialcore.security.SecurityStatusContractTest'
        includeTestsMatching 'com.example.financialcore.transfer.SortedLockTransferIT'
        includeTestsMatching 'com.example.financialcore.transfer.TransactionPropagationIT'
        includeTestsMatching 'com.example.financialcore.transfer.TransactionProxyIT'
        includeTestsMatching 'com.example.financialcore.transfer.TransferBalanceIT'
        includeTestsMatching 'com.example.financialcore.transfer.TransferFailurePointIT'
        includeTestsMatching 'com.example.financialcore.transfer.TransferIdempotencyIT'
F02-C05 · 원문 49–55줄49–55줄
49–55줄 원본
        includeTestsMatching 'com.example.financialcore.transfer.TransferIntegrationTest'
        includeTestsMatching 'com.example.financialcore.transfer.api.TransferControllerHappyPathTest'
        includeTestsMatching 'com.example.financialcore.transfer.api.TransferControllerReplayTest'
        includeTestsMatching 'com.example.financialcore.transfer.api.TransferControllerTest'
        includeTestsMatching 'com.example.financialcore.transfer.api.TransferRequestValidationTest'
    }
}
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

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

전체 번역 55 / 55

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

원본한국어 번역
1// W13_W24_LEARNER_CORE_V1_GATE실행 의미: core-v1-gate.gradle의 다음 검증 또는 설명 단계를 구성한다.
2// Exact union of every W5-W12 staged selector plus six production W19/W20 contracts.실행 의미: core-v1-gate.gradle의 다음 검증 또는 설명 단계를 구성한다.
3tasks.register('coreV1Gate', Test) {실행 의미: Gradle에 coreV1Gate Test task를 등록한다.
4 group = 'verification'실행 의미: core-v1-gate.gradle의 다음 검증 또는 설명 단계를 구성한다.
5 description = 'Exact progressive core V1 release gate; no final-reference-only tests.'실행 의미: core-v1-gate.gradle의 다음 검증 또는 설명 단계를 구성한다.
6 testClassesDirs = sourceSets.test.output.classesDirs실행 의미: class 이름과 기대 test 수를 exact inventory로 고정한다.
7 classpath = sourceSets.test.runtimeClasspath실행 의미: core-v1-gate.gradle의 다음 검증 또는 설명 단계를 구성한다.
8 useJUnitPlatform()실행 의미: core-v1-gate.gradle의 다음 검증 또는 설명 단계를 구성한다.
9 filter {실행 의미: 조건·반복·함수의 실행 block을 연다.
10 failOnNoMatchingTests = true실행 의미: selector가 0개 test를 찾으면 성공 대신 실패하게 한다.
11 includeTestsMatching 'com.example.financialcore.ApplicationContextTest'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
12 includeTestsMatching 'com.example.financialcore.ConcurrencyHarnessTest'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
13 includeTestsMatching 'com.example.financialcore.ConcurrencyHarnessTest.fixed_pool_bounds_observed_activity_and_accounts_for_all_tasks'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
14 includeTestsMatching 'com.example.financialcore.ConcurrencyHarnessTest.ready_timeout_is_a_failure_and_never_a_green_run'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
15 includeTestsMatching 'com.example.financialcore.CoreSchemaIT'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
16 includeTestsMatching 'com.example.financialcore.account.AccountJpaMappingTest'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
17 includeTestsMatching 'com.example.financialcore.account.AccountServiceTest'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
18 includeTestsMatching 'com.example.financialcore.account.AccountTest'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
19 includeTestsMatching 'com.example.financialcore.account.ConcurrentWithdraw20IT'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
20 includeTestsMatching 'com.example.financialcore.account.LostUpdateBaselineIT'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
21 includeTestsMatching 'com.example.financialcore.account.LostUpdateBaselineIT.production_pessimistic_lock_path_commits_twice_and_preserves_both_updates'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
22 includeTestsMatching 'com.example.financialcore.account.LostUpdateBaselineIT.test_only_versionless_unconditional_updates_commit_twice_and_lose_one_update'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
23 includeTestsMatching 'com.example.financialcore.account.OpeningIntegrationTest'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
24 includeTestsMatching 'com.example.financialcore.account.OptimisticAccountIT'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
25 includeTestsMatching 'com.example.financialcore.account.api.AccountControllerHappyPathTest'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
26 includeTestsMatching 'com.example.financialcore.account.api.AccountControllerPersistenceIT'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
27 includeTestsMatching 'com.example.financialcore.account.api.AccountControllerTest'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
28 includeTestsMatching 'com.example.financialcore.account.api.CreateAccountRequestValidationTest'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
29 includeTestsMatching 'com.example.financialcore.api.ApiExceptionHandlerTest'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
30 includeTestsMatching 'com.example.financialcore.api.RequestIdFilterTest'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
31 includeTestsMatching 'com.example.financialcore.audit.AuditPropagationIT'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
32 includeTestsMatching 'com.example.financialcore.idempotency.AtomicClaim50IT'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
33 includeTestsMatching 'com.example.financialcore.idempotency.IdempotencySchemaIT'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
34 includeTestsMatching 'com.example.financialcore.idempotency.RequestHasherTest'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
35 includeTestsMatching 'com.example.financialcore.ledger.LedgerQueryIT'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
36 includeTestsMatching 'com.example.financialcore.ledger.LedgerQueryIT.keysetPagesAreStableAndDoNotRepeatTheCursorRow'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
37 includeTestsMatching 'com.example.financialcore.ledger.LedgerQueryIT.reconciliationReturnsZeroThenDetectsOneInjectedMismatch'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
38 includeTestsMatching 'com.example.financialcore.ledger.LedgerQueryLimitTest'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
39 includeTestsMatching 'com.example.financialcore.security.CloudFailClosedSecurityIT'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
40 includeTestsMatching 'com.example.financialcore.security.MaskingTest'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
41 includeTestsMatching 'com.example.financialcore.security.ObjectAuthorizationIT'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
42 includeTestsMatching 'com.example.financialcore.security.SecurityStatusContractTest'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
43 includeTestsMatching 'com.example.financialcore.transfer.SortedLockTransferIT'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
44 includeTestsMatching 'com.example.financialcore.transfer.TransactionPropagationIT'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
45 includeTestsMatching 'com.example.financialcore.transfer.TransactionProxyIT'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
46 includeTestsMatching 'com.example.financialcore.transfer.TransferBalanceIT'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
47 includeTestsMatching 'com.example.financialcore.transfer.TransferFailurePointIT'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
48 includeTestsMatching 'com.example.financialcore.transfer.TransferIdempotencyIT'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
49 includeTestsMatching 'com.example.financialcore.transfer.TransferIntegrationTest'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
50 includeTestsMatching 'com.example.financialcore.transfer.api.TransferControllerHappyPathTest'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
51 includeTestsMatching 'com.example.financialcore.transfer.api.TransferControllerReplayTest'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
52 includeTestsMatching 'com.example.financialcore.transfer.api.TransferControllerTest'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
53 includeTestsMatching 'com.example.financialcore.transfer.api.TransferRequestValidationTest'실행 의미: 정확한 JUnit class 또는 method selector 하나를 Gate에 추가한다.
54 }실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
55}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
07

STEP 07 / 13

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

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

한 줄로 읽기

core-v1-gate.gradle — wildcard 없는 exact Gradle selector는 W5–W12 누적 selector와 W19/W20 production contract를 exact includeTestsMatching 목록으로 coreV1Gate에 연결한다.

문법 해부

  • .gradle 문법에서 선언·조건·pipeline·block 경계를 먼저 나눈다.
  • expected 값과 actual 결과를 같은 이름처럼 보여도 서로 다른 source로 읽는다.
  • native exit·row count·hash·사람 판정을 서로 대체하지 않는다.

실행 순서

  1. 입력 경로·fixture·환경변수·expected 계약을 고정한다.
  2. source가 실행하는 native process·HTTP·SQL 또는 형식 검사를 따라간다.
  3. actual 값과 exact marker를 대조하고 실패면 성공 발행 전에 중단한다.
  4. finally cleanup과 비범위를 evidence에 남긴다.

W24 조각별 정밀 해설

F02-C01 · 원문 1–12줄
문법 해부
.gradle 문법으로 1–12줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
failOnNoMatchingTests=true, 43 selectors, JUnit Platform를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
selector가 보여도 실행 Green은 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
selector가 보여도 실행 Green은 아니다; reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다; GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다; XML inventory 검증은 verifier 책임이다
다음 연결
다음 조각 또는 F02 evidence 판정으로 상태를 넘긴다.
F02-C02 · 원문 13–24줄
문법 해부
.gradle 문법으로 13–24줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
failOnNoMatchingTests=true, 43 selectors, JUnit Platform를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
selector가 보여도 실행 Green은 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
selector가 보여도 실행 Green은 아니다; reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다; GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다; XML inventory 검증은 verifier 책임이다
다음 연결
다음 조각 또는 F02 evidence 판정으로 상태를 넘긴다.
F02-C03 · 원문 25–36줄
문법 해부
.gradle 문법으로 25–36줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
failOnNoMatchingTests=true, 43 selectors, JUnit Platform를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
selector가 보여도 실행 Green은 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
selector가 보여도 실행 Green은 아니다; reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다; GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다; XML inventory 검증은 verifier 책임이다
다음 연결
다음 조각 또는 F02 evidence 판정으로 상태를 넘긴다.
F02-C04 · 원문 37–48줄
문법 해부
.gradle 문법으로 37–48줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
failOnNoMatchingTests=true, 43 selectors, JUnit Platform를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
selector가 보여도 실행 Green은 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
selector가 보여도 실행 Green은 아니다; reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다; GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다; XML inventory 검증은 verifier 책임이다
다음 연결
다음 조각 또는 F02 evidence 판정으로 상태를 넘긴다.
F02-C05 · 원문 49–55줄
문법 해부
.gradle 문법으로 49–55줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
failOnNoMatchingTests=true, 43 selectors, JUnit Platform를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
selector가 보여도 실행 Green은 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
selector가 보여도 실행 Green은 아니다; reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다; GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다; XML inventory 검증은 verifier 책임이다
다음 연결
다음 조각 또는 F02 evidence 판정으로 상태를 넘긴다.
실행 순서 — core-v1-gate.gradle — wildcard 없는 exact Gradle selector히토리 → 니지카 → 료 → 키타
  1. 히토리

    43 selectors가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 W5–W12 누적 selector와 W19/W20 production contract를 exact includeTestsMatching 목록으로 coreV1Gate에 연결한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 43 selectors와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

08

STEP 08 / 13

실제 값 따라가기

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

순서들어온 값코드가 하는 일나온 값·상태경계
입력failOnNoMatchingTests=truesource 계약에 대입F02 실행/설명 시작 상태selector가 보여도 실행 Green은 아니다
검증43 selectorsexpected와 actual 또는 형식 대조통과 또는 첫 mismatchreference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다
증거no wildcardmarker·hash·row를 같은 run에 연결범위가 적힌 evidence 후보XML inventory 검증은 verifier 책임이다
실제 값 — core-v1-gate.gradle — wildcard 없는 exact Gradle selector히토리 → 니지카 → 료 → 키타
  1. 히토리

    JUnit Platform가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 W5–W12 누적 selector와 W19/W20 production contract를 exact includeTestsMatching 목록으로 coreV1Gate에 연결한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 JUnit Platform와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

09

STEP 09 / 13

Gradle·PowerShell·HTTP·PostgreSQL 내부에서 벌어지는 일

Gradle·JUnit XML·PowerShell·HTTP·PostgreSQL·Docker에서 실제로 일어나는 일과 증명 범위를 구분합니다.

source/contract

core-v1-gate.gradle bytes와 expected 값을 읽는다.

파일 존재만으로 runtime 성공은 아니다.
execution/evidence

native exit·HTTP status·JUnit XML·DB row·hash 중 이 파일이 소유한 값을 만든다.

selector가 보여도 실행 Green은 아니다
release/human

관련 evidence와 사람 의미 검토를 release 후보에 연결한다.

XML inventory 검증은 verifier 책임이다
첫 실패 경계 — core-v1-gate.gradle — wildcard 없는 exact Gradle selector히토리 → 니지카 → 료 → 키타
  1. 히토리

    no wildcard가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 W5–W12 누적 selector와 W19/W20 production contract를 exact includeTestsMatching 목록으로 coreV1Gate에 연결한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘XML inventory 검증은 verifier 책임이다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 no wildcard와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

10

STEP 10 / 13

흔한 착각과 틀린 예

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

❌ failOnNoMatchingTests=true 문자열이 source에 있으니 실제 실행도 Green이다.

왜 틀리나 source literal과 runtime 관찰값은 다른 증거다.

바르게 읽기 native exit·actual XML/HTTP/DB evidence를 별도로 확인한다.

반례 script가 실행 전 경로 오류로 멈춰도 literal은 그대로 남는다.

❌ 파일 SHA-256이 있으면 내용의 의미와 사실성도 검증됐다.

왜 틀리나 hash는 동일 bytes만 말한다.

바르게 읽기 schema·수치·질문·근거는 별도 자동 또는 사람 판정을 거친다.

반례 빈 review 질문을 가진 CSV도 안정된 hash를 가진다.

❌ LOCAL_ARTIFACT_VALIDATED는 release Green과 같다.

왜 틀리나 generic validator는 파일 shape만 확인한다.

바르게 읽기 HUMAN_SEMANTIC_REVIEW_REQUIRED를 유지한다.

반례 잘못된 track 점수표도 byte 수 조건은 통과할 수 있다.

❌ 이 파일이 W24 전체 lifecycle을 모두 소유한다.

왜 틀리나 각 source는 Gate·demo·cleanup·사람 review 중 일부만 담당한다.

바르게 읽기 owner와 non-responsibility를 release manifest에서 분리한다.

반례 D4 source audit에는 runtime_claim=false가 명시된다.

❌ 이전 주 Green이나 오래된 log를 현재 commit 결과로 재사용한다.

왜 틀리나 source·commit·actual result가 같은 실행에 묶이지 않는다.

바르게 읽기 release 후보에서 새 evidence와 hash를 만든다.

반례 expected JSON이 바뀌면 예전 XML은 exact inventory를 증명하지 못한다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

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

증명 범위

selector가 보여도 실행 Green은 아니다

이 책임을 맡는 곳: runtime Gate
증명 범위

reference build.gradle의 23-selector coreV1Gate와 learner overlay의 43-selector/37-suite/66-test 계약은 서로 다르다

이 책임을 맡는 곳: external/human review
증명 범위

GateOverlay 뒤 서로 다른 LearnerRoot를 검증해야 하며 reference root와 learner root를 같게 두면 안 된다

이 책임을 맡는 곳: release manifest
증명 범위

XML inventory 검증은 verifier 책임이다

이 책임을 맡는 곳: 운영 환경
증명하지 않는 범위 — core-v1-gate.gradle — wildcard 없는 exact Gradle selector히토리 → 니지카 → 료 → 키타
  1. 히토리

    failOnNoMatchingTests=true가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 W5–W12 누적 selector와 W19/W20 production contract를 exact includeTestsMatching 목록으로 coreV1Gate에 연결한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘selector가 보여도 실행 Green은 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 failOnNoMatchingTests=true와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

12

STEP 12 / 13

직접 다시 써보기

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

1단계 · 뜻부터 복원

  • W5–W12 누적 selector와 W19/W20 production contract를 exact includeTestsMatching 목록으로 coreV1Gate에 연결한다.
  • 핵심 값은 failOnNoMatchingTests=true, 43 selectors, JUnit Platform, no wildcard다.

2단계 · 코드 조각 재조립

  1. 1. core-v1-gate.gradle의 다음 검증 또는 설명 단계를 구성한다
  2. 2. core-v1-gate.gradle의 다음 검증 또는 설명 단계를 구성한다
  3. 3. Gradle에 coreV1Gate Test task를 등록한다
  4. 4. core-v1-gate.gradle의 다음 검증 또는 설명 단계를 구성한다
  5. 5. core-v1-gate.gradle의 다음 검증 또는 설명 단계를 구성한다
  6. 6. class 이름과 기대 test 수를 exact inventory로 고정한다
  7. 7. core-v1-gate.gradle의 다음 검증 또는 설명 단계를 구성한다
  8. 8. core-v1-gate.gradle의 다음 검증 또는 설명 단계를 구성한다

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

learning_stages/w24/overlay/core-v1-gate.gradle을 새 파일에 다시 쓰고 expected·actual·실패·cleanup·비범위를 주석으로 표시한다.

자가 점검
  • 비어 있지 않은 모든 source 줄을 한 번씩 읽었나?
  • source shape와 runtime Green을 분리했나?
  • 사람 검토·외부 상태를 자동 성공으로 꾸미지 않았나?
  • 첫 실패와 cleanup 책임을 설명할 수 있나?
13

STEP 13 / 13

전체 원본 source

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

원문 정본 전체 source 확인하기
패키지 정본 보조 계약 · exact Gradle gate byteslearning_stages/w24/overlay/core-v1-gate.gradleSHA-256 1417dc814fd3b92e221302c17a6383d8b339579616bf9f4172ae1f189a4806e0
core-v1-gate.gradle — wildcard 없는 exact Gradle selector 전체
// W13_W24_LEARNER_CORE_V1_GATE
// Exact union of every W5-W12 staged selector plus six production W19/W20 contracts.
tasks.register('coreV1Gate', Test) {
    group = 'verification'
    description = 'Exact progressive core V1 release gate; no final-reference-only tests.'
    testClassesDirs = sourceSets.test.output.classesDirs
    classpath = sourceSets.test.runtimeClasspath
    useJUnitPlatform()
    filter {
        failOnNoMatchingTests = true
        includeTestsMatching 'com.example.financialcore.ApplicationContextTest'
        includeTestsMatching 'com.example.financialcore.ConcurrencyHarnessTest'
        includeTestsMatching 'com.example.financialcore.ConcurrencyHarnessTest.fixed_pool_bounds_observed_activity_and_accounts_for_all_tasks'
        includeTestsMatching 'com.example.financialcore.ConcurrencyHarnessTest.ready_timeout_is_a_failure_and_never_a_green_run'
        includeTestsMatching 'com.example.financialcore.CoreSchemaIT'
        includeTestsMatching 'com.example.financialcore.account.AccountJpaMappingTest'
        includeTestsMatching 'com.example.financialcore.account.AccountServiceTest'
        includeTestsMatching 'com.example.financialcore.account.AccountTest'
        includeTestsMatching 'com.example.financialcore.account.ConcurrentWithdraw20IT'
        includeTestsMatching 'com.example.financialcore.account.LostUpdateBaselineIT'
        includeTestsMatching 'com.example.financialcore.account.LostUpdateBaselineIT.production_pessimistic_lock_path_commits_twice_and_preserves_both_updates'
        includeTestsMatching 'com.example.financialcore.account.LostUpdateBaselineIT.test_only_versionless_unconditional_updates_commit_twice_and_lose_one_update'
        includeTestsMatching 'com.example.financialcore.account.OpeningIntegrationTest'
        includeTestsMatching 'com.example.financialcore.account.OptimisticAccountIT'
        includeTestsMatching 'com.example.financialcore.account.api.AccountControllerHappyPathTest'
        includeTestsMatching 'com.example.financialcore.account.api.AccountControllerPersistenceIT'
        includeTestsMatching 'com.example.financialcore.account.api.AccountControllerTest'
        includeTestsMatching 'com.example.financialcore.account.api.CreateAccountRequestValidationTest'
        includeTestsMatching 'com.example.financialcore.api.ApiExceptionHandlerTest'
        includeTestsMatching 'com.example.financialcore.api.RequestIdFilterTest'
        includeTestsMatching 'com.example.financialcore.audit.AuditPropagationIT'
        includeTestsMatching 'com.example.financialcore.idempotency.AtomicClaim50IT'
        includeTestsMatching 'com.example.financialcore.idempotency.IdempotencySchemaIT'
        includeTestsMatching 'com.example.financialcore.idempotency.RequestHasherTest'
        includeTestsMatching 'com.example.financialcore.ledger.LedgerQueryIT'
        includeTestsMatching 'com.example.financialcore.ledger.LedgerQueryIT.keysetPagesAreStableAndDoNotRepeatTheCursorRow'
        includeTestsMatching 'com.example.financialcore.ledger.LedgerQueryIT.reconciliationReturnsZeroThenDetectsOneInjectedMismatch'
        includeTestsMatching 'com.example.financialcore.ledger.LedgerQueryLimitTest'
        includeTestsMatching 'com.example.financialcore.security.CloudFailClosedSecurityIT'
        includeTestsMatching 'com.example.financialcore.security.MaskingTest'
        includeTestsMatching 'com.example.financialcore.security.ObjectAuthorizationIT'
        includeTestsMatching 'com.example.financialcore.security.SecurityStatusContractTest'
        includeTestsMatching 'com.example.financialcore.transfer.SortedLockTransferIT'
        includeTestsMatching 'com.example.financialcore.transfer.TransactionPropagationIT'
        includeTestsMatching 'com.example.financialcore.transfer.TransactionProxyIT'
        includeTestsMatching 'com.example.financialcore.transfer.TransferBalanceIT'
        includeTestsMatching 'com.example.financialcore.transfer.TransferFailurePointIT'
        includeTestsMatching 'com.example.financialcore.transfer.TransferIdempotencyIT'
        includeTestsMatching 'com.example.financialcore.transfer.TransferIntegrationTest'
        includeTestsMatching 'com.example.financialcore.transfer.api.TransferControllerHappyPathTest'
        includeTestsMatching 'com.example.financialcore.transfer.api.TransferControllerReplayTest'
        includeTestsMatching 'com.example.financialcore.transfer.api.TransferControllerTest'
        includeTestsMatching 'com.example.financialcore.transfer.api.TransferRequestValidationTest'
    }
}
03

verify-core-v1-gate.ps1 — actual XML 37/66을 fail-closed 검증

scripts/verify-core-v1-gate.ps1

PDF 전문 정본 · packaged PowerShell source · 정본 · W24-F03
61줄 연결61줄 번역6 chunks
01

STEP 01 / 13

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

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

오늘의 한 문장

native Gradle exit, JUnit XML 존재, exact class set, class별 test 수와 failure/error/skip 0을 함께 확인한다.

  1. CORE_V1_GATE_GREEN은 어느 source와 실제 결과에서 확인해야 할까?
  2. 첫 실패를 만드는 조건과 fail-closed 지점은 어디일까?
  3. 왜 ‘XML이 없으면 즉시 실패한다’를 별도 경계로 남겨야 할까?
이 파일에서 끝까지 다시 쓰는 값CORE_V1_GATE_GREENclasses=37tests=66failures/errors/skipped=0
왜 필요한가 — 66을 fail-closed 검증히토리 → 니지카 → 료 → 키타
  1. 히토리

    CORE_V1_GATE_GREEN가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 native Gradle exit, JUnit XML 존재, exact class set, class별 test 수와 failure/error/skip 0을 함께 확인한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘XML이 없으면 즉시 실패한다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 CORE_V1_GATE_GREEN와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

02

STEP 02 / 13

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

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

새 기능을 멈춘 팀이 코드·test·문서·demo를 같은 release 후보에 묶어 하나씩 검수한다.

검수 도장이 붙은 공통 거래 코어 출고 상자

이 파일은 native Gradle exit, JUnit XML 존재, exact class set, class별 test 수와 failure/error/skip 0을 함께 확인한다. 눈으로 읽을 때는 각 줄을 검수표 한 칸처럼 보고, 입력과 다음 상태를 놓치지 않는다.

마지막 도장은 source shape와 실제 runtime·사람 검토를 구분한 뒤에만 찍는다. 특히 XML이 없으면 즉시 실패한다

딱 여기까지만 비유는 실행 순서를 돕지만 실제 Gradle·Docker·DB·사람 review를 대신하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

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

값 1: CORE_V1_GATE_GREEN

이 파일에서 계속 확인할 고정 단서가 CORE_V1_GATE_GREEN다.

코드 연결
F03 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
XML이 없으면 즉시 실패한다

값 2: classes=37

이 파일에서 계속 확인할 고정 단서가 classes=37다.

코드 연결
F03 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
wildcard·0 tests 성공을 허용하지 않는다

값 3: tests=66

이 파일에서 계속 확인할 고정 단서가 tests=66다.

코드 연결
F03 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
이 HTML은 runner를 실행하지 않았다

값 4: failures/errors/skipped=0

이 파일에서 계속 확인할 고정 단서가 failures/errors/skipped=0다.

코드 연결
F03 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
XML이 없으면 즉시 실패한다
04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

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

단어 몇 개만 뽑은 표가 아닙니다.PDF 전문 정본 · packaged PowerShell source에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.61 / 61 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F03-L01 param( 출고표 1번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 PowerShell script가 받을 입력 계약을 연다.
입력
이전 줄의 상태와 CORE_V1_GATE_GREEN
결과·효과
관찰 상태 F03-001가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
2줄F03-L02 [Parameter(Mandatory=$true)][string]$ProjectRoot, 출고표 2번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 인자가 빠지면 실행 시작 전에 binding을 거절한다.
입력
$true, $ProjectRoot
결과·효과
관찰 상태 F03-002가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
3줄F03-L03 [Parameter(Mandatory=$true)][string]$EvidencePath, 출고표 3번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 인자가 빠지면 실행 시작 전에 binding을 거절한다.
입력
$true, $EvidencePath
결과·효과
관찰 상태 F03-003가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
이 HTML은 runner를 실행하지 않았다
4줄F03-L04 [string]$ExpectedPath = '' 출고표 4번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 verify-core-v1-gate.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$ExpectedPath
결과·효과
관찰 상태 F03-004가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
5줄F03-L05 ) 출고표 5번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 CORE_V1_GATE_GREEN
결과·효과
관찰 상태 F03-005가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
7줄F03-L07 $ErrorActionPreference = 'Stop' 출고표 7번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다.
입력
$ErrorActionPreference, 'Stop'
결과·효과
관찰 상태 F03-007가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
8줄F03-L08 $reference = Split-Path -Parent $PSScriptRoot 출고표 8번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$reference, $PSScriptRoot
결과·효과
관찰 상태 F03-008가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
9줄F03-L09 $project = (Resolve-Path -LiteralPath $ProjectRoot).Path 출고표 9번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 입력 경로를 실제 절대 경로로 확인한다.
입력
$project, $ProjectRoot
결과·효과
관찰 상태 F03-009가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
이 HTML은 runner를 실행하지 않았다
10줄F03-L10 if ([string]::IsNullOrWhiteSpace($ExpectedPath)) { 출고표 10번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$ExpectedPath
결과·효과
관찰 상태 F03-010가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
11줄F03-L11 $ExpectedPath = Join-Path $reference 'learning_stages\w24\overlay\core-v1-expected.json' 출고표 11번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$ExpectedPath, $reference
결과·효과
관찰 상태 F03-011가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
12줄F03-L12 } 출고표 12번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 CORE_V1_GATE_GREEN
결과·효과
관찰 상태 F03-012가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
이 HTML은 runner를 실행하지 않았다
13줄F03-L13 $contract = Get-Content -LiteralPath $ExpectedPath -Raw | ConvertFrom-Json 출고표 13번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 JSON text를 필드로 접근 가능한 PowerShell object로 바꾼다.
입력
$contract, $ExpectedPath
결과·효과
관찰 상태 F03-013가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
14줄F03-L14 $expected = @($contract.classes.psobject.Properties.Name | Sort-Object) 출고표 14번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 class 이름과 기대 test 수를 exact inventory로 고정한다.
입력
$expected, $contract
결과·효과
관찰 상태 F03-014가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
15줄F03-L15 Push-Location $project 출고표 15번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 verify-core-v1-gate.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$project
결과·효과
관찰 상태 F03-015가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
이 HTML은 runner를 실행하지 않았다
16줄F03-L16 try { 출고표 16번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
이전 줄의 상태와 CORE_V1_GATE_GREEN
결과·효과
관찰 상태 F03-016가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
17줄F03-L17 & .\gradlew.bat clean coreV1Gate --no-daemon 출고표 17번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 learner project의 Gradle wrapper로 지정 task를 실행한다.
입력
이전 줄의 상태와 CORE_V1_GATE_GREEN
결과·효과
관찰 상태 F03-017가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
18줄F03-L18 if ($LASTEXITCODE -ne 0) { throw "coreV1Gate native exit=$LASTEXITCODE" } 출고표 18번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 native process 종료 코드를 검사해 실패를 놓치지 않는다.
입력
$LASTEXITCODE, 0, "coreV1Gate native exit=$LASTEXITCODE"
결과·효과
관찰 상태 F03-018가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
이 HTML은 runner를 실행하지 않았다
20줄F03-L20 $resultDirectory = Join-Path $project 'build\test-results\coreV1Gate' 출고표 20번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$resultDirectory, $project, 'build\test-results\coreV1Gate'
결과·효과
관찰 상태 F03-020가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
21줄F03-L21 $xmlFiles = @(Get-ChildItem -LiteralPath $resultDirectory -Filter 'TEST-*.xml' -File) 출고표 21번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 JUnit XML 결과 파일만 exact inventory 입력으로 모은다.
입력
$xmlFiles, $resultDirectory, 'TEST-*.xml'
결과·효과
관찰 상태 F03-021가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
이 HTML은 runner를 실행하지 않았다
22줄F03-L22 if ($xmlFiles.Count -eq 0) { throw 'coreV1Gate produced no XML test result' } 출고표 22번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
$xmlFiles, 0, 'coreV1Gate produced no XML test result'
결과·효과
관찰 상태 F03-022가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
24줄F03-L24 $rows = foreach ($file in $xmlFiles) { 출고표 24번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 고정 목록의 각 항목에 같은 검사를 반복 적용한다.
입력
$rows, $file, $xmlFiles
결과·효과
관찰 상태 F03-024가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
이 HTML은 runner를 실행하지 않았다
25줄F03-L25 [xml]$xml = Get-Content -LiteralPath $file.FullName -Raw 출고표 25번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 verify-core-v1-gate.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$xml, $file
결과·효과
관찰 상태 F03-025가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
26줄F03-L26 [pscustomobject]@{ 출고표 26번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
이전 줄의 상태와 CORE_V1_GATE_GREEN
결과·효과
관찰 상태 F03-026가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
27줄F03-L27 class = [string]$xml.testsuite.name 출고표 27번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 JUnit suite의 class 이름과 test/failure/error/skip 수를 읽는다.
입력
$xml
결과·효과
관찰 상태 F03-027가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
이 HTML은 runner를 실행하지 않았다
28줄F03-L28 tests = [int]$xml.testsuite.tests 출고표 28번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 JUnit suite의 class 이름과 test/failure/error/skip 수를 읽는다.
입력
$xml
결과·효과
관찰 상태 F03-028가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
29줄F03-L29 failures = [int]$xml.testsuite.failures 출고표 29번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 JUnit suite의 class 이름과 test/failure/error/skip 수를 읽는다.
입력
$xml
결과·효과
관찰 상태 F03-029가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
30줄F03-L30 errors = [int]$xml.testsuite.errors 출고표 30번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 JUnit suite의 class 이름과 test/failure/error/skip 수를 읽는다.
입력
$xml
결과·효과
관찰 상태 F03-030가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
이 HTML은 runner를 실행하지 않았다
31줄F03-L31 skipped = [int]$xml.testsuite.skipped 출고표 31번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 JUnit suite의 class 이름과 test/failure/error/skip 수를 읽는다.
입력
$xml
결과·효과
관찰 상태 F03-031가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
32줄F03-L32 } 출고표 32번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 CORE_V1_GATE_GREEN
결과·효과
관찰 상태 F03-032가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
33줄F03-L33 } 출고표 33번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 CORE_V1_GATE_GREEN
결과·효과
관찰 상태 F03-033가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
이 HTML은 runner를 실행하지 않았다
34줄F03-L34 $actual = @($rows.class | Sort-Object -Unique) 출고표 34번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
입력
$actual, $rows
결과·효과
관찰 상태 F03-034가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
35줄F03-L35 $missing = @($expected | Where-Object { $_ -notin $actual }) 출고표 35번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건을 만족하는 row만 필터링한다.
입력
$missing, $expected, $_
결과·효과
관찰 상태 F03-035가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
36줄F03-L36 $unexpected = @($actual | Where-Object { $_ -notin $expected }) 출고표 36번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건을 만족하는 row만 필터링한다.
입력
$unexpected, $actual, $_
결과·효과
관찰 상태 F03-036가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
이 HTML은 runner를 실행하지 않았다
37줄F03-L37 if ($missing.Count -gt 0 -or $unexpected.Count -gt 0) { 출고표 37번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$missing, 0, $unexpected
결과·효과
관찰 상태 F03-037가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
38줄F03-L38 throw "class inventory mismatch; missing=$($missing -join ','); unexpected=$($unexpected -join ',')" 출고표 38번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
$missing, ',', $unexpected
결과·효과
관찰 상태 F03-038가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
39줄F03-L39 } 출고표 39번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 CORE_V1_GATE_GREEN
결과·효과
관찰 상태 F03-039가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
이 HTML은 runner를 실행하지 않았다
40줄F03-L40 $tests = ($rows | Measure-Object tests -Sum).Sum 출고표 40번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 suite별 수치를 전체 합계로 계산한다.
입력
$tests, $rows
결과·효과
관찰 상태 F03-040가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
41줄F03-L41 $failures = ($rows | Measure-Object failures -Sum).Sum 출고표 41번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 suite별 수치를 전체 합계로 계산한다.
입력
$failures, $rows
결과·효과
관찰 상태 F03-041가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
42줄F03-L42 $errors = ($rows | Measure-Object errors -Sum).Sum 출고표 42번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 suite별 수치를 전체 합계로 계산한다.
입력
$errors, $rows
결과·효과
관찰 상태 F03-042가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
이 HTML은 runner를 실행하지 않았다
43줄F03-L43 $skipped = ($rows | Measure-Object skipped -Sum).Sum 출고표 43번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 suite별 수치를 전체 합계로 계산한다.
입력
$skipped, $rows
결과·효과
관찰 상태 F03-043가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
44줄F03-L44 $wrongCounts = @($rows | Where-Object { $_.tests -ne [int]$contract.classes.psobject.Properties[$_.class].Value }) 출고표 44번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 class 이름과 기대 test 수를 exact inventory로 고정한다.
입력
$wrongCounts, $rows, $_
결과·효과
관찰 상태 F03-044가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
45줄F03-L45 if ($actual.Count -ne 37 -or $tests -ne 66 -or $wrongCounts.Count -gt 0 -or $failures -ne 0 -or $errors -ne 0 -or $skipped -ne 0) { 출고표 45번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$actual, 37, $tests
결과·효과
관찰 상태 F03-045가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
이 HTML은 runner를 실행하지 않았다
46줄F03-L46 throw "test summary is not Green: tests=$tests failures=$failures errors=$errors skipped=$skipped" 출고표 46번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
$tests, $failures, $errors
결과·효과
관찰 상태 F03-046가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
47줄F03-L47 } 출고표 47번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 CORE_V1_GATE_GREEN
결과·효과
관찰 상태 F03-047가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
49줄F03-L49 $summary = @( 출고표 49번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$summary
결과·효과
관찰 상태 F03-049가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
50줄F03-L50 'CORE_V1_GATE_GREEN', 출고표 50번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 37 class·66 test·실패/오류/skip 0일 때만 exact local marker를 낸다.
입력
'CORE_V1_GATE_GREEN'
결과·효과
관찰 상태 F03-050가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
51줄F03-L51 "classes=$($actual.Count)", 출고표 51번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 class 이름과 기대 test 수를 exact inventory로 고정한다.
입력
"classes=$($actual.Count)"
결과·효과
관찰 상태 F03-051가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
이 HTML은 runner를 실행하지 않았다
52줄F03-L52 "tests=$tests", 출고표 52번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 verify-core-v1-gate.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
"tests=$tests"
결과·효과
관찰 상태 F03-052가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
53줄F03-L53 "failures=$failures", 출고표 53번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 verify-core-v1-gate.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
"failures=$failures"
결과·효과
관찰 상태 F03-053가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
54줄F03-L54 "errors=$errors", 출고표 54번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 verify-core-v1-gate.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
"errors=$errors"
결과·효과
관찰 상태 F03-054가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
이 HTML은 runner를 실행하지 않았다
55줄F03-L55 "skipped=$skipped" 출고표 55번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 verify-core-v1-gate.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
"skipped=$skipped"
결과·효과
관찰 상태 F03-055가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
56줄F03-L56 ) 출고표 56번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 CORE_V1_GATE_GREEN
결과·효과
관찰 상태 F03-056가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
57줄F03-L57 $summary 출고표 57번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 verify-core-v1-gate.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$summary
결과·효과
관찰 상태 F03-057가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
이 HTML은 runner를 실행하지 않았다
58줄F03-L58 $parent = Split-Path -Parent $EvidencePath 출고표 58번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$parent, $EvidencePath
결과·효과
관찰 상태 F03-058가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
59줄F03-L59 if (-not [string]::IsNullOrWhiteSpace($parent)) { 출고표 59번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$parent
결과·효과
관찰 상태 F03-059가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
60줄F03-L60 New-Item -ItemType Directory -Force -Path $parent | Out-Null 출고표 60번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
입력
$parent
결과·효과
관찰 상태 F03-060가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
이 HTML은 runner를 실행하지 않았다
61줄F03-L61 } 출고표 61번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 CORE_V1_GATE_GREEN
결과·효과
관찰 상태 F03-061가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
62줄F03-L62 $summary | Set-Content -LiteralPath $EvidencePath -Encoding utf8 출고표 62번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
입력
$summary, $EvidencePath
결과·효과
관찰 상태 F03-062가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
63줄F03-L63 } finally { 출고표 63번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 중간 실패가 있어도 반드시 실행할 cleanup 경계를 연다.
입력
이전 줄의 상태와 CORE_V1_GATE_GREEN
결과·효과
관찰 상태 F03-063가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
이 HTML은 runner를 실행하지 않았다
64줄F03-L64 Pop-Location 출고표 64번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 verify-core-v1-gate.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 CORE_V1_GATE_GREEN
결과·효과
관찰 상태 F03-064가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
XML이 없으면 즉시 실패한다
65줄F03-L65 } 출고표 65번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 CORE_V1_GATE_GREEN
결과·효과
관찰 상태 F03-065가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
wildcard·0 tests 성공을 허용하지 않는다
05

STEP 05 / 13

원본 코드 조각

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

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

F03-C01 · 원문 1–12줄1–12줄
1–12줄 원본
param(
  [Parameter(Mandatory=$true)][string]$ProjectRoot,
  [Parameter(Mandatory=$true)][string]$EvidencePath,
  [string]$ExpectedPath = ''
)

$ErrorActionPreference = 'Stop'
$reference = Split-Path -Parent $PSScriptRoot
$project = (Resolve-Path -LiteralPath $ProjectRoot).Path
if ([string]::IsNullOrWhiteSpace($ExpectedPath)) {
  $ExpectedPath = Join-Path $reference 'learning_stages\w24\overlay\core-v1-expected.json'
}
F03-C02 · 원문 13–24줄13–24줄
13–24줄 원본
$contract = Get-Content -LiteralPath $ExpectedPath -Raw | ConvertFrom-Json
$expected = @($contract.classes.psobject.Properties.Name | Sort-Object)
Push-Location $project
try {
  & .\gradlew.bat clean coreV1Gate --no-daemon
  if ($LASTEXITCODE -ne 0) { throw "coreV1Gate native exit=$LASTEXITCODE" }

  $resultDirectory = Join-Path $project 'build\test-results\coreV1Gate'
  $xmlFiles = @(Get-ChildItem -LiteralPath $resultDirectory -Filter 'TEST-*.xml' -File)
  if ($xmlFiles.Count -eq 0) { throw 'coreV1Gate produced no XML test result' }

  $rows = foreach ($file in $xmlFiles) {
F03-C03 · 원문 25–36줄25–36줄
25–36줄 원본
    [xml]$xml = Get-Content -LiteralPath $file.FullName -Raw
    [pscustomobject]@{
      class = [string]$xml.testsuite.name
      tests = [int]$xml.testsuite.tests
      failures = [int]$xml.testsuite.failures
      errors = [int]$xml.testsuite.errors
      skipped = [int]$xml.testsuite.skipped
    }
  }
  $actual = @($rows.class | Sort-Object -Unique)
  $missing = @($expected | Where-Object { $_ -notin $actual })
  $unexpected = @($actual | Where-Object { $_ -notin $expected })
F03-C04 · 원문 37–48줄37–48줄
37–48줄 원본
  if ($missing.Count -gt 0 -or $unexpected.Count -gt 0) {
    throw "class inventory mismatch; missing=$($missing -join ','); unexpected=$($unexpected -join ',')"
  }
  $tests = ($rows | Measure-Object tests -Sum).Sum
  $failures = ($rows | Measure-Object failures -Sum).Sum
  $errors = ($rows | Measure-Object errors -Sum).Sum
  $skipped = ($rows | Measure-Object skipped -Sum).Sum
  $wrongCounts = @($rows | Where-Object { $_.tests -ne [int]$contract.classes.psobject.Properties[$_.class].Value })
  if ($actual.Count -ne 37 -or $tests -ne 66 -or $wrongCounts.Count -gt 0 -or $failures -ne 0 -or $errors -ne 0 -or $skipped -ne 0) {
    throw "test summary is not Green: tests=$tests failures=$failures errors=$errors skipped=$skipped"
  }
F03-C05 · 원문 49–60줄49–60줄
49–60줄 원본
  $summary = @(
    'CORE_V1_GATE_GREEN',
    "classes=$($actual.Count)",
    "tests=$tests",
    "failures=$failures",
    "errors=$errors",
    "skipped=$skipped"
  )
  $summary
  $parent = Split-Path -Parent $EvidencePath
  if (-not [string]::IsNullOrWhiteSpace($parent)) {
    New-Item -ItemType Directory -Force -Path $parent | Out-Null
F03-C06 · 원문 61–65줄61–65줄
61–65줄 원본
  }
  $summary | Set-Content -LiteralPath $EvidencePath -Encoding utf8
} finally {
  Pop-Location
}
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

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

전체 번역 61 / 61

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

원본한국어 번역
1param(실행 의미: PowerShell script가 받을 입력 계약을 연다.
2 [Parameter(Mandatory=$true)][string]$ProjectRoot,실행 의미: 이 인자가 빠지면 실행 시작 전에 binding을 거절한다.
3 [Parameter(Mandatory=$true)][string]$EvidencePath,실행 의미: 이 인자가 빠지면 실행 시작 전에 binding을 거절한다.
4 [string]$ExpectedPath = ''실행 의미: verify-core-v1-gate.ps1의 다음 검증 또는 설명 단계를 구성한다.
5)실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
7$ErrorActionPreference = 'Stop'실행 의미: PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다.
8$reference = Split-Path -Parent $PSScriptRoot실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
9$project = (Resolve-Path -LiteralPath $ProjectRoot).Path실행 의미: 입력 경로를 실제 절대 경로로 확인한다.
10if ([string]::IsNullOrWhiteSpace($ExpectedPath)) {실행 의미: 조건·반복·함수의 실행 block을 연다.
11 $ExpectedPath = Join-Path $reference 'learning_stages\w24\overlay\core-v1-expected.json'실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
12}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
13$contract = Get-Content -LiteralPath $ExpectedPath -Raw | ConvertFrom-Json실행 의미: JSON text를 필드로 접근 가능한 PowerShell object로 바꾼다.
14$expected = @($contract.classes.psobject.Properties.Name | Sort-Object)실행 의미: class 이름과 기대 test 수를 exact inventory로 고정한다.
15Push-Location $project실행 의미: verify-core-v1-gate.ps1의 다음 검증 또는 설명 단계를 구성한다.
16try {실행 의미: 조건·반복·함수의 실행 block을 연다.
17 & .\gradlew.bat clean coreV1Gate --no-daemon실행 의미: learner project의 Gradle wrapper로 지정 task를 실행한다.
18 if ($LASTEXITCODE -ne 0) { throw "coreV1Gate native exit=$LASTEXITCODE" }실행 의미: native process 종료 코드를 검사해 실패를 놓치지 않는다.
20 $resultDirectory = Join-Path $project 'build\test-results\coreV1Gate'실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
21 $xmlFiles = @(Get-ChildItem -LiteralPath $resultDirectory -Filter 'TEST-*.xml' -File)실행 의미: JUnit XML 결과 파일만 exact inventory 입력으로 모은다.
22 if ($xmlFiles.Count -eq 0) { throw 'coreV1Gate produced no XML test result' }실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
24 $rows = foreach ($file in $xmlFiles) {실행 의미: 고정 목록의 각 항목에 같은 검사를 반복 적용한다.
25 [xml]$xml = Get-Content -LiteralPath $file.FullName -Raw실행 의미: verify-core-v1-gate.ps1의 다음 검증 또는 설명 단계를 구성한다.
26 [pscustomobject]@{실행 의미: 조건·반복·함수의 실행 block을 연다.
27 class = [string]$xml.testsuite.name실행 의미: JUnit suite의 class 이름과 test/failure/error/skip 수를 읽는다.
28 tests = [int]$xml.testsuite.tests실행 의미: JUnit suite의 class 이름과 test/failure/error/skip 수를 읽는다.
29 failures = [int]$xml.testsuite.failures실행 의미: JUnit suite의 class 이름과 test/failure/error/skip 수를 읽는다.
30 errors = [int]$xml.testsuite.errors실행 의미: JUnit suite의 class 이름과 test/failure/error/skip 수를 읽는다.
31 skipped = [int]$xml.testsuite.skipped실행 의미: JUnit suite의 class 이름과 test/failure/error/skip 수를 읽는다.
32 }실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
33 }실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
34 $actual = @($rows.class | Sort-Object -Unique)실행 의미: Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
35 $missing = @($expected | Where-Object { $_ -notin $actual })실행 의미: 조건을 만족하는 row만 필터링한다.
36 $unexpected = @($actual | Where-Object { $_ -notin $expected })실행 의미: 조건을 만족하는 row만 필터링한다.
37 if ($missing.Count -gt 0 -or $unexpected.Count -gt 0) {실행 의미: 조건·반복·함수의 실행 block을 연다.
38 throw "class inventory mismatch; missing=$($missing -join ','); unexpected=$($unexpected -join ',')"실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
39 }실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
40 $tests = ($rows | Measure-Object tests -Sum).Sum실행 의미: suite별 수치를 전체 합계로 계산한다.
41 $failures = ($rows | Measure-Object failures -Sum).Sum실행 의미: suite별 수치를 전체 합계로 계산한다.
42 $errors = ($rows | Measure-Object errors -Sum).Sum실행 의미: suite별 수치를 전체 합계로 계산한다.
43 $skipped = ($rows | Measure-Object skipped -Sum).Sum실행 의미: suite별 수치를 전체 합계로 계산한다.
44 $wrongCounts = @($rows | Where-Object { $_.tests -ne [int]$contract.classes.psobject.Properties[$_.class].Value })실행 의미: class 이름과 기대 test 수를 exact inventory로 고정한다.
45 if ($actual.Count -ne 37 -or $tests -ne 66 -or $wrongCounts.Count -gt 0 -or $failures -ne 0 -or $errors -ne 0 -or $skipped -ne 0) {실행 의미: 조건·반복·함수의 실행 block을 연다.
46 throw "test summary is not Green: tests=$tests failures=$failures errors=$errors skipped=$skipped"실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
47 }실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
49 $summary = @(실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
50 'CORE_V1_GATE_GREEN',실행 의미: 37 class·66 test·실패/오류/skip 0일 때만 exact local marker를 낸다.
51 "classes=$($actual.Count)",실행 의미: class 이름과 기대 test 수를 exact inventory로 고정한다.
52 "tests=$tests",실행 의미: verify-core-v1-gate.ps1의 다음 검증 또는 설명 단계를 구성한다.
53 "failures=$failures",실행 의미: verify-core-v1-gate.ps1의 다음 검증 또는 설명 단계를 구성한다.
54 "errors=$errors",실행 의미: verify-core-v1-gate.ps1의 다음 검증 또는 설명 단계를 구성한다.
55 "skipped=$skipped"실행 의미: verify-core-v1-gate.ps1의 다음 검증 또는 설명 단계를 구성한다.
56 )실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
57 $summary실행 의미: verify-core-v1-gate.ps1의 다음 검증 또는 설명 단계를 구성한다.
58 $parent = Split-Path -Parent $EvidencePath실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
59 if (-not [string]::IsNullOrWhiteSpace($parent)) {실행 의미: 조건·반복·함수의 실행 block을 연다.
60 New-Item -ItemType Directory -Force -Path $parent | Out-Null실행 의미: Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
61 }실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
62 $summary | Set-Content -LiteralPath $EvidencePath -Encoding utf8실행 의미: Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
63} finally {실행 의미: 중간 실패가 있어도 반드시 실행할 cleanup 경계를 연다.
64 Pop-Location실행 의미: verify-core-v1-gate.ps1의 다음 검증 또는 설명 단계를 구성한다.
65}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
07

STEP 07 / 13

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

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

한 줄로 읽기

verify-core-v1-gate.ps1 — actual XML 37/66을 fail-closed 검증는 native Gradle exit, JUnit XML 존재, exact class set, class별 test 수와 failure/error/skip 0을 함께 확인한다.

문법 해부

  • .ps1 문법에서 선언·조건·pipeline·block 경계를 먼저 나눈다.
  • expected 값과 actual 결과를 같은 이름처럼 보여도 서로 다른 source로 읽는다.
  • native exit·row count·hash·사람 판정을 서로 대체하지 않는다.

실행 순서

  1. 입력 경로·fixture·환경변수·expected 계약을 고정한다.
  2. source가 실행하는 native process·HTTP·SQL 또는 형식 검사를 따라간다.
  3. actual 값과 exact marker를 대조하고 실패면 성공 발행 전에 중단한다.
  4. finally cleanup과 비범위를 evidence에 남긴다.

W24 조각별 정밀 해설

F03-C01 · 원문 1–12줄
문법 해부
.ps1 문법으로 1–12줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
CORE_V1_GATE_GREEN, classes=37, tests=66를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
XML이 없으면 즉시 실패한다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
XML이 없으면 즉시 실패한다; wildcard·0 tests 성공을 허용하지 않는다; 이 HTML은 runner를 실행하지 않았다
다음 연결
다음 조각 또는 F03 evidence 판정으로 상태를 넘긴다.
F03-C02 · 원문 13–24줄
문법 해부
.ps1 문법으로 13–24줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
CORE_V1_GATE_GREEN, classes=37, tests=66를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
XML이 없으면 즉시 실패한다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
XML이 없으면 즉시 실패한다; wildcard·0 tests 성공을 허용하지 않는다; 이 HTML은 runner를 실행하지 않았다
다음 연결
다음 조각 또는 F03 evidence 판정으로 상태를 넘긴다.
F03-C03 · 원문 25–36줄
문법 해부
.ps1 문법으로 25–36줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
CORE_V1_GATE_GREEN, classes=37, tests=66를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
XML이 없으면 즉시 실패한다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
XML이 없으면 즉시 실패한다; wildcard·0 tests 성공을 허용하지 않는다; 이 HTML은 runner를 실행하지 않았다
다음 연결
다음 조각 또는 F03 evidence 판정으로 상태를 넘긴다.
F03-C04 · 원문 37–48줄
문법 해부
.ps1 문법으로 37–48줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
CORE_V1_GATE_GREEN, classes=37, tests=66를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
XML이 없으면 즉시 실패한다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
XML이 없으면 즉시 실패한다; wildcard·0 tests 성공을 허용하지 않는다; 이 HTML은 runner를 실행하지 않았다
다음 연결
다음 조각 또는 F03 evidence 판정으로 상태를 넘긴다.
F03-C05 · 원문 49–60줄
문법 해부
.ps1 문법으로 49–60줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
CORE_V1_GATE_GREEN, classes=37, tests=66를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
XML이 없으면 즉시 실패한다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
XML이 없으면 즉시 실패한다; wildcard·0 tests 성공을 허용하지 않는다; 이 HTML은 runner를 실행하지 않았다
다음 연결
다음 조각 또는 F03 evidence 판정으로 상태를 넘긴다.
F03-C06 · 원문 61–65줄
문법 해부
.ps1 문법으로 61–65줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
CORE_V1_GATE_GREEN, classes=37, tests=66를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
XML이 없으면 즉시 실패한다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
XML이 없으면 즉시 실패한다; wildcard·0 tests 성공을 허용하지 않는다; 이 HTML은 runner를 실행하지 않았다
다음 연결
다음 조각 또는 F03 evidence 판정으로 상태를 넘긴다.
실행 순서 — 66을 fail-closed 검증히토리 → 니지카 → 료 → 키타
  1. 히토리

    classes=37가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 native Gradle exit, JUnit XML 존재, exact class set, class별 test 수와 failure/error/skip 0을 함께 확인한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘wildcard·0 tests 성공을 허용하지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 classes=37와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

08

STEP 08 / 13

실제 값 따라가기

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

순서들어온 값코드가 하는 일나온 값·상태경계
입력CORE_V1_GATE_GREENsource 계약에 대입F03 실행/설명 시작 상태XML이 없으면 즉시 실패한다
검증classes=37expected와 actual 또는 형식 대조통과 또는 첫 mismatchwildcard·0 tests 성공을 허용하지 않는다
증거failures/errors/skipped=0marker·hash·row를 같은 run에 연결범위가 적힌 evidence 후보이 HTML은 runner를 실행하지 않았다
실제 값 — 66을 fail-closed 검증히토리 → 니지카 → 료 → 키타
  1. 히토리

    tests=66가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 native Gradle exit, JUnit XML 존재, exact class set, class별 test 수와 failure/error/skip 0을 함께 확인한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘이 HTML은 runner를 실행하지 않았다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 tests=66와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

09

STEP 09 / 13

Gradle·PowerShell·HTTP·PostgreSQL 내부에서 벌어지는 일

Gradle·JUnit XML·PowerShell·HTTP·PostgreSQL·Docker에서 실제로 일어나는 일과 증명 범위를 구분합니다.

source/contract

verify-core-v1-gate.ps1 bytes와 expected 값을 읽는다.

파일 존재만으로 runtime 성공은 아니다.
execution/evidence

native exit·HTTP status·JUnit XML·DB row·hash 중 이 파일이 소유한 값을 만든다.

XML이 없으면 즉시 실패한다
release/human

관련 evidence와 사람 의미 검토를 release 후보에 연결한다.

이 HTML은 runner를 실행하지 않았다
첫 실패 경계 — 66을 fail-closed 검증히토리 → 니지카 → 료 → 키타
  1. 히토리

    failures/errors/skipped=0가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 native Gradle exit, JUnit XML 존재, exact class set, class별 test 수와 failure/error/skip 0을 함께 확인한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘XML이 없으면 즉시 실패한다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 failures/errors/skipped=0와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

10

STEP 10 / 13

흔한 착각과 틀린 예

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

❌ CORE_V1_GATE_GREEN 문자열이 source에 있으니 실제 실행도 Green이다.

왜 틀리나 source literal과 runtime 관찰값은 다른 증거다.

바르게 읽기 native exit·actual XML/HTTP/DB evidence를 별도로 확인한다.

반례 script가 실행 전 경로 오류로 멈춰도 literal은 그대로 남는다.

❌ 파일 SHA-256이 있으면 내용의 의미와 사실성도 검증됐다.

왜 틀리나 hash는 동일 bytes만 말한다.

바르게 읽기 schema·수치·질문·근거는 별도 자동 또는 사람 판정을 거친다.

반례 빈 review 질문을 가진 CSV도 안정된 hash를 가진다.

❌ LOCAL_ARTIFACT_VALIDATED는 release Green과 같다.

왜 틀리나 generic validator는 파일 shape만 확인한다.

바르게 읽기 HUMAN_SEMANTIC_REVIEW_REQUIRED를 유지한다.

반례 잘못된 track 점수표도 byte 수 조건은 통과할 수 있다.

❌ 이 파일이 W24 전체 lifecycle을 모두 소유한다.

왜 틀리나 각 source는 Gate·demo·cleanup·사람 review 중 일부만 담당한다.

바르게 읽기 owner와 non-responsibility를 release manifest에서 분리한다.

반례 D4 source audit에는 runtime_claim=false가 명시된다.

❌ 이전 주 Green이나 오래된 log를 현재 commit 결과로 재사용한다.

왜 틀리나 source·commit·actual result가 같은 실행에 묶이지 않는다.

바르게 읽기 release 후보에서 새 evidence와 hash를 만든다.

반례 expected JSON이 바뀌면 예전 XML은 exact inventory를 증명하지 못한다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

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

증명 범위

XML이 없으면 즉시 실패한다

이 책임을 맡는 곳: runtime Gate
증명 범위

wildcard·0 tests 성공을 허용하지 않는다

이 책임을 맡는 곳: external/human review
증명 범위

이 HTML은 runner를 실행하지 않았다

이 책임을 맡는 곳: release manifest
증명 범위

XML이 없으면 즉시 실패한다

이 책임을 맡는 곳: 운영 환경
증명하지 않는 범위 — 66을 fail-closed 검증히토리 → 니지카 → 료 → 키타
  1. 히토리

    CORE_V1_GATE_GREEN가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 native Gradle exit, JUnit XML 존재, exact class set, class별 test 수와 failure/error/skip 0을 함께 확인한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘wildcard·0 tests 성공을 허용하지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 CORE_V1_GATE_GREEN와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

12

STEP 12 / 13

직접 다시 써보기

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

1단계 · 뜻부터 복원

  • native Gradle exit, JUnit XML 존재, exact class set, class별 test 수와 failure/error/skip 0을 함께 확인한다.
  • 핵심 값은 CORE_V1_GATE_GREEN, classes=37, tests=66, failures/errors/skipped=0다.

2단계 · 코드 조각 재조립

  1. 1. PowerShell script가 받을 입력 계약을 연다
  2. 2. 이 인자가 빠지면 실행 시작 전에 binding을 거절한다
  3. 3. 이 인자가 빠지면 실행 시작 전에 binding을 거절한다
  4. 4. verify-core-v1-gate.ps1의 다음 검증 또는 설명 단계를 구성한다
  5. 5. 앞에서 연 block 또는 호출 범위를 닫는다
  6. 7. PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다
  7. 8. 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다
  8. 9. 입력 경로를 실제 절대 경로로 확인한다

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

scripts/verify-core-v1-gate.ps1을 새 파일에 다시 쓰고 expected·actual·실패·cleanup·비범위를 주석으로 표시한다.

자가 점검
  • 비어 있지 않은 모든 source 줄을 한 번씩 읽었나?
  • source shape와 runtime Green을 분리했나?
  • 사람 검토·외부 상태를 자동 성공으로 꾸미지 않았나?
  • 첫 실패와 cleanup 책임을 설명할 수 있나?
13

STEP 13 / 13

전체 원본 source

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

원문 정본 전체 source 확인하기
PDF 전문 정본 · packaged PowerShell sourcescripts/verify-core-v1-gate.ps1SHA-256 0702cb66d199ed64b8d0d8772e1f08df46324cd2de788e558981e4c39353a8f3
verify-core-v1-gate.ps1 — actual XML 37/66을 fail-closed 검증 전체
param(
  [Parameter(Mandatory=$true)][string]$ProjectRoot,
  [Parameter(Mandatory=$true)][string]$EvidencePath,
  [string]$ExpectedPath = ''
)

$ErrorActionPreference = 'Stop'
$reference = Split-Path -Parent $PSScriptRoot
$project = (Resolve-Path -LiteralPath $ProjectRoot).Path
if ([string]::IsNullOrWhiteSpace($ExpectedPath)) {
  $ExpectedPath = Join-Path $reference 'learning_stages\w24\overlay\core-v1-expected.json'
}
$contract = Get-Content -LiteralPath $ExpectedPath -Raw | ConvertFrom-Json
$expected = @($contract.classes.psobject.Properties.Name | Sort-Object)
Push-Location $project
try {
  & .\gradlew.bat clean coreV1Gate --no-daemon
  if ($LASTEXITCODE -ne 0) { throw "coreV1Gate native exit=$LASTEXITCODE" }

  $resultDirectory = Join-Path $project 'build\test-results\coreV1Gate'
  $xmlFiles = @(Get-ChildItem -LiteralPath $resultDirectory -Filter 'TEST-*.xml' -File)
  if ($xmlFiles.Count -eq 0) { throw 'coreV1Gate produced no XML test result' }

  $rows = foreach ($file in $xmlFiles) {
    [xml]$xml = Get-Content -LiteralPath $file.FullName -Raw
    [pscustomobject]@{
      class = [string]$xml.testsuite.name
      tests = [int]$xml.testsuite.tests
      failures = [int]$xml.testsuite.failures
      errors = [int]$xml.testsuite.errors
      skipped = [int]$xml.testsuite.skipped
    }
  }
  $actual = @($rows.class | Sort-Object -Unique)
  $missing = @($expected | Where-Object { $_ -notin $actual })
  $unexpected = @($actual | Where-Object { $_ -notin $expected })
  if ($missing.Count -gt 0 -or $unexpected.Count -gt 0) {
    throw "class inventory mismatch; missing=$($missing -join ','); unexpected=$($unexpected -join ',')"
  }
  $tests = ($rows | Measure-Object tests -Sum).Sum
  $failures = ($rows | Measure-Object failures -Sum).Sum
  $errors = ($rows | Measure-Object errors -Sum).Sum
  $skipped = ($rows | Measure-Object skipped -Sum).Sum
  $wrongCounts = @($rows | Where-Object { $_.tests -ne [int]$contract.classes.psobject.Properties[$_.class].Value })
  if ($actual.Count -ne 37 -or $tests -ne 66 -or $wrongCounts.Count -gt 0 -or $failures -ne 0 -or $errors -ne 0 -or $skipped -ne 0) {
    throw "test summary is not Green: tests=$tests failures=$failures errors=$errors skipped=$skipped"
  }

  $summary = @(
    'CORE_V1_GATE_GREEN',
    "classes=$($actual.Count)",
    "tests=$tests",
    "failures=$failures",
    "errors=$errors",
    "skipped=$skipped"
  )
  $summary
  $parent = Split-Path -Parent $EvidencePath
  if (-not [string]::IsNullOrWhiteSpace($parent)) {
    New-Item -ItemType Directory -Force -Path $parent | Out-Null
  }
  $summary | Set-Content -LiteralPath $EvidencePath -Encoding utf8
} finally {
  Pop-Location
}
04

W24 D1 test inventory — actual XML을 evidence에 원자 저장

illustrative/powershell/W24-D1-primary-evidence-closure.ps1

학습용 예시 · PDF inline PowerShell · 정본 답안 아님 · 비실행 · 학습용 예시 · 정본 답안 아님 · W24-F04
84줄 연결84줄 번역8 chunks
01

STEP 01 / 13

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

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

오늘의 한 문장

PDF p789의 당일 evidence closure를 가독성 있게 정리해 class별 XML hash와 aggregate를 test-inventory.md에 묶는다.

  1. actual_xml=37은 어느 source와 실제 결과에서 확인해야 할까?
  2. 첫 실패를 만드는 조건과 fail-closed 지점은 어디일까?
  3. 왜 ‘PDF-only 학습 예시이며 packaged 정본이 아니다’를 별도 경계로 남겨야 할까?
이 파일에서 끝까지 다시 쓰는 값actual_xml=37tests=66atomic tmp moveexpected/gate SHA-256
왜 필요한가 — W24 D1 test inventory — actual XML을 evidence에 원자 저장히토리 → 니지카 → 료 → 키타
  1. 히토리

    actual_xml=37가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 PDF p789의 당일 evidence closure를 가독성 있게 정리해 class별 XML hash와 aggregate를 test-inventory.md에 묶는다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘PDF-only 학습 예시이며 packaged 정본이 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 actual_xml=37와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

02

STEP 02 / 13

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

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

새 기능을 멈춘 팀이 코드·test·문서·demo를 같은 release 후보에 묶어 하나씩 검수한다.

검수 도장이 붙은 공통 거래 코어 출고 상자

이 파일은 PDF p789의 당일 evidence closure를 가독성 있게 정리해 class별 XML hash와 aggregate를 test-inventory.md에 묶는다. 눈으로 읽을 때는 각 줄을 검수표 한 칸처럼 보고, 입력과 다음 상태를 놓치지 않는다.

마지막 도장은 source shape와 실제 runtime·사람 검토를 구분한 뒤에만 찍는다. 특히 PDF-only 학습 예시이며 packaged 정본이 아니다

딱 여기까지만 비유는 실행 순서를 돕지만 실제 Gradle·Docker·DB·사람 review를 대신하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

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

값 1: actual_xml=37

이 파일에서 계속 확인할 고정 단서가 actual_xml=37다.

코드 연결
F04 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
PDF-only 학습 예시이며 packaged 정본이 아니다

값 2: tests=66

이 파일에서 계속 확인할 고정 단서가 tests=66다.

코드 연결
F04 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
고정 숫자만 적은 문서는 통과하지 않는다

값 3: atomic tmp move

이 파일에서 계속 확인할 고정 단서가 atomic tmp move다.

코드 연결
F04 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
실제 실행 결과를 주장하지 않는다

값 4: expected/gate SHA-256

이 파일에서 계속 확인할 고정 단서가 expected/gate SHA-256다.

코드 연결
F04 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
PDF-only 학습 예시이며 packaged 정본이 아니다
04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

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

단어 몇 개만 뽑은 표가 아닙니다.학습용 예시 · PDF inline PowerShell · 정본 답안 아님 · 비실행에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.84 / 84 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F04-L01 # W24 PDF p789에서 제공한 당일 Gate를 읽기 좋게 정리한 학습용 예시다. 출고표 1번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
이전 줄의 상태와 actual_xml=37
결과·효과
관찰 상태 F04-001가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
2줄F04-L02 # packaged reference source가 아니며, 실제 Gradle/JUnit 실행 결과도 아니다. 출고표 2번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
이전 줄의 상태와 actual_xml=37
결과·효과
관찰 상태 F04-002가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
3줄F04-L03 $PRIMARY_PRODUCER = 1 출고표 3번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$PRIMARY_PRODUCER, 1
결과·효과
관찰 상태 F04-003가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
4줄F04-L04 $Artifact = Join-Path $LearnerRoot 'evidence\w24\test-inventory.md' 출고표 4번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Artifact, $LearnerRoot, 'evidence\w24\test-inventory.md'
결과·효과
관찰 상태 F04-004가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
5줄F04-L05 $Verifier = Join-Path $ReferenceRoot 'scripts\verify-core-v1-gate.ps1' 출고표 5번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Verifier, $ReferenceRoot, 'scripts\verify-core-v1-gate.ps1'
결과·효과
관찰 상태 F04-005가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
6줄F04-L06 $GateText = Join-Path $LearnerRoot 'evidence\w24\core-v1-gate.txt' 출고표 6번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$GateText, $LearnerRoot, 'evidence\w24\core-v1-gate.txt'
결과·효과
관찰 상태 F04-006가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
8줄F04-L08 & powershell.exe -NoProfile -ExecutionPolicy Bypass -File $Verifier ` 출고표 8번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$Verifier
결과·효과
관찰 상태 F04-008가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
9줄F04-L09 -ProjectRoot $LearnerRoot -EvidencePath $GateText 출고표 9번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$LearnerRoot, $GateText
결과·효과
관찰 상태 F04-009가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
10줄F04-L10 if ($LASTEXITCODE -ne 0) { 출고표 10번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 native process 종료 코드를 검사해 실패를 놓치지 않는다.
입력
$LASTEXITCODE, 0
결과·효과
관찰 상태 F04-010가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
11줄F04-L11 throw "W24D1 core verifier native exit=$LASTEXITCODE" 출고표 11번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 native process 종료 코드를 검사해 실패를 놓치지 않는다.
입력
$LASTEXITCODE
결과·효과
관찰 상태 F04-011가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
12줄F04-L12 } 출고표 12번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 actual_xml=37
결과·효과
관찰 상태 F04-012가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
14줄F04-L14 $ExpectedPath = Join-Path $ReferenceRoot 'learning_stages\w24\overlay\core-v1-expected.json' 출고표 14번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$ExpectedPath, $ReferenceRoot
결과·효과
관찰 상태 F04-014가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
15줄F04-L15 $Expected = Get-Content -Raw -LiteralPath $ExpectedPath | ConvertFrom-Json 출고표 15번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 JSON text를 필드로 접근 가능한 PowerShell object로 바꾼다.
입력
$Expected, $ExpectedPath
결과·효과
관찰 상태 F04-015가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
16줄F04-L16 $ResultDir = Join-Path $LearnerRoot 'build\test-results\coreV1Gate' 출고표 16번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$ResultDir, $LearnerRoot, 'build\test-results\coreV1Gate'
결과·효과
관찰 상태 F04-016가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
17줄F04-L17 $Rows = @(Get-ChildItem -LiteralPath $ResultDir -Filter 'TEST-*.xml' -File | ForEach-Object { 출고표 17번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 JUnit XML 결과 파일만 exact inventory 입력으로 모은다.
입력
$Rows, $ResultDir, 'TEST-*.xml'
결과·효과
관찰 상태 F04-017가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
18줄F04-L18 [xml]$Xml = Get-Content -Raw -LiteralPath $_.FullName 출고표 18번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$Xml, $_
결과·효과
관찰 상태 F04-018가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
19줄F04-L19 [pscustomobject]@{ 출고표 19번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
이전 줄의 상태와 actual_xml=37
결과·효과
관찰 상태 F04-019가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
20줄F04-L20 class = [string]$Xml.testsuite.name 출고표 20번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 JUnit suite의 class 이름과 test/failure/error/skip 수를 읽는다.
입력
$Xml
결과·효과
관찰 상태 F04-020가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
21줄F04-L21 tests = [int]$Xml.testsuite.tests 출고표 21번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 JUnit suite의 class 이름과 test/failure/error/skip 수를 읽는다.
입력
$Xml
결과·효과
관찰 상태 F04-021가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
22줄F04-L22 failures = [int]$Xml.testsuite.failures 출고표 22번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 JUnit suite의 class 이름과 test/failure/error/skip 수를 읽는다.
입력
$Xml
결과·효과
관찰 상태 F04-022가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
23줄F04-L23 errors = [int]$Xml.testsuite.errors 출고표 23번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 JUnit suite의 class 이름과 test/failure/error/skip 수를 읽는다.
입력
$Xml
결과·효과
관찰 상태 F04-023가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
24줄F04-L24 skipped = [int]$Xml.testsuite.skipped 출고표 24번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 JUnit suite의 class 이름과 test/failure/error/skip 수를 읽는다.
입력
$Xml
결과·효과
관찰 상태 F04-024가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
25줄F04-L25 xml_sha256 = (Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash.ToLowerInvariant() 출고표 25번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 현재 bytes를 64자리 digest로 evidence에 결박한다.
입력
$_
결과·효과
관찰 상태 F04-025가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
26줄F04-L26 } 출고표 26번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 actual_xml=37
결과·효과
관찰 상태 F04-026가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
27줄F04-L27 }) 출고표 27번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 actual_xml=37
결과·효과
관찰 상태 F04-027가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
29줄F04-L29 $ExpectedNames = @($Expected.classes.psobject.Properties.Name | Sort-Object) 출고표 29번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 class 이름과 기대 test 수를 exact inventory로 고정한다.
입력
$ExpectedNames, $Expected
결과·효과
관찰 상태 F04-029가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
30줄F04-L30 $ActualNames = @($Rows.class | Sort-Object -Unique) 출고표 30번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
입력
$ActualNames, $Rows
결과·효과
관찰 상태 F04-030가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
31줄F04-L31 if (Compare-Object $ExpectedNames $ActualNames) { 출고표 31번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 expected와 actual 집합에 누락·예상 밖 항목이 있는지 비교한다.
입력
$ExpectedNames, $ActualNames
결과·효과
관찰 상태 F04-031가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
32줄F04-L32 throw 'W24D1 actual XML class set differs from canonical expectation' 출고표 32번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
이전 줄의 상태와 actual_xml=37
결과·효과
관찰 상태 F04-032가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
33줄F04-L33 } 출고표 33번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 actual_xml=37
결과·효과
관찰 상태 F04-033가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
34줄F04-L34 foreach ($Row in $Rows) { 출고표 34번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 고정 목록의 각 항목에 같은 검사를 반복 적용한다.
입력
$Row, $Rows
결과·효과
관찰 상태 F04-034가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
35줄F04-L35 $ExpectedTests = [int]$Expected.classes.psobject.Properties[$Row.class].Value 출고표 35번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 class 이름과 기대 test 수를 exact inventory로 고정한다.
입력
$ExpectedTests, $Expected, $Row
결과·효과
관찰 상태 F04-035가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
36줄F04-L36 if ($Row.tests -ne $ExpectedTests -or $Row.failures -ne 0 -or $Row.errors -ne 0 -or $Row.skipped -ne 0) { 출고표 36번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$Row, $ExpectedTests, $Row
결과·효과
관찰 상태 F04-036가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
37줄F04-L37 throw "W24D1 class/count/status mismatch: $($Row.class)" 출고표 37번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
$Row
결과·효과
관찰 상태 F04-037가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
38줄F04-L38 } 출고표 38번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 actual_xml=37
결과·효과
관찰 상태 F04-038가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
39줄F04-L39 } 출고표 39번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 actual_xml=37
결과·효과
관찰 상태 F04-039가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
41줄F04-L41 $Tests = ($Rows | Measure-Object tests -Sum).Sum 출고표 41번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 suite별 수치를 전체 합계로 계산한다.
입력
$Tests, $Rows
결과·효과
관찰 상태 F04-041가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
42줄F04-L42 $Failures = ($Rows | Measure-Object failures -Sum).Sum 출고표 42번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 suite별 수치를 전체 합계로 계산한다.
입력
$Failures, $Rows
결과·효과
관찰 상태 F04-042가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
43줄F04-L43 $Errors = ($Rows | Measure-Object errors -Sum).Sum 출고표 43번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 suite별 수치를 전체 합계로 계산한다.
입력
$Errors, $Rows
결과·효과
관찰 상태 F04-043가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
44줄F04-L44 $Skipped = ($Rows | Measure-Object skipped -Sum).Sum 출고표 44번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 suite별 수치를 전체 합계로 계산한다.
입력
$Skipped, $Rows
결과·효과
관찰 상태 F04-044가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
45줄F04-L45 if ($Rows.Count -ne 37 -or $Tests -ne 66 -or $Failures -ne 0 -or $Errors -ne 0 -or $Skipped -ne 0) { 출고표 45번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$Rows, 37, $Tests
결과·효과
관찰 상태 F04-045가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
46줄F04-L46 throw "W24D1 actual aggregate mismatch classes=$($Rows.Count) tests=$Tests" 출고표 46번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 class 이름과 기대 test 수를 exact inventory로 고정한다.
입력
$Rows, $Tests
결과·효과
관찰 상태 F04-046가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
47줄F04-L47 } 출고표 47번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 actual_xml=37
결과·효과
관찰 상태 F04-047가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
49줄F04-L49 $Gate = Get-Content -Raw -LiteralPath $GateText 출고표 49번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Gate, $GateText
결과·효과
관찰 상태 F04-049가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
50줄F04-L50 foreach ($Token in @('CORE_V1_GATE_GREEN', 'classes=37', 'tests=66', 'failures=0', 'errors=0', 'skipped=0')) { 출고표 50번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 class 이름과 기대 test 수를 exact inventory로 고정한다.
입력
$Token, 'CORE_V1_GATE_GREEN', 'classes=37'
결과·효과
관찰 상태 F04-050가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
51줄F04-L51 if ($Gate -cnotmatch [regex]::Escape($Token)) { 출고표 51번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$Gate, $Token
결과·효과
관찰 상태 F04-051가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
52줄F04-L52 throw "W24D1 gate marker missing: $Token" 출고표 52번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
"W24D1 gate marker missing: $Token"
결과·효과
관찰 상태 F04-052가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
53줄F04-L53 } 출고표 53번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 actual_xml=37
결과·효과
관찰 상태 F04-053가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
54줄F04-L54 } 출고표 54번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 actual_xml=37
결과·효과
관찰 상태 F04-054가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
56줄F04-L56 $ExpectedHash = (Get-FileHash -LiteralPath $ExpectedPath -Algorithm SHA256).Hash.ToLowerInvariant() 출고표 56번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 현재 bytes를 64자리 digest로 evidence에 결박한다.
입력
$ExpectedHash, $ExpectedPath
결과·효과
관찰 상태 F04-056가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
57줄F04-L57 $GateHash = (Get-FileHash -LiteralPath $GateText -Algorithm SHA256).Hash.ToLowerInvariant() 출고표 57번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 현재 bytes를 64자리 digest로 evidence에 결박한다.
입력
$GateHash, $GateText
결과·효과
관찰 상태 F04-057가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
58줄F04-L58 $Lines = @( 출고표 58번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Lines
결과·효과
관찰 상태 F04-058가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
59줄F04-L59 '# W24 test inventory', 출고표 59번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
'# W24 test inventory'
결과·효과
관찰 상태 F04-059가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
60줄F04-L60 'status: GREEN', 출고표 60번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
'status: GREEN'
결과·효과
관찰 상태 F04-060가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
61줄F04-L61 'source: actual coreV1Gate XML', 출고표 61번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
'source: actual coreV1Gate XML'
결과·효과
관찰 상태 F04-061가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
62줄F04-L62 "classes: $($Rows.Count)", 출고표 62번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 class 이름과 기대 test 수를 exact inventory로 고정한다.
입력
"classes: $($Rows.Count)"
결과·효과
관찰 상태 F04-062가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
63줄F04-L63 "tests: $Tests", 출고표 63번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
"tests: $Tests"
결과·효과
관찰 상태 F04-063가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
64줄F04-L64 "failures: $Failures", 출고표 64번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
"failures: $Failures"
결과·효과
관찰 상태 F04-064가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
65줄F04-L65 "errors: $Errors", 출고표 65번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
"errors: $Errors"
결과·효과
관찰 상태 F04-065가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
66줄F04-L66 "skipped: $Skipped", 출고표 66번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
"skipped: $Skipped"
결과·효과
관찰 상태 F04-066가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
67줄F04-L67 "expected_sha256: $ExpectedHash", 출고표 67번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 현재 bytes를 64자리 digest로 evidence에 결박한다.
입력
"expected_sha256: $ExpectedHash"
결과·효과
관찰 상태 F04-067가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
68줄F04-L68 "gate_sha256: $GateHash", 출고표 68번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 현재 bytes를 64자리 digest로 evidence에 결박한다.
입력
"gate_sha256: $GateHash"
결과·효과
관찰 상태 F04-068가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
69줄F04-L69 '', 출고표 69번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 actual_xml=37
결과·효과
관찰 상태 F04-069가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
70줄F04-L70 '| class | tests | failures | errors | skipped | xml_sha256 |', 출고표 70번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 현재 bytes를 64자리 digest로 evidence에 결박한다.
입력
이전 줄의 상태와 actual_xml=37
결과·효과
관찰 상태 F04-070가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
71줄F04-L71 '|---|---:|---:|---:|---:|---|' 출고표 71번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
입력
'|---|---:|---:|---:|---:|---|'
결과·효과
관찰 상태 F04-071가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
72줄F04-L72 ) 출고표 72번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 actual_xml=37
결과·효과
관찰 상태 F04-072가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
73줄F04-L73 $Lines += @($Rows | Sort-Object class | ForEach-Object { 출고표 73번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 고정 목록의 각 항목에 같은 검사를 반복 적용한다.
입력
$Lines, $Rows
결과·효과
관찰 상태 F04-073가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
74줄F04-L74 "| $($_.class) | $($_.tests) | $($_.failures) | $($_.errors) | $($_.skipped) | $($_.xml_sha256) |" 출고표 74번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 현재 bytes를 64자리 digest로 evidence에 결박한다.
입력
$_, $_, $_
결과·효과
관찰 상태 F04-074가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
75줄F04-L75 }) 출고표 75번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 actual_xml=37
결과·효과
관찰 상태 F04-075가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
77줄F04-L77 $Tmp = "$Artifact.tmp" 출고표 77번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Tmp, "$Artifact.tmp"
결과·효과
관찰 상태 F04-077가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
78줄F04-L78 New-Item -ItemType Directory -Force (Split-Path -Parent $Artifact) | Out-Null 출고표 78번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
입력
$Artifact
결과·효과
관찰 상태 F04-078가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
79줄F04-L79 $Lines | Set-Content -Encoding utf8 $Tmp 출고표 79번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
입력
$Lines, $Tmp
결과·효과
관찰 상태 F04-079가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
80줄F04-L80 $Saved = Get-Content -Raw -LiteralPath $Tmp 출고표 80번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Saved, $Tmp
결과·효과
관찰 상태 F04-080가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
81줄F04-L81 foreach ($Token in @('source: actual coreV1Gate XML', 'classes: 37', 'tests: 66', 'failures: 0', 'errors: 0', 'skipped: 0', "expected_sha256: $ExpectedHash", "gate_sha256: $GateHash")) { 출고표 81번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 class 이름과 기대 test 수를 exact inventory로 고정한다.
입력
$Token, 'source: actual coreV1Gate XML', 'classes: 37'
결과·효과
관찰 상태 F04-081가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
82줄F04-L82 if ($Saved -cnotmatch [regex]::Escape($Token)) { 출고표 82번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$Saved, $Token
결과·효과
관찰 상태 F04-082가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
83줄F04-L83 throw "W24D1 inventory marker missing: $Token" 출고표 83번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
"W24D1 inventory marker missing: $Token"
결과·효과
관찰 상태 F04-083가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
84줄F04-L84 } 출고표 84번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 actual_xml=37
결과·효과
관찰 상태 F04-084가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
85줄F04-L85 } 출고표 85번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 actual_xml=37
결과·효과
관찰 상태 F04-085가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
86줄F04-L86 Move-Item -Force -LiteralPath $Tmp -Destination $Artifact 출고표 86번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$Tmp, $Artifact
결과·효과
관찰 상태 F04-086가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
87줄F04-L87 if (!(Test-Path -LiteralPath $Artifact -PathType Leaf)) { 출고표 87번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 필수 파일이나 경로가 실제로 있는지 확인한다.
입력
$Artifact
결과·효과
관찰 상태 F04-087가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
88줄F04-L88 throw 'W24D1 atomic inventory move failed' 출고표 88번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
'W24D1 atomic inventory move failed'
결과·효과
관찰 상태 F04-088가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
89줄F04-L89 } 출고표 89번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 actual_xml=37
결과·효과
관찰 상태 F04-089가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
고정 숫자만 적은 문서는 통과하지 않는다
90줄F04-L90 $Hash = (Get-FileHash -LiteralPath $Artifact -Algorithm SHA256).Hash.ToLowerInvariant() 출고표 90번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 현재 bytes를 64자리 digest로 evidence에 결박한다.
입력
$Hash, $Artifact
결과·효과
관찰 상태 F04-090가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 실행 결과를 주장하지 않는다
91줄F04-L91 "W24D1_PRIMARY_EVIDENCE_GREEN classes=37 tests=66 failures=0 errors=0 skipped=0 actual_xml=37 sha256=$Hash" 출고표 91번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 class 이름과 기대 test 수를 exact inventory로 고정한다.
입력
37, 66, 0
결과·효과
관찰 상태 F04-091가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시이며 packaged 정본이 아니다
05

STEP 05 / 13

원본 코드 조각

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

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

F04-C01 · 원문 1–12줄1–12줄
1–12줄 원본
# W24 PDF p789에서 제공한 당일 Gate를 읽기 좋게 정리한 학습용 예시다.
# packaged reference source가 아니며, 실제 Gradle/JUnit 실행 결과도 아니다.
$PRIMARY_PRODUCER = 1
$Artifact = Join-Path $LearnerRoot 'evidence\w24\test-inventory.md'
$Verifier = Join-Path $ReferenceRoot 'scripts\verify-core-v1-gate.ps1'
$GateText = Join-Path $LearnerRoot 'evidence\w24\core-v1-gate.txt'

& powershell.exe -NoProfile -ExecutionPolicy Bypass -File $Verifier `
  -ProjectRoot $LearnerRoot -EvidencePath $GateText
if ($LASTEXITCODE -ne 0) {
  throw "W24D1 core verifier native exit=$LASTEXITCODE"
}
F04-C02 · 원문 13–24줄13–24줄
13–24줄 원본

$ExpectedPath = Join-Path $ReferenceRoot 'learning_stages\w24\overlay\core-v1-expected.json'
$Expected = Get-Content -Raw -LiteralPath $ExpectedPath | ConvertFrom-Json
$ResultDir = Join-Path $LearnerRoot 'build\test-results\coreV1Gate'
$Rows = @(Get-ChildItem -LiteralPath $ResultDir -Filter 'TEST-*.xml' -File | ForEach-Object {
  [xml]$Xml = Get-Content -Raw -LiteralPath $_.FullName
  [pscustomobject]@{
    class = [string]$Xml.testsuite.name
    tests = [int]$Xml.testsuite.tests
    failures = [int]$Xml.testsuite.failures
    errors = [int]$Xml.testsuite.errors
    skipped = [int]$Xml.testsuite.skipped
F04-C03 · 원문 25–36줄25–36줄
25–36줄 원본
    xml_sha256 = (Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash.ToLowerInvariant()
  }
})

$ExpectedNames = @($Expected.classes.psobject.Properties.Name | Sort-Object)
$ActualNames = @($Rows.class | Sort-Object -Unique)
if (Compare-Object $ExpectedNames $ActualNames) {
  throw 'W24D1 actual XML class set differs from canonical expectation'
}
foreach ($Row in $Rows) {
  $ExpectedTests = [int]$Expected.classes.psobject.Properties[$Row.class].Value
  if ($Row.tests -ne $ExpectedTests -or $Row.failures -ne 0 -or $Row.errors -ne 0 -or $Row.skipped -ne 0) {
F04-C04 · 원문 37–48줄37–48줄
37–48줄 원본
    throw "W24D1 class/count/status mismatch: $($Row.class)"
  }
}

$Tests = ($Rows | Measure-Object tests -Sum).Sum
$Failures = ($Rows | Measure-Object failures -Sum).Sum
$Errors = ($Rows | Measure-Object errors -Sum).Sum
$Skipped = ($Rows | Measure-Object skipped -Sum).Sum
if ($Rows.Count -ne 37 -or $Tests -ne 66 -or $Failures -ne 0 -or $Errors -ne 0 -or $Skipped -ne 0) {
  throw "W24D1 actual aggregate mismatch classes=$($Rows.Count) tests=$Tests"
}
F04-C05 · 원문 49–60줄49–60줄
49–60줄 원본
$Gate = Get-Content -Raw -LiteralPath $GateText
foreach ($Token in @('CORE_V1_GATE_GREEN', 'classes=37', 'tests=66', 'failures=0', 'errors=0', 'skipped=0')) {
  if ($Gate -cnotmatch [regex]::Escape($Token)) {
    throw "W24D1 gate marker missing: $Token"
  }
}

$ExpectedHash = (Get-FileHash -LiteralPath $ExpectedPath -Algorithm SHA256).Hash.ToLowerInvariant()
$GateHash = (Get-FileHash -LiteralPath $GateText -Algorithm SHA256).Hash.ToLowerInvariant()
$Lines = @(
  '# W24 test inventory',
  'status: GREEN',
F04-C06 · 원문 61–72줄61–72줄
61–72줄 원본
  'source: actual coreV1Gate XML',
  "classes: $($Rows.Count)",
  "tests: $Tests",
  "failures: $Failures",
  "errors: $Errors",
  "skipped: $Skipped",
  "expected_sha256: $ExpectedHash",
  "gate_sha256: $GateHash",
  '',
  '| class | tests | failures | errors | skipped | xml_sha256 |',
  '|---|---:|---:|---:|---:|---|'
)
F04-C07 · 원문 73–84줄73–84줄
73–84줄 원본
$Lines += @($Rows | Sort-Object class | ForEach-Object {
  "| $($_.class) | $($_.tests) | $($_.failures) | $($_.errors) | $($_.skipped) | $($_.xml_sha256) |"
})

$Tmp = "$Artifact.tmp"
New-Item -ItemType Directory -Force (Split-Path -Parent $Artifact) | Out-Null
$Lines | Set-Content -Encoding utf8 $Tmp
$Saved = Get-Content -Raw -LiteralPath $Tmp
foreach ($Token in @('source: actual coreV1Gate XML', 'classes: 37', 'tests: 66', 'failures: 0', 'errors: 0', 'skipped: 0', "expected_sha256: $ExpectedHash", "gate_sha256: $GateHash")) {
  if ($Saved -cnotmatch [regex]::Escape($Token)) {
    throw "W24D1 inventory marker missing: $Token"
  }
F04-C08 · 원문 85–91줄85–91줄
85–91줄 원본
}
Move-Item -Force -LiteralPath $Tmp -Destination $Artifact
if (!(Test-Path -LiteralPath $Artifact -PathType Leaf)) {
  throw 'W24D1 atomic inventory move failed'
}
$Hash = (Get-FileHash -LiteralPath $Artifact -Algorithm SHA256).Hash.ToLowerInvariant()
"W24D1_PRIMARY_EVIDENCE_GREEN classes=37 tests=66 failures=0 errors=0 skipped=0 actual_xml=37 sha256=$Hash"
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

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

전체 번역 84 / 84

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

원본한국어 번역
1# W24 PDF p789에서 제공한 당일 Gate를 읽기 좋게 정리한 학습용 예시다.문서 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
2# packaged reference source가 아니며, 실제 Gradle/JUnit 실행 결과도 아니다.문서 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
3$PRIMARY_PRODUCER = 1실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
4$Artifact = Join-Path $LearnerRoot 'evidence\w24\test-inventory.md'실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
5$Verifier = Join-Path $ReferenceRoot 'scripts\verify-core-v1-gate.ps1'실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
6$GateText = Join-Path $LearnerRoot 'evidence\w24\core-v1-gate.txt'실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
8& powershell.exe -NoProfile -ExecutionPolicy Bypass -File $Verifier `실행 의미: W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
9 -ProjectRoot $LearnerRoot -EvidencePath $GateText실행 의미: W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
10if ($LASTEXITCODE -ne 0) {실행 의미: native process 종료 코드를 검사해 실패를 놓치지 않는다.
11 throw "W24D1 core verifier native exit=$LASTEXITCODE"실행 의미: native process 종료 코드를 검사해 실패를 놓치지 않는다.
12}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
14$ExpectedPath = Join-Path $ReferenceRoot 'learning_stages\w24\overlay\core-v1-expected.json'실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
15$Expected = Get-Content -Raw -LiteralPath $ExpectedPath | ConvertFrom-Json실행 의미: JSON text를 필드로 접근 가능한 PowerShell object로 바꾼다.
16$ResultDir = Join-Path $LearnerRoot 'build\test-results\coreV1Gate'실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
17$Rows = @(Get-ChildItem -LiteralPath $ResultDir -Filter 'TEST-*.xml' -File | ForEach-Object {실행 의미: JUnit XML 결과 파일만 exact inventory 입력으로 모은다.
18 [xml]$Xml = Get-Content -Raw -LiteralPath $_.FullName실행 의미: W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
19 [pscustomobject]@{실행 의미: 조건·반복·함수의 실행 block을 연다.
20 class = [string]$Xml.testsuite.name실행 의미: JUnit suite의 class 이름과 test/failure/error/skip 수를 읽는다.
21 tests = [int]$Xml.testsuite.tests실행 의미: JUnit suite의 class 이름과 test/failure/error/skip 수를 읽는다.
22 failures = [int]$Xml.testsuite.failures실행 의미: JUnit suite의 class 이름과 test/failure/error/skip 수를 읽는다.
23 errors = [int]$Xml.testsuite.errors실행 의미: JUnit suite의 class 이름과 test/failure/error/skip 수를 읽는다.
24 skipped = [int]$Xml.testsuite.skipped실행 의미: JUnit suite의 class 이름과 test/failure/error/skip 수를 읽는다.
25 xml_sha256 = (Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash.ToLowerInvariant()실행 의미: 현재 bytes를 64자리 digest로 evidence에 결박한다.
26 }실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
27})실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
29$ExpectedNames = @($Expected.classes.psobject.Properties.Name | Sort-Object)실행 의미: class 이름과 기대 test 수를 exact inventory로 고정한다.
30$ActualNames = @($Rows.class | Sort-Object -Unique)실행 의미: Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
31if (Compare-Object $ExpectedNames $ActualNames) {실행 의미: expected와 actual 집합에 누락·예상 밖 항목이 있는지 비교한다.
32 throw 'W24D1 actual XML class set differs from canonical expectation'실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
33}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
34foreach ($Row in $Rows) {실행 의미: 고정 목록의 각 항목에 같은 검사를 반복 적용한다.
35 $ExpectedTests = [int]$Expected.classes.psobject.Properties[$Row.class].Value실행 의미: class 이름과 기대 test 수를 exact inventory로 고정한다.
36 if ($Row.tests -ne $ExpectedTests -or $Row.failures -ne 0 -or $Row.errors -ne 0 -or $Row.skipped -ne 0) {실행 의미: 조건·반복·함수의 실행 block을 연다.
37 throw "W24D1 class/count/status mismatch: $($Row.class)"실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
38 }실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
39}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
41$Tests = ($Rows | Measure-Object tests -Sum).Sum실행 의미: suite별 수치를 전체 합계로 계산한다.
42$Failures = ($Rows | Measure-Object failures -Sum).Sum실행 의미: suite별 수치를 전체 합계로 계산한다.
43$Errors = ($Rows | Measure-Object errors -Sum).Sum실행 의미: suite별 수치를 전체 합계로 계산한다.
44$Skipped = ($Rows | Measure-Object skipped -Sum).Sum실행 의미: suite별 수치를 전체 합계로 계산한다.
45if ($Rows.Count -ne 37 -or $Tests -ne 66 -or $Failures -ne 0 -or $Errors -ne 0 -or $Skipped -ne 0) {실행 의미: 조건·반복·함수의 실행 block을 연다.
46 throw "W24D1 actual aggregate mismatch classes=$($Rows.Count) tests=$Tests"실행 의미: class 이름과 기대 test 수를 exact inventory로 고정한다.
47}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
49$Gate = Get-Content -Raw -LiteralPath $GateText실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
50foreach ($Token in @('CORE_V1_GATE_GREEN', 'classes=37', 'tests=66', 'failures=0', 'errors=0', 'skipped=0')) {실행 의미: class 이름과 기대 test 수를 exact inventory로 고정한다.
51 if ($Gate -cnotmatch [regex]::Escape($Token)) {실행 의미: 조건·반복·함수의 실행 block을 연다.
52 throw "W24D1 gate marker missing: $Token"실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
53 }실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
54}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
56$ExpectedHash = (Get-FileHash -LiteralPath $ExpectedPath -Algorithm SHA256).Hash.ToLowerInvariant()실행 의미: 현재 bytes를 64자리 digest로 evidence에 결박한다.
57$GateHash = (Get-FileHash -LiteralPath $GateText -Algorithm SHA256).Hash.ToLowerInvariant()실행 의미: 현재 bytes를 64자리 digest로 evidence에 결박한다.
58$Lines = @(실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
59 '# W24 test inventory',실행 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
60 'status: GREEN',실행 의미: W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
61 'source: actual coreV1Gate XML',실행 의미: W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
62 "classes: $($Rows.Count)",실행 의미: class 이름과 기대 test 수를 exact inventory로 고정한다.
63 "tests: $Tests",실행 의미: W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
64 "failures: $Failures",실행 의미: W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
65 "errors: $Errors",실행 의미: W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
66 "skipped: $Skipped",실행 의미: W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
67 "expected_sha256: $ExpectedHash",실행 의미: 현재 bytes를 64자리 digest로 evidence에 결박한다.
68 "gate_sha256: $GateHash",실행 의미: 현재 bytes를 64자리 digest로 evidence에 결박한다.
69 '',실행 의미: W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
70 '| class | tests | failures | errors | skipped | xml_sha256 |',실행 의미: 현재 bytes를 64자리 digest로 evidence에 결박한다.
71 '|---|---:|---:|---:|---:|---|'실행 의미: Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
72)실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
73$Lines += @($Rows | Sort-Object class | ForEach-Object {실행 의미: 고정 목록의 각 항목에 같은 검사를 반복 적용한다.
74 "| $($_.class) | $($_.tests) | $($_.failures) | $($_.errors) | $($_.skipped) | $($_.xml_sha256) |"실행 의미: 현재 bytes를 64자리 digest로 evidence에 결박한다.
75})실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
77$Tmp = "$Artifact.tmp"실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
78New-Item -ItemType Directory -Force (Split-Path -Parent $Artifact) | Out-Null실행 의미: Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
79$Lines | Set-Content -Encoding utf8 $Tmp실행 의미: Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
80$Saved = Get-Content -Raw -LiteralPath $Tmp실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
81foreach ($Token in @('source: actual coreV1Gate XML', 'classes: 37', 'tests: 66', 'failures: 0', 'errors: 0', 'skipped: 0', "expected_sha256: $ExpectedHash", "gate_sha256: $GateHash")) {실행 의미: class 이름과 기대 test 수를 exact inventory로 고정한다.
82 if ($Saved -cnotmatch [regex]::Escape($Token)) {실행 의미: 조건·반복·함수의 실행 block을 연다.
83 throw "W24D1 inventory marker missing: $Token"실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
84 }실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
85}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
86Move-Item -Force -LiteralPath $Tmp -Destination $Artifact실행 의미: W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다.
87if (!(Test-Path -LiteralPath $Artifact -PathType Leaf)) {실행 의미: 필수 파일이나 경로가 실제로 있는지 확인한다.
88 throw 'W24D1 atomic inventory move failed'실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
89}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
90$Hash = (Get-FileHash -LiteralPath $Artifact -Algorithm SHA256).Hash.ToLowerInvariant()실행 의미: 현재 bytes를 64자리 digest로 evidence에 결박한다.
91"W24D1_PRIMARY_EVIDENCE_GREEN classes=37 tests=66 failures=0 errors=0 skipped=0 actual_xml=37 sha256=$Hash"실행 의미: class 이름과 기대 test 수를 exact inventory로 고정한다.
07

STEP 07 / 13

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

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

한 줄로 읽기

W24 D1 test inventory — actual XML을 evidence에 원자 저장는 PDF p789의 당일 evidence closure를 가독성 있게 정리해 class별 XML hash와 aggregate를 test-inventory.md에 묶는다.

문법 해부

  • .ps1 문법에서 선언·조건·pipeline·block 경계를 먼저 나눈다.
  • expected 값과 actual 결과를 같은 이름처럼 보여도 서로 다른 source로 읽는다.
  • native exit·row count·hash·사람 판정을 서로 대체하지 않는다.

실행 순서

  1. 입력 경로·fixture·환경변수·expected 계약을 고정한다.
  2. source가 실행하는 native process·HTTP·SQL 또는 형식 검사를 따라간다.
  3. actual 값과 exact marker를 대조하고 실패면 성공 발행 전에 중단한다.
  4. finally cleanup과 비범위를 evidence에 남긴다.

W24 조각별 정밀 해설

F04-C01 · 원문 1–12줄
문법 해부
.ps1 문법으로 1–12줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
actual_xml=37, tests=66, atomic tmp move를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
PDF-only 학습 예시이며 packaged 정본이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
PDF-only 학습 예시이며 packaged 정본이 아니다; 고정 숫자만 적은 문서는 통과하지 않는다; 실제 실행 결과를 주장하지 않는다
다음 연결
다음 조각 또는 F04 evidence 판정으로 상태를 넘긴다.
F04-C02 · 원문 13–24줄
문법 해부
.ps1 문법으로 13–24줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
actual_xml=37, tests=66, atomic tmp move를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
PDF-only 학습 예시이며 packaged 정본이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
PDF-only 학습 예시이며 packaged 정본이 아니다; 고정 숫자만 적은 문서는 통과하지 않는다; 실제 실행 결과를 주장하지 않는다
다음 연결
다음 조각 또는 F04 evidence 판정으로 상태를 넘긴다.
F04-C03 · 원문 25–36줄
문법 해부
.ps1 문법으로 25–36줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
actual_xml=37, tests=66, atomic tmp move를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
PDF-only 학습 예시이며 packaged 정본이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
PDF-only 학습 예시이며 packaged 정본이 아니다; 고정 숫자만 적은 문서는 통과하지 않는다; 실제 실행 결과를 주장하지 않는다
다음 연결
다음 조각 또는 F04 evidence 판정으로 상태를 넘긴다.
F04-C04 · 원문 37–48줄
문법 해부
.ps1 문법으로 37–48줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
actual_xml=37, tests=66, atomic tmp move를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
PDF-only 학습 예시이며 packaged 정본이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
PDF-only 학습 예시이며 packaged 정본이 아니다; 고정 숫자만 적은 문서는 통과하지 않는다; 실제 실행 결과를 주장하지 않는다
다음 연결
다음 조각 또는 F04 evidence 판정으로 상태를 넘긴다.
F04-C05 · 원문 49–60줄
문법 해부
.ps1 문법으로 49–60줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
actual_xml=37, tests=66, atomic tmp move를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
PDF-only 학습 예시이며 packaged 정본이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
PDF-only 학습 예시이며 packaged 정본이 아니다; 고정 숫자만 적은 문서는 통과하지 않는다; 실제 실행 결과를 주장하지 않는다
다음 연결
다음 조각 또는 F04 evidence 판정으로 상태를 넘긴다.
F04-C06 · 원문 61–72줄
문법 해부
.ps1 문법으로 61–72줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
actual_xml=37, tests=66, atomic tmp move를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
PDF-only 학습 예시이며 packaged 정본이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
PDF-only 학습 예시이며 packaged 정본이 아니다; 고정 숫자만 적은 문서는 통과하지 않는다; 실제 실행 결과를 주장하지 않는다
다음 연결
다음 조각 또는 F04 evidence 판정으로 상태를 넘긴다.
F04-C07 · 원문 73–84줄
문법 해부
.ps1 문법으로 73–84줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
actual_xml=37, tests=66, atomic tmp move를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
PDF-only 학습 예시이며 packaged 정본이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
PDF-only 학습 예시이며 packaged 정본이 아니다; 고정 숫자만 적은 문서는 통과하지 않는다; 실제 실행 결과를 주장하지 않는다
다음 연결
다음 조각 또는 F04 evidence 판정으로 상태를 넘긴다.
F04-C08 · 원문 85–91줄
문법 해부
.ps1 문법으로 85–91줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
actual_xml=37, tests=66, atomic tmp move를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
PDF-only 학습 예시이며 packaged 정본이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
PDF-only 학습 예시이며 packaged 정본이 아니다; 고정 숫자만 적은 문서는 통과하지 않는다; 실제 실행 결과를 주장하지 않는다
다음 연결
다음 조각 또는 F04 evidence 판정으로 상태를 넘긴다.
실행 순서 — W24 D1 test inventory — actual XML을 evidence에 원자 저장히토리 → 니지카 → 료 → 키타
  1. 히토리

    tests=66가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 PDF p789의 당일 evidence closure를 가독성 있게 정리해 class별 XML hash와 aggregate를 test-inventory.md에 묶는다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘고정 숫자만 적은 문서는 통과하지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 tests=66와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

08

STEP 08 / 13

실제 값 따라가기

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

순서들어온 값코드가 하는 일나온 값·상태경계
입력actual_xml=37source 계약에 대입F04 실행/설명 시작 상태PDF-only 학습 예시이며 packaged 정본이 아니다
검증tests=66expected와 actual 또는 형식 대조통과 또는 첫 mismatch고정 숫자만 적은 문서는 통과하지 않는다
증거expected/gate SHA-256marker·hash·row를 같은 run에 연결범위가 적힌 evidence 후보실제 실행 결과를 주장하지 않는다
실제 값 — W24 D1 test inventory — actual XML을 evidence에 원자 저장히토리 → 니지카 → 료 → 키타
  1. 히토리

    atomic tmp move가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 PDF p789의 당일 evidence closure를 가독성 있게 정리해 class별 XML hash와 aggregate를 test-inventory.md에 묶는다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘실제 실행 결과를 주장하지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 atomic tmp move와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

09

STEP 09 / 13

Gradle·PowerShell·HTTP·PostgreSQL 내부에서 벌어지는 일

Gradle·JUnit XML·PowerShell·HTTP·PostgreSQL·Docker에서 실제로 일어나는 일과 증명 범위를 구분합니다.

source/contract

W24-D1-primary-evidence-closure.ps1 bytes와 expected 값을 읽는다.

파일 존재만으로 runtime 성공은 아니다.
execution/evidence

native exit·HTTP status·JUnit XML·DB row·hash 중 이 파일이 소유한 값을 만든다.

PDF-only 학습 예시이며 packaged 정본이 아니다
release/human

관련 evidence와 사람 의미 검토를 release 후보에 연결한다.

실제 실행 결과를 주장하지 않는다
첫 실패 경계 — W24 D1 test inventory — actual XML을 evidence에 원자 저장히토리 → 니지카 → 료 → 키타
  1. 히토리

    expected/gate SHA-256가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 PDF p789의 당일 evidence closure를 가독성 있게 정리해 class별 XML hash와 aggregate를 test-inventory.md에 묶는다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘PDF-only 학습 예시이며 packaged 정본이 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 expected/gate SHA-256와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

10

STEP 10 / 13

흔한 착각과 틀린 예

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

❌ actual_xml=37 문자열이 source에 있으니 실제 실행도 Green이다.

왜 틀리나 source literal과 runtime 관찰값은 다른 증거다.

바르게 읽기 native exit·actual XML/HTTP/DB evidence를 별도로 확인한다.

반례 script가 실행 전 경로 오류로 멈춰도 literal은 그대로 남는다.

❌ 파일 SHA-256이 있으면 내용의 의미와 사실성도 검증됐다.

왜 틀리나 hash는 동일 bytes만 말한다.

바르게 읽기 schema·수치·질문·근거는 별도 자동 또는 사람 판정을 거친다.

반례 빈 review 질문을 가진 CSV도 안정된 hash를 가진다.

❌ LOCAL_ARTIFACT_VALIDATED는 release Green과 같다.

왜 틀리나 generic validator는 파일 shape만 확인한다.

바르게 읽기 HUMAN_SEMANTIC_REVIEW_REQUIRED를 유지한다.

반례 잘못된 track 점수표도 byte 수 조건은 통과할 수 있다.

❌ 이 파일이 W24 전체 lifecycle을 모두 소유한다.

왜 틀리나 각 source는 Gate·demo·cleanup·사람 review 중 일부만 담당한다.

바르게 읽기 owner와 non-responsibility를 release manifest에서 분리한다.

반례 D4 source audit에는 runtime_claim=false가 명시된다.

❌ 이전 주 Green이나 오래된 log를 현재 commit 결과로 재사용한다.

왜 틀리나 source·commit·actual result가 같은 실행에 묶이지 않는다.

바르게 읽기 release 후보에서 새 evidence와 hash를 만든다.

반례 expected JSON이 바뀌면 예전 XML은 exact inventory를 증명하지 못한다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

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

증명 범위

PDF-only 학습 예시이며 packaged 정본이 아니다

이 책임을 맡는 곳: runtime Gate
증명 범위

고정 숫자만 적은 문서는 통과하지 않는다

이 책임을 맡는 곳: external/human review
증명 범위

실제 실행 결과를 주장하지 않는다

이 책임을 맡는 곳: release manifest
증명 범위

PDF-only 학습 예시이며 packaged 정본이 아니다

이 책임을 맡는 곳: 운영 환경
증명하지 않는 범위 — W24 D1 test inventory — actual XML을 evidence에 원자 저장히토리 → 니지카 → 료 → 키타
  1. 히토리

    actual_xml=37가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 PDF p789의 당일 evidence closure를 가독성 있게 정리해 class별 XML hash와 aggregate를 test-inventory.md에 묶는다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘고정 숫자만 적은 문서는 통과하지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 actual_xml=37와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

12

STEP 12 / 13

직접 다시 써보기

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

1단계 · 뜻부터 복원

  • PDF p789의 당일 evidence closure를 가독성 있게 정리해 class별 XML hash와 aggregate를 test-inventory.md에 묶는다.
  • 핵심 값은 actual_xml=37, tests=66, atomic tmp move, expected/gate SHA-256다.

2단계 · 코드 조각 재조립

  1. 1. 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다
  2. 2. 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다
  3. 3. 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다
  4. 4. 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다
  5. 5. 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다
  6. 6. 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다
  7. 8. W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다
  8. 9. W24-D1-primary-evidence-closure.ps1의 다음 검증 또는 설명 단계를 구성한다

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

illustrative/powershell/W24-D1-primary-evidence-closure.ps1을 새 파일에 다시 쓰고 expected·actual·실패·cleanup·비범위를 주석으로 표시한다.

자가 점검
  • 비어 있지 않은 모든 source 줄을 한 번씩 읽었나?
  • source shape와 runtime Green을 분리했나?
  • 사람 검토·외부 상태를 자동 성공으로 꾸미지 않았나?
  • 첫 실패와 cleanup 책임을 설명할 수 있나?
13

STEP 13 / 13

전체 원본 source

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

학습용 예시 전체 확인하기 · 정본 답안 아님
학습용 예시 · PDF inline PowerShell · 정본 답안 아님 · 비실행illustrative/powershell/W24-D1-primary-evidence-closure.ps1SHA-256 252c59c67de1729914bad1515bd8384e5a7e08aaa4c27948c44656b4c33108b8
W24 D1 test inventory — actual XML을 evidence에 원자 저장 전체
# W24 PDF p789에서 제공한 당일 Gate를 읽기 좋게 정리한 학습용 예시다.
# packaged reference source가 아니며, 실제 Gradle/JUnit 실행 결과도 아니다.
$PRIMARY_PRODUCER = 1
$Artifact = Join-Path $LearnerRoot 'evidence\w24\test-inventory.md'
$Verifier = Join-Path $ReferenceRoot 'scripts\verify-core-v1-gate.ps1'
$GateText = Join-Path $LearnerRoot 'evidence\w24\core-v1-gate.txt'

& powershell.exe -NoProfile -ExecutionPolicy Bypass -File $Verifier `
  -ProjectRoot $LearnerRoot -EvidencePath $GateText
if ($LASTEXITCODE -ne 0) {
  throw "W24D1 core verifier native exit=$LASTEXITCODE"
}

$ExpectedPath = Join-Path $ReferenceRoot 'learning_stages\w24\overlay\core-v1-expected.json'
$Expected = Get-Content -Raw -LiteralPath $ExpectedPath | ConvertFrom-Json
$ResultDir = Join-Path $LearnerRoot 'build\test-results\coreV1Gate'
$Rows = @(Get-ChildItem -LiteralPath $ResultDir -Filter 'TEST-*.xml' -File | ForEach-Object {
  [xml]$Xml = Get-Content -Raw -LiteralPath $_.FullName
  [pscustomobject]@{
    class = [string]$Xml.testsuite.name
    tests = [int]$Xml.testsuite.tests
    failures = [int]$Xml.testsuite.failures
    errors = [int]$Xml.testsuite.errors
    skipped = [int]$Xml.testsuite.skipped
    xml_sha256 = (Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash.ToLowerInvariant()
  }
})

$ExpectedNames = @($Expected.classes.psobject.Properties.Name | Sort-Object)
$ActualNames = @($Rows.class | Sort-Object -Unique)
if (Compare-Object $ExpectedNames $ActualNames) {
  throw 'W24D1 actual XML class set differs from canonical expectation'
}
foreach ($Row in $Rows) {
  $ExpectedTests = [int]$Expected.classes.psobject.Properties[$Row.class].Value
  if ($Row.tests -ne $ExpectedTests -or $Row.failures -ne 0 -or $Row.errors -ne 0 -or $Row.skipped -ne 0) {
    throw "W24D1 class/count/status mismatch: $($Row.class)"
  }
}

$Tests = ($Rows | Measure-Object tests -Sum).Sum
$Failures = ($Rows | Measure-Object failures -Sum).Sum
$Errors = ($Rows | Measure-Object errors -Sum).Sum
$Skipped = ($Rows | Measure-Object skipped -Sum).Sum
if ($Rows.Count -ne 37 -or $Tests -ne 66 -or $Failures -ne 0 -or $Errors -ne 0 -or $Skipped -ne 0) {
  throw "W24D1 actual aggregate mismatch classes=$($Rows.Count) tests=$Tests"
}

$Gate = Get-Content -Raw -LiteralPath $GateText
foreach ($Token in @('CORE_V1_GATE_GREEN', 'classes=37', 'tests=66', 'failures=0', 'errors=0', 'skipped=0')) {
  if ($Gate -cnotmatch [regex]::Escape($Token)) {
    throw "W24D1 gate marker missing: $Token"
  }
}

$ExpectedHash = (Get-FileHash -LiteralPath $ExpectedPath -Algorithm SHA256).Hash.ToLowerInvariant()
$GateHash = (Get-FileHash -LiteralPath $GateText -Algorithm SHA256).Hash.ToLowerInvariant()
$Lines = @(
  '# W24 test inventory',
  'status: GREEN',
  'source: actual coreV1Gate XML',
  "classes: $($Rows.Count)",
  "tests: $Tests",
  "failures: $Failures",
  "errors: $Errors",
  "skipped: $Skipped",
  "expected_sha256: $ExpectedHash",
  "gate_sha256: $GateHash",
  '',
  '| class | tests | failures | errors | skipped | xml_sha256 |',
  '|---|---:|---:|---:|---:|---|'
)
$Lines += @($Rows | Sort-Object class | ForEach-Object {
  "| $($_.class) | $($_.tests) | $($_.failures) | $($_.errors) | $($_.skipped) | $($_.xml_sha256) |"
})

$Tmp = "$Artifact.tmp"
New-Item -ItemType Directory -Force (Split-Path -Parent $Artifact) | Out-Null
$Lines | Set-Content -Encoding utf8 $Tmp
$Saved = Get-Content -Raw -LiteralPath $Tmp
foreach ($Token in @('source: actual coreV1Gate XML', 'classes: 37', 'tests: 66', 'failures: 0', 'errors: 0', 'skipped: 0', "expected_sha256: $ExpectedHash", "gate_sha256: $GateHash")) {
  if ($Saved -cnotmatch [regex]::Escape($Token)) {
    throw "W24D1 inventory marker missing: $Token"
  }
}
Move-Item -Force -LiteralPath $Tmp -Destination $Artifact
if (!(Test-Path -LiteralPath $Artifact -PathType Leaf)) {
  throw 'W24D1 atomic inventory move failed'
}
$Hash = (Get-FileHash -LiteralPath $Artifact -Algorithm SHA256).Hash.ToLowerInvariant()
"W24D1_PRIMARY_EVIDENCE_GREEN classes=37 tests=66 failures=0 errors=0 skipped=0 actual_xml=37 sha256=$Hash"
05

W24 D2 architecture pack — 정상·실패·중복 sequence와 수동 검토 경계

illustrative/markdown/W24-D2-architecture-pack.md

학습용 예시 · PDF template/validator · 정본 답안 아님 · 학습용 예시 · 정본 답안 아님 · W24-F05
23줄 연결23줄 번역3 chunks
01

STEP 01 / 13

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

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

오늘의 한 문장

ERD와 세 transaction 흐름에 atomic claim, sorted locks, rollback, replay를 배치하고 파일 hash 검사와 의미 검토를 분리한다.

  1. from=10000은 어느 source와 실제 결과에서 확인해야 할까?
  2. 첫 실패를 만드는 조건과 fail-closed 지점은 어디일까?
  3. 왜 ‘architecture-pack.pdf 완성본이 아니다’를 별도 경계로 남겨야 할까?
이 파일에서 끝까지 다시 쓰는 값from=10000to=5000amount=1000same payload replaydifferent hash=409
왜 필요한가 — W24 D2 architecture pack — 정상·실패·중복 sequence와 수동 검토 경계히토리 → 니지카 → 료 → 키타
  1. 히토리

    from=10000가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 ERD와 세 transaction 흐름에 atomic claim, sorted locks, rollback, replay를 배치하고 파일 hash 검사와 의미 검토를 분리한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘architecture-pack.pdf 완성본이 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 from=10000와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

02

STEP 02 / 13

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

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

새 기능을 멈춘 팀이 코드·test·문서·demo를 같은 release 후보에 묶어 하나씩 검수한다.

검수 도장이 붙은 공통 거래 코어 출고 상자

이 파일은 ERD와 세 transaction 흐름에 atomic claim, sorted locks, rollback, replay를 배치하고 파일 hash 검사와 의미 검토를 분리한다. 눈으로 읽을 때는 각 줄을 검수표 한 칸처럼 보고, 입력과 다음 상태를 놓치지 않는다.

마지막 도장은 source shape와 실제 runtime·사람 검토를 구분한 뒤에만 찍는다. 특히 architecture-pack.pdf 완성본이 아니다

딱 여기까지만 비유는 실행 순서를 돕지만 실제 Gradle·Docker·DB·사람 review를 대신하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

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

값 1: from=10000

이 파일에서 계속 확인할 고정 단서가 from=10000다.

코드 연결
F05 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
architecture-pack.pdf 완성본이 아니다

값 2: to=5000

이 파일에서 계속 확인할 고정 단서가 to=5000다.

코드 연결
F05 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
MANUAL_REVIEW_REQUIRED는 Green이 아니다

값 3: amount=1000

이 파일에서 계속 확인할 고정 단서가 amount=1000다.

코드 연결
F05 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
실은행 GL·HA는 범위 밖이다

값 4: same payload replay

이 파일에서 계속 확인할 고정 단서가 same payload replay다.

코드 연결
F05 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
architecture-pack.pdf 완성본이 아니다

값 5: different hash=409

이 파일에서 계속 확인할 고정 단서가 different hash=409다.

코드 연결
F05 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
MANUAL_REVIEW_REQUIRED는 Green이 아니다
04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

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

단어 몇 개만 뽑은 표가 아닙니다.학습용 예시 · PDF template/validator · 정본 답안 아님에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.23 / 23 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F05-L01 # W24 D2 architecture pack 학습 골격 출고표 1번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F05-001가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
architecture-pack.pdf 완성본이 아니다
3줄F05-L03 > PDF p792의 TEMPLATE와 validator를 한 파일에 모은 학습용 예시다. 완성 architecture-pack.pdf도, 사람 의미 검토 결과도 아니다. 출고표 3번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D2-architecture-pack.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F05-003가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실은행 GL·HA는 범위 밖이다
5줄F05-L05 ## Sequence 핵심 출고표 5번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F05-005가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
MANUAL_REVIEW_REQUIRED는 Green이 아니다
7줄F05-L07 Request -> RequestIdFilter -> Authorization -> AtomicClaim 출고표 7번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 인증 header를 runtime에서 만들되 evidence에 원문 비밀을 남기지 않는다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F05-007가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
architecture-pack.pdf 완성본이 아니다
8줄F05-L08 owner -> sorted account locks -> debit/credit -> ledger pair -> COMPLETE -> COMMIT -> response 출고표 8번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D2-architecture-pack.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F05-008가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
MANUAL_REVIEW_REQUIRED는 Green이 아니다
9줄F05-L09 existing same hash COMPLETE -> replay stored response 출고표 9번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D2-architecture-pack.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F05-009가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실은행 GL·HA는 범위 밖이다
10줄F05-L10 different hash -> 409 no state change 출고표 10번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D2-architecture-pack.md의 다음 검증 또는 설명 단계를 구성한다.
입력
409
결과·효과
관찰 상태 F05-010가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
architecture-pack.pdf 완성본이 아니다
12줄F05-L12 ## 학습자 산출물 검사 출고표 12번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F05-012가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실은행 GL·HA는 범위 밖이다
14줄F05-L14 $Artifact = Join-Path $LearnerRoot 'evidence\w24\architecture-pack.pdf' 출고표 14번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Artifact, $LearnerRoot, 'evidence\w24\architecture-pack.pdf'
결과·효과
관찰 상태 F05-014가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
MANUAL_REVIEW_REQUIRED는 Green이 아니다
15줄F05-L15 if (!(Test-Path -LiteralPath $Artifact -PathType Leaf)) { 출고표 15번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 필수 파일이나 경로가 실제로 있는지 확인한다.
입력
$Artifact
결과·효과
관찰 상태 F05-015가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실은행 GL·HA는 범위 밖이다
16줄F05-L16 throw "learner artifact missing: $Artifact" 출고표 16번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
"learner artifact missing: $Artifact"
결과·효과
관찰 상태 F05-016가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
architecture-pack.pdf 완성본이 아니다
17줄F05-L17 } 출고표 17번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F05-017가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
MANUAL_REVIEW_REQUIRED는 Green이 아니다
18줄F05-L18 $Item = Get-Item -LiteralPath $Artifact 출고표 18번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Item, $Artifact
결과·효과
관찰 상태 F05-018가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실은행 GL·HA는 범위 밖이다
19줄F05-L19 if ($Item.Length -lt 128) { 출고표 19번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$Item, 128
결과·효과
관찰 상태 F05-019가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
architecture-pack.pdf 완성본이 아니다
20줄F05-L20 throw "artifact is too small to support the claim: bytes=$($Item.Length)" 출고표 20번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
$Item
결과·효과
관찰 상태 F05-020가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
MANUAL_REVIEW_REQUIRED는 Green이 아니다
21줄F05-L21 } 출고표 21번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F05-021가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실은행 GL·HA는 범위 밖이다
22줄F05-L22 $Hash = (Get-FileHash -LiteralPath $Artifact -Algorithm SHA256).Hash.ToLowerInvariant() 출고표 22번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 현재 bytes를 64자리 digest로 evidence에 결박한다.
입력
$Hash, $Artifact
결과·효과
관찰 상태 F05-022가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
architecture-pack.pdf 완성본이 아니다
23줄F05-L23 "MANUAL_REVIEW_REQUIRED W24D2 bytes=$($Item.Length) sha256=$Hash" 출고표 23번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 자동 검사가 내용의 의미를 판정하지 못해 사람 검토가 남았음을 표시한다.
입력
$Item, $Hash
결과·효과
관찰 상태 F05-023가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
MANUAL_REVIEW_REQUIRED는 Green이 아니다
25줄F05-L25 ## 사람 확인이 남는 이유 출고표 25번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F05-025가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
architecture-pack.pdf 완성본이 아니다
27줄F05-L27 - 이 검사는 파일 존재·최소 크기·hash만 본다. 출고표 27번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D2-architecture-pack.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F05-027가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실은행 GL·HA는 범위 밖이다
28줄F05-L28 - ERD가 실제 V001/V002+ migration과 같은지 자동으로 증명하지 않는다. 출고표 28번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D2-architecture-pack.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F05-028가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
architecture-pack.pdf 완성본이 아니다
29줄F05-L29 - 정상·중간 실패·동시 중복 sequence의 lock order, atomic claim, commit/rollback, replay 의미는 사람이 대조한다. 출고표 29번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D2-architecture-pack.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F05-029가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
MANUAL_REVIEW_REQUIRED는 Green이 아니다
30줄F05-L30 - 실은행 GL, 결제망, HA, 운영 용량은 이 산출물의 범위 밖이다. 출고표 30번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D2-architecture-pack.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F05-030가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실은행 GL·HA는 범위 밖이다
05

STEP 05 / 13

원본 코드 조각

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

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

F05-C01 · 원문 1–12줄1–12줄
1–12줄 원본
# W24 D2 architecture pack 학습 골격

> PDF p792의 TEMPLATE와 validator를 한 파일에 모은 학습용 예시다. 완성 architecture-pack.pdf도, 사람 의미 검토 결과도 아니다.

## Sequence 핵심

Request -> RequestIdFilter -> Authorization -> AtomicClaim
owner -> sorted account locks -> debit/credit -> ledger pair -> COMPLETE -> COMMIT -> response
existing same hash COMPLETE -> replay stored response
different hash -> 409 no state change

## 학습자 산출물 검사
F05-C02 · 원문 13–24줄13–24줄
13–24줄 원본

    $Artifact = Join-Path $LearnerRoot 'evidence\w24\architecture-pack.pdf'
    if (!(Test-Path -LiteralPath $Artifact -PathType Leaf)) {
      throw "learner artifact missing: $Artifact"
    }
    $Item = Get-Item -LiteralPath $Artifact
    if ($Item.Length -lt 128) {
      throw "artifact is too small to support the claim: bytes=$($Item.Length)"
    }
    $Hash = (Get-FileHash -LiteralPath $Artifact -Algorithm SHA256).Hash.ToLowerInvariant()
    "MANUAL_REVIEW_REQUIRED W24D2 bytes=$($Item.Length) sha256=$Hash"
F05-C03 · 원문 25–30줄25–30줄
25–30줄 원본
## 사람 확인이 남는 이유

- 이 검사는 파일 존재·최소 크기·hash만 본다.
- ERD가 실제 V001/V002+ migration과 같은지 자동으로 증명하지 않는다.
- 정상·중간 실패·동시 중복 sequence의 lock order, atomic claim, commit/rollback, replay 의미는 사람이 대조한다.
- 실은행 GL, 결제망, HA, 운영 용량은 이 산출물의 범위 밖이다.
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

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

전체 번역 23 / 23

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

원본한국어 번역
1# W24 D2 architecture pack 학습 골격문서 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
3> PDF p792의 TEMPLATE와 validator를 한 파일에 모은 학습용 예시다. 완성 architecture-pack.pdf도, 사람 의미 검토 결과도 아니다.문서 의미: W24-D2-architecture-pack.md의 다음 검증 또는 설명 단계를 구성한다.
5## Sequence 핵심문서 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
7Request -> RequestIdFilter -> Authorization -> AtomicClaim문서 의미: 인증 header를 runtime에서 만들되 evidence에 원문 비밀을 남기지 않는다.
8owner -> sorted account locks -> debit/credit -> ledger pair -> COMPLETE -> COMMIT -> response문서 의미: W24-D2-architecture-pack.md의 다음 검증 또는 설명 단계를 구성한다.
9existing same hash COMPLETE -> replay stored response문서 의미: W24-D2-architecture-pack.md의 다음 검증 또는 설명 단계를 구성한다.
10different hash -> 409 no state change문서 의미: W24-D2-architecture-pack.md의 다음 검증 또는 설명 단계를 구성한다.
12## 학습자 산출물 검사문서 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
14 $Artifact = Join-Path $LearnerRoot 'evidence\w24\architecture-pack.pdf'문서 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
15 if (!(Test-Path -LiteralPath $Artifact -PathType Leaf)) {문서 의미: 필수 파일이나 경로가 실제로 있는지 확인한다.
16 throw "learner artifact missing: $Artifact"문서 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
17 }문서 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
18 $Item = Get-Item -LiteralPath $Artifact문서 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
19 if ($Item.Length -lt 128) {문서 의미: 조건·반복·함수의 실행 block을 연다.
20 throw "artifact is too small to support the claim: bytes=$($Item.Length)"문서 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
21 }문서 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
22 $Hash = (Get-FileHash -LiteralPath $Artifact -Algorithm SHA256).Hash.ToLowerInvariant()문서 의미: 현재 bytes를 64자리 digest로 evidence에 결박한다.
23 "MANUAL_REVIEW_REQUIRED W24D2 bytes=$($Item.Length) sha256=$Hash"문서 의미: 자동 검사가 내용의 의미를 판정하지 못해 사람 검토가 남았음을 표시한다.
25## 사람 확인이 남는 이유문서 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
27- 이 검사는 파일 존재·최소 크기·hash만 본다.문서 의미: W24-D2-architecture-pack.md의 다음 검증 또는 설명 단계를 구성한다.
28- ERD가 실제 V001/V002+ migration과 같은지 자동으로 증명하지 않는다.문서 의미: W24-D2-architecture-pack.md의 다음 검증 또는 설명 단계를 구성한다.
29- 정상·중간 실패·동시 중복 sequence의 lock order, atomic claim, commit/rollback, replay 의미는 사람이 대조한다.문서 의미: W24-D2-architecture-pack.md의 다음 검증 또는 설명 단계를 구성한다.
30- 실은행 GL, 결제망, HA, 운영 용량은 이 산출물의 범위 밖이다.문서 의미: W24-D2-architecture-pack.md의 다음 검증 또는 설명 단계를 구성한다.
07

STEP 07 / 13

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

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

한 줄로 읽기

W24 D2 architecture pack — 정상·실패·중복 sequence와 수동 검토 경계는 ERD와 세 transaction 흐름에 atomic claim, sorted locks, rollback, replay를 배치하고 파일 hash 검사와 의미 검토를 분리한다.

문법 해부

  • .md 문법에서 선언·조건·pipeline·block 경계를 먼저 나눈다.
  • expected 값과 actual 결과를 같은 이름처럼 보여도 서로 다른 source로 읽는다.
  • native exit·row count·hash·사람 판정을 서로 대체하지 않는다.

실행 순서

  1. 입력 경로·fixture·환경변수·expected 계약을 고정한다.
  2. source가 실행하는 native process·HTTP·SQL 또는 형식 검사를 따라간다.
  3. actual 값과 exact marker를 대조하고 실패면 성공 발행 전에 중단한다.
  4. finally cleanup과 비범위를 evidence에 남긴다.

W24 조각별 정밀 해설

F05-C01 · 원문 1–12줄
문법 해부
.md 문법으로 1–12줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
from=10000, to=5000, amount=1000를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
architecture-pack.pdf 완성본이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
architecture-pack.pdf 완성본이 아니다; MANUAL_REVIEW_REQUIRED는 Green이 아니다; 실은행 GL·HA는 범위 밖이다
다음 연결
다음 조각 또는 F05 evidence 판정으로 상태를 넘긴다.
F05-C02 · 원문 13–24줄
문법 해부
.md 문법으로 13–24줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
from=10000, to=5000, amount=1000를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
architecture-pack.pdf 완성본이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
architecture-pack.pdf 완성본이 아니다; MANUAL_REVIEW_REQUIRED는 Green이 아니다; 실은행 GL·HA는 범위 밖이다
다음 연결
다음 조각 또는 F05 evidence 판정으로 상태를 넘긴다.
F05-C03 · 원문 25–30줄
문법 해부
.md 문법으로 25–30줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
from=10000, to=5000, amount=1000를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
architecture-pack.pdf 완성본이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
architecture-pack.pdf 완성본이 아니다; MANUAL_REVIEW_REQUIRED는 Green이 아니다; 실은행 GL·HA는 범위 밖이다
다음 연결
다음 조각 또는 F05 evidence 판정으로 상태를 넘긴다.
실행 순서 — W24 D2 architecture pack — 정상·실패·중복 sequence와 수동 검토 경계히토리 → 니지카 → 료 → 키타
  1. 히토리

    to=5000가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 ERD와 세 transaction 흐름에 atomic claim, sorted locks, rollback, replay를 배치하고 파일 hash 검사와 의미 검토를 분리한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘MANUAL_REVIEW_REQUIRED는 Green이 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 to=5000와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

08

STEP 08 / 13

실제 값 따라가기

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

순서들어온 값코드가 하는 일나온 값·상태경계
입력from=10000source 계약에 대입F05 실행/설명 시작 상태architecture-pack.pdf 완성본이 아니다
검증to=5000expected와 actual 또는 형식 대조통과 또는 첫 mismatchMANUAL_REVIEW_REQUIRED는 Green이 아니다
증거different hash=409marker·hash·row를 같은 run에 연결범위가 적힌 evidence 후보실은행 GL·HA는 범위 밖이다
실제 값 — W24 D2 architecture pack — 정상·실패·중복 sequence와 수동 검토 경계히토리 → 니지카 → 료 → 키타
  1. 히토리

    amount=1000가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 ERD와 세 transaction 흐름에 atomic claim, sorted locks, rollback, replay를 배치하고 파일 hash 검사와 의미 검토를 분리한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘실은행 GL·HA는 범위 밖이다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 amount=1000와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

09

STEP 09 / 13

Gradle·PowerShell·HTTP·PostgreSQL 내부에서 벌어지는 일

Gradle·JUnit XML·PowerShell·HTTP·PostgreSQL·Docker에서 실제로 일어나는 일과 증명 범위를 구분합니다.

source/contract

W24-D2-architecture-pack.md bytes와 expected 값을 읽는다.

파일 존재만으로 runtime 성공은 아니다.
execution/evidence

native exit·HTTP status·JUnit XML·DB row·hash 중 이 파일이 소유한 값을 만든다.

architecture-pack.pdf 완성본이 아니다
release/human

관련 evidence와 사람 의미 검토를 release 후보에 연결한다.

실은행 GL·HA는 범위 밖이다
첫 실패 경계 — W24 D2 architecture pack — 정상·실패·중복 sequence와 수동 검토 경계히토리 → 니지카 → 료 → 키타
  1. 히토리

    same payload replay가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 ERD와 세 transaction 흐름에 atomic claim, sorted locks, rollback, replay를 배치하고 파일 hash 검사와 의미 검토를 분리한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘architecture-pack.pdf 완성본이 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 same payload replay와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

10

STEP 10 / 13

흔한 착각과 틀린 예

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

❌ from=10000 문자열이 source에 있으니 실제 실행도 Green이다.

왜 틀리나 source literal과 runtime 관찰값은 다른 증거다.

바르게 읽기 native exit·actual XML/HTTP/DB evidence를 별도로 확인한다.

반례 script가 실행 전 경로 오류로 멈춰도 literal은 그대로 남는다.

❌ 파일 SHA-256이 있으면 내용의 의미와 사실성도 검증됐다.

왜 틀리나 hash는 동일 bytes만 말한다.

바르게 읽기 schema·수치·질문·근거는 별도 자동 또는 사람 판정을 거친다.

반례 빈 review 질문을 가진 CSV도 안정된 hash를 가진다.

❌ LOCAL_ARTIFACT_VALIDATED는 release Green과 같다.

왜 틀리나 generic validator는 파일 shape만 확인한다.

바르게 읽기 HUMAN_SEMANTIC_REVIEW_REQUIRED를 유지한다.

반례 잘못된 track 점수표도 byte 수 조건은 통과할 수 있다.

❌ 이 파일이 W24 전체 lifecycle을 모두 소유한다.

왜 틀리나 각 source는 Gate·demo·cleanup·사람 review 중 일부만 담당한다.

바르게 읽기 owner와 non-responsibility를 release manifest에서 분리한다.

반례 D4 source audit에는 runtime_claim=false가 명시된다.

❌ 이전 주 Green이나 오래된 log를 현재 commit 결과로 재사용한다.

왜 틀리나 source·commit·actual result가 같은 실행에 묶이지 않는다.

바르게 읽기 release 후보에서 새 evidence와 hash를 만든다.

반례 expected JSON이 바뀌면 예전 XML은 exact inventory를 증명하지 못한다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

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

증명 범위

architecture-pack.pdf 완성본이 아니다

이 책임을 맡는 곳: runtime Gate
증명 범위

MANUAL_REVIEW_REQUIRED는 Green이 아니다

이 책임을 맡는 곳: external/human review
증명 범위

실은행 GL·HA는 범위 밖이다

이 책임을 맡는 곳: release manifest
증명 범위

architecture-pack.pdf 완성본이 아니다

이 책임을 맡는 곳: 운영 환경
증명하지 않는 범위 — W24 D2 architecture pack — 정상·실패·중복 sequence와 수동 검토 경계히토리 → 니지카 → 료 → 키타
  1. 히토리

    different hash=409가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 ERD와 세 transaction 흐름에 atomic claim, sorted locks, rollback, replay를 배치하고 파일 hash 검사와 의미 검토를 분리한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘MANUAL_REVIEW_REQUIRED는 Green이 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 different hash=409와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

12

STEP 12 / 13

직접 다시 써보기

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

1단계 · 뜻부터 복원

  • ERD와 세 transaction 흐름에 atomic claim, sorted locks, rollback, replay를 배치하고 파일 hash 검사와 의미 검토를 분리한다.
  • 핵심 값은 from=10000, to=5000, amount=1000, same payload replay, different hash=409다.

2단계 · 코드 조각 재조립

  1. 1. 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다
  2. 3. W24-D2-architecture-pack.md의 다음 검증 또는 설명 단계를 구성한다
  3. 5. 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다
  4. 7. 인증 header를 runtime에서 만들되 evidence에 원문 비밀을 남기지 않는다
  5. 8. W24-D2-architecture-pack.md의 다음 검증 또는 설명 단계를 구성한다
  6. 9. W24-D2-architecture-pack.md의 다음 검증 또는 설명 단계를 구성한다
  7. 10. W24-D2-architecture-pack.md의 다음 검증 또는 설명 단계를 구성한다
  8. 12. 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다

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

illustrative/markdown/W24-D2-architecture-pack.md을 새 파일에 다시 쓰고 expected·actual·실패·cleanup·비범위를 주석으로 표시한다.

자가 점검
  • 비어 있지 않은 모든 source 줄을 한 번씩 읽었나?
  • source shape와 runtime Green을 분리했나?
  • 사람 검토·외부 상태를 자동 성공으로 꾸미지 않았나?
  • 첫 실패와 cleanup 책임을 설명할 수 있나?
13

STEP 13 / 13

전체 원본 source

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

학습용 예시 전체 확인하기 · 정본 답안 아님
학습용 예시 · PDF template/validator · 정본 답안 아님illustrative/markdown/W24-D2-architecture-pack.mdSHA-256 6307231731bdf72ee393a4aaf82396ed6d9de3ad1f8fdf4c037a810540828efa
W24 D2 architecture pack — 정상·실패·중복 sequence와 수동 검토 경계 전체
# W24 D2 architecture pack 학습 골격

> PDF p792의 TEMPLATE와 validator를 한 파일에 모은 학습용 예시다. 완성 architecture-pack.pdf도, 사람 의미 검토 결과도 아니다.

## Sequence 핵심

Request -> RequestIdFilter -> Authorization -> AtomicClaim
owner -> sorted account locks -> debit/credit -> ledger pair -> COMPLETE -> COMMIT -> response
existing same hash COMPLETE -> replay stored response
different hash -> 409 no state change

## 학습자 산출물 검사

    $Artifact = Join-Path $LearnerRoot 'evidence\w24\architecture-pack.pdf'
    if (!(Test-Path -LiteralPath $Artifact -PathType Leaf)) {
      throw "learner artifact missing: $Artifact"
    }
    $Item = Get-Item -LiteralPath $Artifact
    if ($Item.Length -lt 128) {
      throw "artifact is too small to support the claim: bytes=$($Item.Length)"
    }
    $Hash = (Get-FileHash -LiteralPath $Artifact -Algorithm SHA256).Hash.ToLowerInvariant()
    "MANUAL_REVIEW_REQUIRED W24D2 bytes=$($Item.Length) sha256=$Hash"

## 사람 확인이 남는 이유

- 이 검사는 파일 존재·최소 크기·hash만 본다.
- ERD가 실제 V001/V002+ migration과 같은지 자동으로 증명하지 않는다.
- 정상·중간 실패·동시 중복 sequence의 lock order, atomic claim, commit/rollback, replay 의미는 사람이 대조한다.
- 실은행 GL, 결제망, HA, 운영 용량은 이 산출물의 범위 밖이다.
06

W24 D3 README — 위험·선택·검증·결과·한계 연결

illustrative/markdown/W24-D3-readme-evidence.md

학습용 예시 · PDF template/validator · 정본 답안 아님 · 학습용 예시 · 정본 답안 아님 · W24-F06
31줄 연결31줄 번역4 chunks
01

STEP 01 / 13

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

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

오늘의 한 문장

기능 나열 대신 일곱 위험을 evidence path와 test envelope에 연결하는 README 골격과 형식 validator를 보여 준다.

  1. SQLSTATE 40P01은 어느 source와 실제 결과에서 확인해야 할까?
  2. 첫 실패를 만드는 조건과 fail-closed 지점은 어디일까?
  3. 왜 ‘학습자 README 완성본이 아니다’를 별도 경계로 남겨야 할까?
이 파일에서 끝까지 다시 쓰는 값SQLSTATE 40P01SortedLockTransferIT100 reverse runsLOCAL_ARTIFACT_VALIDATED
왜 필요한가 — W24 D3 README — 위험·선택·검증·결과·한계 연결히토리 → 니지카 → 료 → 키타
  1. 히토리

    SQLSTATE 40P01가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 기능 나열 대신 일곱 위험을 evidence path와 test envelope에 연결하는 README 골격과 형식 validator를 보여 준다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘학습자 README 완성본이 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 SQLSTATE 40P01와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

02

STEP 02 / 13

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

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

새 기능을 멈춘 팀이 코드·test·문서·demo를 같은 release 후보에 묶어 하나씩 검수한다.

검수 도장이 붙은 공통 거래 코어 출고 상자

이 파일은 기능 나열 대신 일곱 위험을 evidence path와 test envelope에 연결하는 README 골격과 형식 validator를 보여 준다. 눈으로 읽을 때는 각 줄을 검수표 한 칸처럼 보고, 입력과 다음 상태를 놓치지 않는다.

마지막 도장은 source shape와 실제 runtime·사람 검토를 구분한 뒤에만 찍는다. 특히 학습자 README 완성본이 아니다

딱 여기까지만 비유는 실행 순서를 돕지만 실제 Gradle·Docker·DB·사람 review를 대신하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

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

값 1: SQLSTATE 40P01

이 파일에서 계속 확인할 고정 단서가 SQLSTATE 40P01다.

코드 연결
F06 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
학습자 README 완성본이 아니다

값 2: SortedLockTransferIT

이 파일에서 계속 확인할 고정 단서가 SortedLockTransferIT다.

코드 연결
F06 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
hash는 내용의 진실성을 증명하지 않는다

값 3: 100 reverse runs

이 파일에서 계속 확인할 고정 단서가 100 reverse runs다.

코드 연결
F06 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
운영 용량 보장이 아니다

값 4: LOCAL_ARTIFACT_VALIDATED

이 파일에서 계속 확인할 고정 단서가 LOCAL_ARTIFACT_VALIDATED다.

코드 연결
F06 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
학습자 README 완성본이 아니다
04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

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

단어 몇 개만 뽑은 표가 아닙니다.학습용 예시 · PDF template/validator · 정본 답안 아님에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.31 / 31 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F06-L01 # W24 D3 README 학습 골격 출고표 1번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
이전 줄의 상태와 SQLSTATE 40P01
결과·효과
관찰 상태 F06-001가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
학습자 README 완성본이 아니다
3줄F06-L03 > PDF p794–795의 TEMPLATE와 validator를 한 파일에 모은 학습용 예시다. 학습자 README 완성본이나 의미 Green이 아니다. 출고표 3번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 SQLSTATE 40P01
결과·효과
관찰 상태 F06-003가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
운영 용량 보장이 아니다
5줄F06-L05 ## Risk: concurrent reverse transfers 출고표 5번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
이전 줄의 상태와 SQLSTATE 40P01
결과·효과
관찰 상태 F06-005가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
hash는 내용의 진실성을 증명하지 않는다
7줄F06-L07 - Failure before: cyclic lock order produced SQLSTATE 40P01 출고표 7번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 SQLSTATE 40P01
결과·효과
관찰 상태 F06-007가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
학습자 README 완성본이 아니다
8줄F06-L08 - Choice: canonical sorted account lock order 출고표 8번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 SQLSTATE 40P01
결과·효과
관찰 상태 F06-008가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
hash는 내용의 진실성을 증명하지 않는다
9줄F06-L09 - Verification: SortedLockTransferIT, 100 reverse runs 출고표 9번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다.
입력
100
결과·효과
관찰 상태 F06-009가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
운영 용량 보장이 아니다
10줄F06-L10 - Result: deadlock 0 within documented test envelope 출고표 10번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다.
입력
0
결과·효과
관찰 상태 F06-010가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
학습자 README 완성본이 아니다
11줄F06-L11 - Limitation: local PostgreSQL 17.10, not production capacity 출고표 11번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다.
입력
17, 10
결과·효과
관찰 상태 F06-011가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
hash는 내용의 진실성을 증명하지 않는다
13줄F06-L13 ## 학습자 산출물 검사 출고표 13번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
이전 줄의 상태와 SQLSTATE 40P01
결과·효과
관찰 상태 F06-013가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
학습자 README 완성본이 아니다
15줄F06-L15 $Artifact = Join-Path $LearnerRoot 'README.md' 출고표 15번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Artifact, $LearnerRoot, 'README.md'
결과·효과
관찰 상태 F06-015가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
운영 용량 보장이 아니다
16줄F06-L16 if (!(Test-Path -LiteralPath $Artifact -PathType Leaf)) { 출고표 16번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 필수 파일이나 경로가 실제로 있는지 확인한다.
입력
$Artifact
결과·효과
관찰 상태 F06-016가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
학습자 README 완성본이 아니다
17줄F06-L17 throw "learner artifact missing: $Artifact" 출고표 17번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
"learner artifact missing: $Artifact"
결과·효과
관찰 상태 F06-017가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
hash는 내용의 진실성을 증명하지 않는다
18줄F06-L18 } 출고표 18번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 SQLSTATE 40P01
결과·효과
관찰 상태 F06-018가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
운영 용량 보장이 아니다
19줄F06-L19 $Item = Get-Item -LiteralPath $Artifact 출고표 19번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Item, $Artifact
결과·효과
관찰 상태 F06-019가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
학습자 README 완성본이 아니다
20줄F06-L20 if ($Item.Length -lt 40) { 출고표 20번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$Item, 40
결과·효과
관찰 상태 F06-020가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
hash는 내용의 진실성을 증명하지 않는다
21줄F06-L21 throw "artifact is too small to support the claim: bytes=$($Item.Length)" 출고표 21번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
$Item
결과·효과
관찰 상태 F06-021가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
운영 용량 보장이 아니다
22줄F06-L22 } 출고표 22번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 SQLSTATE 40P01
결과·효과
관찰 상태 F06-022가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
학습자 README 완성본이 아니다
23줄F06-L23 $Text = Get-Content -LiteralPath $Artifact -Raw 출고표 23번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Text, $Artifact
결과·효과
관찰 상태 F06-023가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
hash는 내용의 진실성을 증명하지 않는다
24줄F06-L24 if ($Text -match '(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b') { 출고표 24번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
입력
$Text, '(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b'
결과·효과
관찰 상태 F06-024가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
운영 용량 보장이 아니다
25줄F06-L25 throw 'unresolved placeholder in learner artifact' 출고표 25번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
이전 줄의 상태와 SQLSTATE 40P01
결과·효과
관찰 상태 F06-025가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
학습자 README 완성본이 아니다
26줄F06-L26 } 출고표 26번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 SQLSTATE 40P01
결과·효과
관찰 상태 F06-026가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
hash는 내용의 진실성을 증명하지 않는다
27줄F06-L27 $NonBlank = @($Text -split '[\r\n]+' | Where-Object { $_.Trim().Length -gt 0 }) 출고표 27번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건을 만족하는 row만 필터링한다.
입력
$NonBlank, $Text, '[\r\n]+'
결과·효과
관찰 상태 F06-027가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
운영 용량 보장이 아니다
28줄F06-L28 if ($NonBlank.Count -lt 3) { 출고표 28번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$NonBlank, 3
결과·효과
관찰 상태 F06-028가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
학습자 README 완성본이 아니다
29줄F06-L29 throw "artifact needs at least three nonblank evidence lines: $($NonBlank.Count)" 출고표 29번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
$NonBlank
결과·효과
관찰 상태 F06-029가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
hash는 내용의 진실성을 증명하지 않는다
30줄F06-L30 } 출고표 30번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 SQLSTATE 40P01
결과·효과
관찰 상태 F06-030가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
운영 용량 보장이 아니다
31줄F06-L31 $Hash = (Get-FileHash -LiteralPath $Artifact -Algorithm SHA256).Hash.ToLowerInvariant() 출고표 31번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 현재 bytes를 64자리 digest로 evidence에 결박한다.
입력
$Hash, $Artifact
결과·효과
관찰 상태 F06-031가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
학습자 README 완성본이 아니다
32줄F06-L32 "LOCAL_ARTIFACT_VALIDATED W24D3 bytes=$($Item.Length) sha256=$Hash" 출고표 32번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 파일 bytes·기본 형식·hash만 통과한 보조 marker를 낸다.
입력
$Item, $Hash
결과·효과
관찰 상태 F06-032가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
hash는 내용의 진실성을 증명하지 않는다
34줄F06-L34 ## 경계 출고표 34번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
이전 줄의 상태와 SQLSTATE 40P01
결과·효과
관찰 상태 F06-034가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
학습자 README 완성본이 아니다
36줄F06-L36 - LOCAL_ARTIFACT_VALIDATED는 bytes·placeholder·비공백 줄·hash만 확인한다. 출고표 36번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 파일 bytes·기본 형식·hash만 통과한 보조 marker를 낸다.
입력
이전 줄의 상태와 SQLSTATE 40P01
결과·효과
관찰 상태 F06-036가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
운영 용량 보장이 아니다
37줄F06-L37 - 원자성·잠금·멱등·대사·query·보안·운영의 위험-선택-test-결과-한계 연결은 사람이 읽는다. 출고표 37번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 SQLSTATE 40P01
결과·효과
관찰 상태 F06-037가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
학습자 README 완성본이 아니다
38줄F06-L38 - 실행하지 않은 환경 수치를 운영 보장으로 확대하지 않는다. 출고표 38번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 SQLSTATE 40P01
결과·효과
관찰 상태 F06-038가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
hash는 내용의 진실성을 증명하지 않는다
05

STEP 05 / 13

원본 코드 조각

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

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

F06-C01 · 원문 1–12줄1–12줄
1–12줄 원본
# W24 D3 README 학습 골격

> PDF p794–795의 TEMPLATE와 validator를 한 파일에 모은 학습용 예시다. 학습자 README 완성본이나 의미 Green이 아니다.

## Risk: concurrent reverse transfers

- Failure before: cyclic lock order produced SQLSTATE 40P01
- Choice: canonical sorted account lock order
- Verification: SortedLockTransferIT, 100 reverse runs
- Result: deadlock 0 within documented test envelope
- Limitation: local PostgreSQL 17.10, not production capacity
F06-C02 · 원문 13–24줄13–24줄
13–24줄 원본
## 학습자 산출물 검사

    $Artifact = Join-Path $LearnerRoot 'README.md'
    if (!(Test-Path -LiteralPath $Artifact -PathType Leaf)) {
      throw "learner artifact missing: $Artifact"
    }
    $Item = Get-Item -LiteralPath $Artifact
    if ($Item.Length -lt 40) {
      throw "artifact is too small to support the claim: bytes=$($Item.Length)"
    }
    $Text = Get-Content -LiteralPath $Artifact -Raw
    if ($Text -match '(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b') {
F06-C03 · 원문 25–36줄25–36줄
25–36줄 원본
      throw 'unresolved placeholder in learner artifact'
    }
    $NonBlank = @($Text -split '[\r\n]+' | Where-Object { $_.Trim().Length -gt 0 })
    if ($NonBlank.Count -lt 3) {
      throw "artifact needs at least three nonblank evidence lines: $($NonBlank.Count)"
    }
    $Hash = (Get-FileHash -LiteralPath $Artifact -Algorithm SHA256).Hash.ToLowerInvariant()
    "LOCAL_ARTIFACT_VALIDATED W24D3 bytes=$($Item.Length) sha256=$Hash"

## 경계

- LOCAL_ARTIFACT_VALIDATED는 bytes·placeholder·비공백 줄·hash만 확인한다.
F06-C04 · 원문 37–38줄37–38줄
37–38줄 원본
- 원자성·잠금·멱등·대사·query·보안·운영의 위험-선택-test-결과-한계 연결은 사람이 읽는다.
- 실행하지 않은 환경 수치를 운영 보장으로 확대하지 않는다.
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

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

전체 번역 31 / 31

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

원본한국어 번역
1# W24 D3 README 학습 골격문서 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
3> PDF p794–795의 TEMPLATE와 validator를 한 파일에 모은 학습용 예시다. 학습자 README 완성본이나 의미 Green이 아니다.문서 의미: W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다.
5## Risk: concurrent reverse transfers문서 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
7- Failure before: cyclic lock order produced SQLSTATE 40P01문서 의미: W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다.
8- Choice: canonical sorted account lock order문서 의미: W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다.
9- Verification: SortedLockTransferIT, 100 reverse runs문서 의미: W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다.
10- Result: deadlock 0 within documented test envelope문서 의미: W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다.
11- Limitation: local PostgreSQL 17.10, not production capacity문서 의미: W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다.
13## 학습자 산출물 검사문서 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
15 $Artifact = Join-Path $LearnerRoot 'README.md'문서 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
16 if (!(Test-Path -LiteralPath $Artifact -PathType Leaf)) {문서 의미: 필수 파일이나 경로가 실제로 있는지 확인한다.
17 throw "learner artifact missing: $Artifact"문서 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
18 }문서 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
19 $Item = Get-Item -LiteralPath $Artifact문서 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
20 if ($Item.Length -lt 40) {문서 의미: 조건·반복·함수의 실행 block을 연다.
21 throw "artifact is too small to support the claim: bytes=$($Item.Length)"문서 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
22 }문서 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
23 $Text = Get-Content -LiteralPath $Artifact -Raw문서 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
24 if ($Text -match '(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b') {문서 의미: Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
25 throw 'unresolved placeholder in learner artifact'문서 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
26 }문서 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
27 $NonBlank = @($Text -split '[\r\n]+' | Where-Object { $_.Trim().Length -gt 0 })문서 의미: 조건을 만족하는 row만 필터링한다.
28 if ($NonBlank.Count -lt 3) {문서 의미: 조건·반복·함수의 실행 block을 연다.
29 throw "artifact needs at least three nonblank evidence lines: $($NonBlank.Count)"문서 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
30 }문서 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
31 $Hash = (Get-FileHash -LiteralPath $Artifact -Algorithm SHA256).Hash.ToLowerInvariant()문서 의미: 현재 bytes를 64자리 digest로 evidence에 결박한다.
32 "LOCAL_ARTIFACT_VALIDATED W24D3 bytes=$($Item.Length) sha256=$Hash"문서 의미: 파일 bytes·기본 형식·hash만 통과한 보조 marker를 낸다.
34## 경계문서 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
36- LOCAL_ARTIFACT_VALIDATED는 bytes·placeholder·비공백 줄·hash만 확인한다.문서 의미: 파일 bytes·기본 형식·hash만 통과한 보조 marker를 낸다.
37- 원자성·잠금·멱등·대사·query·보안·운영의 위험-선택-test-결과-한계 연결은 사람이 읽는다.문서 의미: W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다.
38- 실행하지 않은 환경 수치를 운영 보장으로 확대하지 않는다.문서 의미: W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다.
07

STEP 07 / 13

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

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

한 줄로 읽기

W24 D3 README — 위험·선택·검증·결과·한계 연결는 기능 나열 대신 일곱 위험을 evidence path와 test envelope에 연결하는 README 골격과 형식 validator를 보여 준다.

문법 해부

  • .md 문법에서 선언·조건·pipeline·block 경계를 먼저 나눈다.
  • expected 값과 actual 결과를 같은 이름처럼 보여도 서로 다른 source로 읽는다.
  • native exit·row count·hash·사람 판정을 서로 대체하지 않는다.

실행 순서

  1. 입력 경로·fixture·환경변수·expected 계약을 고정한다.
  2. source가 실행하는 native process·HTTP·SQL 또는 형식 검사를 따라간다.
  3. actual 값과 exact marker를 대조하고 실패면 성공 발행 전에 중단한다.
  4. finally cleanup과 비범위를 evidence에 남긴다.

W24 조각별 정밀 해설

F06-C01 · 원문 1–12줄
문법 해부
.md 문법으로 1–12줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
SQLSTATE 40P01, SortedLockTransferIT, 100 reverse runs를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
학습자 README 완성본이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
학습자 README 완성본이 아니다; hash는 내용의 진실성을 증명하지 않는다; 운영 용량 보장이 아니다
다음 연결
다음 조각 또는 F06 evidence 판정으로 상태를 넘긴다.
F06-C02 · 원문 13–24줄
문법 해부
.md 문법으로 13–24줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
SQLSTATE 40P01, SortedLockTransferIT, 100 reverse runs를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
학습자 README 완성본이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
학습자 README 완성본이 아니다; hash는 내용의 진실성을 증명하지 않는다; 운영 용량 보장이 아니다
다음 연결
다음 조각 또는 F06 evidence 판정으로 상태를 넘긴다.
F06-C03 · 원문 25–36줄
문법 해부
.md 문법으로 25–36줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
SQLSTATE 40P01, SortedLockTransferIT, 100 reverse runs를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
학습자 README 완성본이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
학습자 README 완성본이 아니다; hash는 내용의 진실성을 증명하지 않는다; 운영 용량 보장이 아니다
다음 연결
다음 조각 또는 F06 evidence 판정으로 상태를 넘긴다.
F06-C04 · 원문 37–38줄
문법 해부
.md 문법으로 37–38줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
SQLSTATE 40P01, SortedLockTransferIT, 100 reverse runs를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
학습자 README 완성본이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
학습자 README 완성본이 아니다; hash는 내용의 진실성을 증명하지 않는다; 운영 용량 보장이 아니다
다음 연결
다음 조각 또는 F06 evidence 판정으로 상태를 넘긴다.
실행 순서 — W24 D3 README — 위험·선택·검증·결과·한계 연결히토리 → 니지카 → 료 → 키타
  1. 히토리

    SortedLockTransferIT가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 기능 나열 대신 일곱 위험을 evidence path와 test envelope에 연결하는 README 골격과 형식 validator를 보여 준다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘hash는 내용의 진실성을 증명하지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 SortedLockTransferIT와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

08

STEP 08 / 13

실제 값 따라가기

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

순서들어온 값코드가 하는 일나온 값·상태경계
입력SQLSTATE 40P01source 계약에 대입F06 실행/설명 시작 상태학습자 README 완성본이 아니다
검증SortedLockTransferITexpected와 actual 또는 형식 대조통과 또는 첫 mismatchhash는 내용의 진실성을 증명하지 않는다
증거LOCAL_ARTIFACT_VALIDATEDmarker·hash·row를 같은 run에 연결범위가 적힌 evidence 후보운영 용량 보장이 아니다
실제 값 — W24 D3 README — 위험·선택·검증·결과·한계 연결히토리 → 니지카 → 료 → 키타
  1. 히토리

    100 reverse runs가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 기능 나열 대신 일곱 위험을 evidence path와 test envelope에 연결하는 README 골격과 형식 validator를 보여 준다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘운영 용량 보장이 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 100 reverse runs와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

09

STEP 09 / 13

Gradle·PowerShell·HTTP·PostgreSQL 내부에서 벌어지는 일

Gradle·JUnit XML·PowerShell·HTTP·PostgreSQL·Docker에서 실제로 일어나는 일과 증명 범위를 구분합니다.

source/contract

W24-D3-readme-evidence.md bytes와 expected 값을 읽는다.

파일 존재만으로 runtime 성공은 아니다.
execution/evidence

native exit·HTTP status·JUnit XML·DB row·hash 중 이 파일이 소유한 값을 만든다.

학습자 README 완성본이 아니다
release/human

관련 evidence와 사람 의미 검토를 release 후보에 연결한다.

운영 용량 보장이 아니다
첫 실패 경계 — W24 D3 README — 위험·선택·검증·결과·한계 연결히토리 → 니지카 → 료 → 키타
  1. 히토리

    LOCAL_ARTIFACT_VALIDATED가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 기능 나열 대신 일곱 위험을 evidence path와 test envelope에 연결하는 README 골격과 형식 validator를 보여 준다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘학습자 README 완성본이 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 LOCAL_ARTIFACT_VALIDATED와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

10

STEP 10 / 13

흔한 착각과 틀린 예

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

❌ SQLSTATE 40P01 문자열이 source에 있으니 실제 실행도 Green이다.

왜 틀리나 source literal과 runtime 관찰값은 다른 증거다.

바르게 읽기 native exit·actual XML/HTTP/DB evidence를 별도로 확인한다.

반례 script가 실행 전 경로 오류로 멈춰도 literal은 그대로 남는다.

❌ 파일 SHA-256이 있으면 내용의 의미와 사실성도 검증됐다.

왜 틀리나 hash는 동일 bytes만 말한다.

바르게 읽기 schema·수치·질문·근거는 별도 자동 또는 사람 판정을 거친다.

반례 빈 review 질문을 가진 CSV도 안정된 hash를 가진다.

❌ LOCAL_ARTIFACT_VALIDATED는 release Green과 같다.

왜 틀리나 generic validator는 파일 shape만 확인한다.

바르게 읽기 HUMAN_SEMANTIC_REVIEW_REQUIRED를 유지한다.

반례 잘못된 track 점수표도 byte 수 조건은 통과할 수 있다.

❌ 이 파일이 W24 전체 lifecycle을 모두 소유한다.

왜 틀리나 각 source는 Gate·demo·cleanup·사람 review 중 일부만 담당한다.

바르게 읽기 owner와 non-responsibility를 release manifest에서 분리한다.

반례 D4 source audit에는 runtime_claim=false가 명시된다.

❌ 이전 주 Green이나 오래된 log를 현재 commit 결과로 재사용한다.

왜 틀리나 source·commit·actual result가 같은 실행에 묶이지 않는다.

바르게 읽기 release 후보에서 새 evidence와 hash를 만든다.

반례 expected JSON이 바뀌면 예전 XML은 exact inventory를 증명하지 못한다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

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

증명 범위

학습자 README 완성본이 아니다

이 책임을 맡는 곳: runtime Gate
증명 범위

hash는 내용의 진실성을 증명하지 않는다

이 책임을 맡는 곳: external/human review
증명 범위

운영 용량 보장이 아니다

이 책임을 맡는 곳: release manifest
증명 범위

학습자 README 완성본이 아니다

이 책임을 맡는 곳: 운영 환경
증명하지 않는 범위 — W24 D3 README — 위험·선택·검증·결과·한계 연결히토리 → 니지카 → 료 → 키타
  1. 히토리

    SQLSTATE 40P01가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 기능 나열 대신 일곱 위험을 evidence path와 test envelope에 연결하는 README 골격과 형식 validator를 보여 준다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘hash는 내용의 진실성을 증명하지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 SQLSTATE 40P01와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

12

STEP 12 / 13

직접 다시 써보기

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

1단계 · 뜻부터 복원

  • 기능 나열 대신 일곱 위험을 evidence path와 test envelope에 연결하는 README 골격과 형식 validator를 보여 준다.
  • 핵심 값은 SQLSTATE 40P01, SortedLockTransferIT, 100 reverse runs, LOCAL_ARTIFACT_VALIDATED다.

2단계 · 코드 조각 재조립

  1. 1. 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다
  2. 3. W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다
  3. 5. 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다
  4. 7. W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다
  5. 8. W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다
  6. 9. W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다
  7. 10. W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다
  8. 11. W24-D3-readme-evidence.md의 다음 검증 또는 설명 단계를 구성한다

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

illustrative/markdown/W24-D3-readme-evidence.md을 새 파일에 다시 쓰고 expected·actual·실패·cleanup·비범위를 주석으로 표시한다.

자가 점검
  • 비어 있지 않은 모든 source 줄을 한 번씩 읽었나?
  • source shape와 runtime Green을 분리했나?
  • 사람 검토·외부 상태를 자동 성공으로 꾸미지 않았나?
  • 첫 실패와 cleanup 책임을 설명할 수 있나?
13

STEP 13 / 13

전체 원본 source

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

학습용 예시 전체 확인하기 · 정본 답안 아님
학습용 예시 · PDF template/validator · 정본 답안 아님illustrative/markdown/W24-D3-readme-evidence.mdSHA-256 f99d5d3db81806515ae67a081e9f8993a940cafbc5fdf55272e5a6062f8062dd
W24 D3 README — 위험·선택·검증·결과·한계 연결 전체
# W24 D3 README 학습 골격

> PDF p794–795의 TEMPLATE와 validator를 한 파일에 모은 학습용 예시다. 학습자 README 완성본이나 의미 Green이 아니다.

## Risk: concurrent reverse transfers

- Failure before: cyclic lock order produced SQLSTATE 40P01
- Choice: canonical sorted account lock order
- Verification: SortedLockTransferIT, 100 reverse runs
- Result: deadlock 0 within documented test envelope
- Limitation: local PostgreSQL 17.10, not production capacity

## 학습자 산출물 검사

    $Artifact = Join-Path $LearnerRoot 'README.md'
    if (!(Test-Path -LiteralPath $Artifact -PathType Leaf)) {
      throw "learner artifact missing: $Artifact"
    }
    $Item = Get-Item -LiteralPath $Artifact
    if ($Item.Length -lt 40) {
      throw "artifact is too small to support the claim: bytes=$($Item.Length)"
    }
    $Text = Get-Content -LiteralPath $Artifact -Raw
    if ($Text -match '(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b') {
      throw 'unresolved placeholder in learner artifact'
    }
    $NonBlank = @($Text -split '[\r\n]+' | Where-Object { $_.Trim().Length -gt 0 })
    if ($NonBlank.Count -lt 3) {
      throw "artifact needs at least three nonblank evidence lines: $($NonBlank.Count)"
    }
    $Hash = (Get-FileHash -LiteralPath $Artifact -Algorithm SHA256).Hash.ToLowerInvariant()
    "LOCAL_ARTIFACT_VALIDATED W24D3 bytes=$($Item.Length) sha256=$Hash"

## 경계

- LOCAL_ARTIFACT_VALIDATED는 bytes·placeholder·비공백 줄·hash만 확인한다.
- 원자성·잠금·멱등·대사·query·보안·운영의 위험-선택-test-결과-한계 연결은 사람이 읽는다.
- 실행하지 않은 환경 수치를 운영 보장으로 확대하지 않는다.
07

W24-SQL-Q39 — 전월에는 있고 당월에는 없는 고객

illustrative/sql/W24-SQL-Q39.sql

학습용 예시 · Q39/Q40 prompt 기반 SQL · 정본 답안 아님 · workbook 제공 정답 아님 · 학습용 예시 · 정본 답안 아님 · W24-F07
39줄 연결39줄 번역4 chunks
01

STEP 01 / 13

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

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

오늘의 한 문장

fixture_clock 기준 반개구간과 NOT EXISTS를 사용해 전월 SUCCESS 고객 집합에서 당월 활동 고객을 NULL-safe하게 제외한다.

  1. previous month은 어느 source와 실제 결과에서 확인해야 할까?
  2. 첫 실패를 만드는 조건과 fail-closed 지점은 어디일까?
  3. 왜 ‘workbook 제공 정답이 아니다’를 별도 경계로 남겨야 할까?
이 파일에서 끝까지 다시 쓰는 값previous monthcurrent monthNOT EXISTShalf-open rangeSUCCESS
왜 필요한가 — W24-SQL-Q39 — 전월에는 있고 당월에는 없는 고객히토리 → 니지카 → 료 → 키타
  1. 히토리

    previous month가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 fixture_clock 기준 반개구간과 NOT EXISTS를 사용해 전월 SUCCESS 고객 집합에서 당월 활동 고객을 NULL-safe하게 제외한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘workbook 제공 정답이 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 previous month와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

02

STEP 02 / 13

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

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

새 기능을 멈춘 팀이 코드·test·문서·demo를 같은 release 후보에 묶어 하나씩 검수한다.

검수 도장이 붙은 공통 거래 코어 출고 상자

이 파일은 fixture_clock 기준 반개구간과 NOT EXISTS를 사용해 전월 SUCCESS 고객 집합에서 당월 활동 고객을 NULL-safe하게 제외한다. 눈으로 읽을 때는 각 줄을 검수표 한 칸처럼 보고, 입력과 다음 상태를 놓치지 않는다.

마지막 도장은 source shape와 실제 runtime·사람 검토를 구분한 뒤에만 찍는다. 특히 workbook 제공 정답이 아니다

딱 여기까지만 비유는 실행 순서를 돕지만 실제 Gradle·Docker·DB·사람 review를 대신하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

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

값 1: previous month

이 파일에서 계속 확인할 고정 단서가 previous month다.

코드 연결
F07 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
workbook 제공 정답이 아니다

값 2: current month

이 파일에서 계속 확인할 고정 단서가 current month다.

코드 연결
F07 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
SUCCESS만 활동으로 센다는 가정을 명시한다

값 3: NOT EXISTS

이 파일에서 계속 확인할 고정 단서가 NOT EXISTS다.

코드 연결
F07 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
실제 PostgreSQL 실행 결과가 아니다

값 4: half-open range

이 파일에서 계속 확인할 고정 단서가 half-open range다.

코드 연결
F07 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
workbook 제공 정답이 아니다

값 5: SUCCESS

이 파일에서 계속 확인할 고정 단서가 SUCCESS다.

코드 연결
F07 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
SUCCESS만 활동으로 센다는 가정을 명시한다
04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

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

단어 몇 개만 뽑은 표가 아닙니다.학습용 예시 · Q39/Q40 prompt 기반 SQL · 정본 답안 아님 · workbook 제공 정답 아님에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.39 / 39 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F07-L01 -- W24-SQL-Q39 학습용 예시이며 workbook 제공 정답이 아니다. 출고표 1번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-001가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
2줄F07-L02 -- 가정: 전월/당월은 fixture_clock.as_of가 속한 달을 기준으로 하고 SUCCESS 거래만 활동으로 센다. 출고표 2번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-002가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
SUCCESS만 활동으로 센다는 가정을 명시한다
3줄F07-L03 -- 입력 grain: business_tx 한 행 = 거래 한 건. 출력 grain: customer 한 행. 예상 cardinality는 fixture 실행으로 확인한다. 출고표 3번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-003가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
4줄F07-L04 WITH bounds AS ( 출고표 4번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-004가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
5줄F07-L05 SELECT 출고표 5번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-005가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
SUCCESS만 활동으로 센다는 가정을 명시한다
6줄F07-L06 date_trunc('month', as_of) AS current_start, 출고표 6번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 fixture clock을 달 시작 경계로 정규화한다.
입력
'month'
결과·효과
관찰 상태 F07-006가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
7줄F07-L07 date_trunc('month', as_of) - INTERVAL '1 month' AS previous_start 출고표 7번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 fixture clock을 달 시작 경계로 정규화한다.
입력
'month', '1 month'
결과·효과
관찰 상태 F07-007가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
8줄F07-L08 FROM fixture_clock 출고표 8번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-008가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
SUCCESS만 활동으로 센다는 가정을 명시한다
9줄F07-L09 ), 출고표 9번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-009가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
10줄F07-L10 previous_customers AS ( 출고표 10번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-010가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
11줄F07-L11 SELECT DISTINCT a.customer_id 출고표 11번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-011가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
SUCCESS만 활동으로 센다는 가정을 명시한다
12줄F07-L12 FROM business_tx AS tx 출고표 12번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-012가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
13줄F07-L13 JOIN account AS a 출고표 13번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-013가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
14줄F07-L14 ON a.account_id = tx.account_id 출고표 14번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-014가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
SUCCESS만 활동으로 센다는 가정을 명시한다
15줄F07-L15 CROSS JOIN bounds AS b 출고표 15번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-015가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
16줄F07-L16 WHERE tx.status = 'SUCCESS' 출고표 16번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
'SUCCESS'
결과·효과
관찰 상태 F07-016가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
17줄F07-L17 AND tx.occurred_at >= b.previous_start 출고표 17번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-017가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
SUCCESS만 활동으로 센다는 가정을 명시한다
18줄F07-L18 AND tx.occurred_at < b.current_start 출고표 18번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-018가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
19줄F07-L19 ) 출고표 19번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-019가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
20줄F07-L20 SELECT 출고표 20번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-020가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
SUCCESS만 활동으로 센다는 가정을 명시한다
21줄F07-L21 c.customer_id, 출고표 21번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-021가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
22줄F07-L22 c.customer_name 출고표 22번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-022가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
23줄F07-L23 FROM previous_customers AS p 출고표 23번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-023가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
SUCCESS만 활동으로 센다는 가정을 명시한다
24줄F07-L24 JOIN customer AS c 출고표 24번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-024가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
25줄F07-L25 ON c.customer_id = p.customer_id 출고표 25번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-025가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
26줄F07-L26 WHERE NOT EXISTS ( 출고표 26번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 당월에 대응 거래가 하나라도 있으면 그 고객을 결과에서 제외한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-026가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
SUCCESS만 활동으로 센다는 가정을 명시한다
27줄F07-L27 SELECT 1 출고표 27번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
1
결과·효과
관찰 상태 F07-027가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
28줄F07-L28 FROM account AS a 출고표 28번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-028가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
29줄F07-L29 JOIN business_tx AS tx 출고표 29번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-029가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
SUCCESS만 활동으로 센다는 가정을 명시한다
30줄F07-L30 ON tx.account_id = a.account_id 출고표 30번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-030가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
31줄F07-L31 CROSS JOIN bounds AS b 출고표 31번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-031가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
32줄F07-L32 WHERE a.customer_id = p.customer_id 출고표 32번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-032가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
SUCCESS만 활동으로 센다는 가정을 명시한다
33줄F07-L33 AND tx.status = 'SUCCESS' 출고표 33번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
'SUCCESS'
결과·효과
관찰 상태 F07-033가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
34줄F07-L34 AND tx.occurred_at >= b.current_start 출고표 34번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-034가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
35줄F07-L35 AND tx.occurred_at < b.current_start + INTERVAL '1 month' 출고표 35번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 반개구간의 이전 달 또는 다음 달 경계를 계산한다.
입력
'1 month'
결과·효과
관찰 상태 F07-035가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
SUCCESS만 활동으로 센다는 가정을 명시한다
36줄F07-L36 ) 출고표 36번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-036가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
37줄F07-L37 ORDER BY c.customer_id; 출고표 37번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 출력 또는 window 계산 순서를 안정적으로 정한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-037가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
39줄F07-L39 -- NULL-safe 반례: NOT EXISTS는 subquery에 NULL 값이 있어도 NOT IN처럼 전체 결과가 UNKNOWN으로 오염되지 않는다. 출고표 39번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 당월에 대응 거래가 하나라도 있으면 그 고객을 결과에서 제외한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-039가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
40줄F07-L40 -- 경계 반례: current_start 시각의 거래는 전월이 아니라 당월에 정확히 한 번 포함된다. 출고표 40번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 previous month
결과·효과
관찰 상태 F07-040가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
05

STEP 05 / 13

원본 코드 조각

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

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

F07-C01 · 원문 1–12줄1–12줄
1–12줄 원본
-- W24-SQL-Q39 학습용 예시이며 workbook 제공 정답이 아니다.
-- 가정: 전월/당월은 fixture_clock.as_of가 속한 달을 기준으로 하고 SUCCESS 거래만 활동으로 센다.
-- 입력 grain: business_tx 한 행 = 거래 한 건. 출력 grain: customer 한 행. 예상 cardinality는 fixture 실행으로 확인한다.
WITH bounds AS (
  SELECT
    date_trunc('month', as_of) AS current_start,
    date_trunc('month', as_of) - INTERVAL '1 month' AS previous_start
  FROM fixture_clock
),
previous_customers AS (
  SELECT DISTINCT a.customer_id
  FROM business_tx AS tx
F07-C02 · 원문 13–24줄13–24줄
13–24줄 원본
  JOIN account AS a
    ON a.account_id = tx.account_id
  CROSS JOIN bounds AS b
  WHERE tx.status = 'SUCCESS'
    AND tx.occurred_at >= b.previous_start
    AND tx.occurred_at < b.current_start
)
SELECT
  c.customer_id,
  c.customer_name
FROM previous_customers AS p
JOIN customer AS c
F07-C03 · 원문 25–36줄25–36줄
25–36줄 원본
  ON c.customer_id = p.customer_id
WHERE NOT EXISTS (
  SELECT 1
  FROM account AS a
  JOIN business_tx AS tx
    ON tx.account_id = a.account_id
  CROSS JOIN bounds AS b
  WHERE a.customer_id = p.customer_id
    AND tx.status = 'SUCCESS'
    AND tx.occurred_at >= b.current_start
    AND tx.occurred_at < b.current_start + INTERVAL '1 month'
)
F07-C04 · 원문 37–40줄37–40줄
37–40줄 원본
ORDER BY c.customer_id;

-- NULL-safe 반례: NOT EXISTS는 subquery에 NULL 값이 있어도 NOT IN처럼 전체 결과가 UNKNOWN으로 오염되지 않는다.
-- 경계 반례: current_start 시각의 거래는 전월이 아니라 당월에 정확히 한 번 포함된다.
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

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

전체 번역 39 / 39

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

원본한국어 번역
1-- W24-SQL-Q39 학습용 예시이며 workbook 제공 정답이 아니다.실행 의미: W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
2-- 가정: 전월/당월은 fixture_clock.as_of가 속한 달을 기준으로 하고 SUCCESS 거래만 활동으로 센다.실행 의미: W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
3-- 입력 grain: business_tx 한 행 = 거래 한 건. 출력 grain: customer 한 행. 예상 cardinality는 fixture 실행으로 확인한다.실행 의미: W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
4WITH bounds AS (실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
5 SELECT실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
6 date_trunc('month', as_of) AS current_start,실행 의미: fixture clock을 달 시작 경계로 정규화한다.
7 date_trunc('month', as_of) - INTERVAL '1 month' AS previous_start실행 의미: fixture clock을 달 시작 경계로 정규화한다.
8 FROM fixture_clock실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
9),실행 의미: W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
10previous_customers AS (실행 의미: W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
11 SELECT DISTINCT a.customer_id실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
12 FROM business_tx AS tx실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
13 JOIN account AS a실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
14 ON a.account_id = tx.account_id실행 의미: W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
15 CROSS JOIN bounds AS b실행 의미: W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
16 WHERE tx.status = 'SUCCESS'실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
17 AND tx.occurred_at >= b.previous_start실행 의미: W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
18 AND tx.occurred_at < b.current_start실행 의미: W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
19)실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
20SELECT실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
21 c.customer_id,실행 의미: W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
22 c.customer_name실행 의미: W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
23FROM previous_customers AS p실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
24JOIN customer AS c실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
25 ON c.customer_id = p.customer_id실행 의미: W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
26WHERE NOT EXISTS (실행 의미: 당월에 대응 거래가 하나라도 있으면 그 고객을 결과에서 제외한다.
27 SELECT 1실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
28 FROM account AS a실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
29 JOIN business_tx AS tx실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
30 ON tx.account_id = a.account_id실행 의미: W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
31 CROSS JOIN bounds AS b실행 의미: W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
32 WHERE a.customer_id = p.customer_id실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
33 AND tx.status = 'SUCCESS'실행 의미: W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
34 AND tx.occurred_at >= b.current_start실행 의미: W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
35 AND tx.occurred_at < b.current_start + INTERVAL '1 month'실행 의미: 반개구간의 이전 달 또는 다음 달 경계를 계산한다.
36)실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
37ORDER BY c.customer_id;실행 의미: 출력 또는 window 계산 순서를 안정적으로 정한다.
39-- NULL-safe 반례: NOT EXISTS는 subquery에 NULL 값이 있어도 NOT IN처럼 전체 결과가 UNKNOWN으로 오염되지 않는다.실행 의미: 당월에 대응 거래가 하나라도 있으면 그 고객을 결과에서 제외한다.
40-- 경계 반례: current_start 시각의 거래는 전월이 아니라 당월에 정확히 한 번 포함된다.실행 의미: W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다.
07

STEP 07 / 13

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

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

한 줄로 읽기

W24-SQL-Q39 — 전월에는 있고 당월에는 없는 고객는 fixture_clock 기준 반개구간과 NOT EXISTS를 사용해 전월 SUCCESS 고객 집합에서 당월 활동 고객을 NULL-safe하게 제외한다.

문법 해부

  • .sql 문법에서 선언·조건·pipeline·block 경계를 먼저 나눈다.
  • expected 값과 actual 결과를 같은 이름처럼 보여도 서로 다른 source로 읽는다.
  • native exit·row count·hash·사람 판정을 서로 대체하지 않는다.

실행 순서

  1. 입력 경로·fixture·환경변수·expected 계약을 고정한다.
  2. source가 실행하는 native process·HTTP·SQL 또는 형식 검사를 따라간다.
  3. actual 값과 exact marker를 대조하고 실패면 성공 발행 전에 중단한다.
  4. finally cleanup과 비범위를 evidence에 남긴다.

W24 조각별 정밀 해설

F07-C01 · 원문 1–12줄
문법 해부
.sql 문법으로 1–12줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
previous month, current month, NOT EXISTS를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
workbook 제공 정답이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
workbook 제공 정답이 아니다; SUCCESS만 활동으로 센다는 가정을 명시한다; 실제 PostgreSQL 실행 결과가 아니다
다음 연결
다음 조각 또는 F07 evidence 판정으로 상태를 넘긴다.
F07-C02 · 원문 13–24줄
문법 해부
.sql 문법으로 13–24줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
previous month, current month, NOT EXISTS를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
workbook 제공 정답이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
workbook 제공 정답이 아니다; SUCCESS만 활동으로 센다는 가정을 명시한다; 실제 PostgreSQL 실행 결과가 아니다
다음 연결
다음 조각 또는 F07 evidence 판정으로 상태를 넘긴다.
F07-C03 · 원문 25–36줄
문법 해부
.sql 문법으로 25–36줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
previous month, current month, NOT EXISTS를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
workbook 제공 정답이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
workbook 제공 정답이 아니다; SUCCESS만 활동으로 센다는 가정을 명시한다; 실제 PostgreSQL 실행 결과가 아니다
다음 연결
다음 조각 또는 F07 evidence 판정으로 상태를 넘긴다.
F07-C04 · 원문 37–40줄
문법 해부
.sql 문법으로 37–40줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
previous month, current month, NOT EXISTS를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
workbook 제공 정답이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
workbook 제공 정답이 아니다; SUCCESS만 활동으로 센다는 가정을 명시한다; 실제 PostgreSQL 실행 결과가 아니다
다음 연결
다음 조각 또는 F07 evidence 판정으로 상태를 넘긴다.
실행 순서 — W24-SQL-Q39 — 전월에는 있고 당월에는 없는 고객히토리 → 니지카 → 료 → 키타
  1. 히토리

    current month가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 fixture_clock 기준 반개구간과 NOT EXISTS를 사용해 전월 SUCCESS 고객 집합에서 당월 활동 고객을 NULL-safe하게 제외한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘SUCCESS만 활동으로 센다는 가정을 명시한다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 current month와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

08

STEP 08 / 13

실제 값 따라가기

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

순서들어온 값코드가 하는 일나온 값·상태경계
입력previous monthsource 계약에 대입F07 실행/설명 시작 상태workbook 제공 정답이 아니다
검증current monthexpected와 actual 또는 형식 대조통과 또는 첫 mismatchSUCCESS만 활동으로 센다는 가정을 명시한다
증거SUCCESSmarker·hash·row를 같은 run에 연결범위가 적힌 evidence 후보실제 PostgreSQL 실행 결과가 아니다
실제 값 — W24-SQL-Q39 — 전월에는 있고 당월에는 없는 고객히토리 → 니지카 → 료 → 키타
  1. 히토리

    NOT EXISTS가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 fixture_clock 기준 반개구간과 NOT EXISTS를 사용해 전월 SUCCESS 고객 집합에서 당월 활동 고객을 NULL-safe하게 제외한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘실제 PostgreSQL 실행 결과가 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 NOT EXISTS와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

09

STEP 09 / 13

Gradle·PowerShell·HTTP·PostgreSQL 내부에서 벌어지는 일

Gradle·JUnit XML·PowerShell·HTTP·PostgreSQL·Docker에서 실제로 일어나는 일과 증명 범위를 구분합니다.

source/contract

W24-SQL-Q39.sql bytes와 expected 값을 읽는다.

파일 존재만으로 runtime 성공은 아니다.
execution/evidence

native exit·HTTP status·JUnit XML·DB row·hash 중 이 파일이 소유한 값을 만든다.

workbook 제공 정답이 아니다
release/human

관련 evidence와 사람 의미 검토를 release 후보에 연결한다.

실제 PostgreSQL 실행 결과가 아니다
첫 실패 경계 — W24-SQL-Q39 — 전월에는 있고 당월에는 없는 고객히토리 → 니지카 → 료 → 키타
  1. 히토리

    half-open range가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 fixture_clock 기준 반개구간과 NOT EXISTS를 사용해 전월 SUCCESS 고객 집합에서 당월 활동 고객을 NULL-safe하게 제외한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘workbook 제공 정답이 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 half-open range와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

10

STEP 10 / 13

흔한 착각과 틀린 예

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

❌ previous month 문자열이 source에 있으니 실제 실행도 Green이다.

왜 틀리나 source literal과 runtime 관찰값은 다른 증거다.

바르게 읽기 native exit·actual XML/HTTP/DB evidence를 별도로 확인한다.

반례 script가 실행 전 경로 오류로 멈춰도 literal은 그대로 남는다.

❌ 파일 SHA-256이 있으면 내용의 의미와 사실성도 검증됐다.

왜 틀리나 hash는 동일 bytes만 말한다.

바르게 읽기 schema·수치·질문·근거는 별도 자동 또는 사람 판정을 거친다.

반례 빈 review 질문을 가진 CSV도 안정된 hash를 가진다.

❌ LOCAL_ARTIFACT_VALIDATED는 release Green과 같다.

왜 틀리나 generic validator는 파일 shape만 확인한다.

바르게 읽기 HUMAN_SEMANTIC_REVIEW_REQUIRED를 유지한다.

반례 잘못된 track 점수표도 byte 수 조건은 통과할 수 있다.

❌ 이 파일이 W24 전체 lifecycle을 모두 소유한다.

왜 틀리나 각 source는 Gate·demo·cleanup·사람 review 중 일부만 담당한다.

바르게 읽기 owner와 non-responsibility를 release manifest에서 분리한다.

반례 D4 source audit에는 runtime_claim=false가 명시된다.

❌ 이전 주 Green이나 오래된 log를 현재 commit 결과로 재사용한다.

왜 틀리나 source·commit·actual result가 같은 실행에 묶이지 않는다.

바르게 읽기 release 후보에서 새 evidence와 hash를 만든다.

반례 expected JSON이 바뀌면 예전 XML은 exact inventory를 증명하지 못한다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

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

증명 범위

workbook 제공 정답이 아니다

이 책임을 맡는 곳: runtime Gate
증명 범위

SUCCESS만 활동으로 센다는 가정을 명시한다

이 책임을 맡는 곳: external/human review
증명 범위

실제 PostgreSQL 실행 결과가 아니다

이 책임을 맡는 곳: release manifest
증명 범위

workbook 제공 정답이 아니다

이 책임을 맡는 곳: 운영 환경
증명하지 않는 범위 — W24-SQL-Q39 — 전월에는 있고 당월에는 없는 고객히토리 → 니지카 → 료 → 키타
  1. 히토리

    SUCCESS가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 fixture_clock 기준 반개구간과 NOT EXISTS를 사용해 전월 SUCCESS 고객 집합에서 당월 활동 고객을 NULL-safe하게 제외한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘SUCCESS만 활동으로 센다는 가정을 명시한다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 SUCCESS와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

12

STEP 12 / 13

직접 다시 써보기

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

1단계 · 뜻부터 복원

  • fixture_clock 기준 반개구간과 NOT EXISTS를 사용해 전월 SUCCESS 고객 집합에서 당월 활동 고객을 NULL-safe하게 제외한다.
  • 핵심 값은 previous month, current month, NOT EXISTS, half-open range, SUCCESS다.

2단계 · 코드 조각 재조립

  1. 1. W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다
  2. 2. W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다
  3. 3. W24-SQL-Q39.sql의 다음 검증 또는 설명 단계를 구성한다
  4. 4. SQL 집합의 입력·변환·필터 단계를 선언한다
  5. 5. SQL 집합의 입력·변환·필터 단계를 선언한다
  6. 6. fixture clock을 달 시작 경계로 정규화한다
  7. 7. fixture clock을 달 시작 경계로 정규화한다
  8. 8. SQL 집합의 입력·변환·필터 단계를 선언한다

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

illustrative/sql/W24-SQL-Q39.sql을 새 파일에 다시 쓰고 expected·actual·실패·cleanup·비범위를 주석으로 표시한다.

자가 점검
  • 비어 있지 않은 모든 source 줄을 한 번씩 읽었나?
  • source shape와 runtime Green을 분리했나?
  • 사람 검토·외부 상태를 자동 성공으로 꾸미지 않았나?
  • 첫 실패와 cleanup 책임을 설명할 수 있나?
13

STEP 13 / 13

전체 원본 source

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

학습용 예시 전체 확인하기 · 정본 답안 아님
학습용 예시 · Q39/Q40 prompt 기반 SQL · 정본 답안 아님 · workbook 제공 정답 아님illustrative/sql/W24-SQL-Q39.sqlSHA-256 6a983a0b6f0938248caa4d26be9fe55e848db4a65c6d00911d008307ab74675e
W24-SQL-Q39 — 전월에는 있고 당월에는 없는 고객 전체
-- W24-SQL-Q39 학습용 예시이며 workbook 제공 정답이 아니다.
-- 가정: 전월/당월은 fixture_clock.as_of가 속한 달을 기준으로 하고 SUCCESS 거래만 활동으로 센다.
-- 입력 grain: business_tx 한 행 = 거래 한 건. 출력 grain: customer 한 행. 예상 cardinality는 fixture 실행으로 확인한다.
WITH bounds AS (
  SELECT
    date_trunc('month', as_of) AS current_start,
    date_trunc('month', as_of) - INTERVAL '1 month' AS previous_start
  FROM fixture_clock
),
previous_customers AS (
  SELECT DISTINCT a.customer_id
  FROM business_tx AS tx
  JOIN account AS a
    ON a.account_id = tx.account_id
  CROSS JOIN bounds AS b
  WHERE tx.status = 'SUCCESS'
    AND tx.occurred_at >= b.previous_start
    AND tx.occurred_at < b.current_start
)
SELECT
  c.customer_id,
  c.customer_name
FROM previous_customers AS p
JOIN customer AS c
  ON c.customer_id = p.customer_id
WHERE NOT EXISTS (
  SELECT 1
  FROM account AS a
  JOIN business_tx AS tx
    ON tx.account_id = a.account_id
  CROSS JOIN bounds AS b
  WHERE a.customer_id = p.customer_id
    AND tx.status = 'SUCCESS'
    AND tx.occurred_at >= b.current_start
    AND tx.occurred_at < b.current_start + INTERVAL '1 month'
)
ORDER BY c.customer_id;

-- NULL-safe 반례: NOT EXISTS는 subquery에 NULL 값이 있어도 NOT IN처럼 전체 결과가 UNKNOWN으로 오염되지 않는다.
-- 경계 반례: current_start 시각의 거래는 전월이 아니라 당월에 정확히 한 번 포함된다.
08

reset-demo.ps1 — 계좌 응답의 numeric ID를 state로 연결

scripts/reset-demo.ps1

PDF 전문 정본 · packaged PowerShell source · 정본 · W24-F08
53줄 연결53줄 번역5 chunks
01

STEP 01 / 13

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

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

오늘의 한 문장

customer-1 인증으로 두 계좌를 만들고 반환된 양의 정수 accountId와 시작 잔액을 비밀 없는 demo-state.json에 저장한다.

  1. from=10000은 어느 source와 실제 결과에서 확인해야 할까?
  2. 첫 실패를 만드는 조건과 fail-closed 지점은 어디일까?
  3. 왜 ‘FCL_DEMO_PASSWORD는 환경변수로만 받는다’를 별도 경계로 남겨야 할까?
이 파일에서 끝까지 다시 쓰는 값from=10000to=5000numeric accountIdDEMO_RESET_OK
왜 필요한가 — reset-demo.ps1 — 계좌 응답의 numeric ID를 state로 연결히토리 → 니지카 → 료 → 키타
  1. 히토리

    from=10000가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 customer-1 인증으로 두 계좌를 만들고 반환된 양의 정수 accountId와 시작 잔액을 비밀 없는 demo-state.json에 저장한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘FCL_DEMO_PASSWORD는 환경변수로만 받는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 from=10000와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

02

STEP 02 / 13

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

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

새 기능을 멈춘 팀이 코드·test·문서·demo를 같은 release 후보에 묶어 하나씩 검수한다.

검수 도장이 붙은 공통 거래 코어 출고 상자

이 파일은 customer-1 인증으로 두 계좌를 만들고 반환된 양의 정수 accountId와 시작 잔액을 비밀 없는 demo-state.json에 저장한다. 눈으로 읽을 때는 각 줄을 검수표 한 칸처럼 보고, 입력과 다음 상태를 놓치지 않는다.

마지막 도장은 source shape와 실제 runtime·사람 검토를 구분한 뒤에만 찍는다. 특히 FCL_DEMO_PASSWORD는 환경변수로만 받는다

딱 여기까지만 비유는 실행 순서를 돕지만 실제 Gradle·Docker·DB·사람 review를 대신하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

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

값 1: from=10000

이 파일에서 계속 확인할 고정 단서가 from=10000다.

코드 연결
F08 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
FCL_DEMO_PASSWORD는 환경변수로만 받는다

값 2: to=5000

이 파일에서 계속 확인할 고정 단서가 to=5000다.

코드 연결
F08 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
문자열 A/B를 long ID에 넣지 않는다

값 3: numeric accountId

이 파일에서 계속 확인할 고정 단서가 numeric accountId다.

코드 연결
F08 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
reset만으로 transfer Green은 아니다

값 4: DEMO_RESET_OK

이 파일에서 계속 확인할 고정 단서가 DEMO_RESET_OK다.

코드 연결
F08 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
FCL_DEMO_PASSWORD는 환경변수로만 받는다
04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

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

단어 몇 개만 뽑은 표가 아닙니다.PDF 전문 정본 · packaged PowerShell source에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.53 / 53 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F08-L01 param( 출고표 1번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 PowerShell script가 받을 입력 계약을 연다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F08-001가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
FCL_DEMO_PASSWORD는 환경변수로만 받는다
2줄F08-L02 [string]$RunId = "w24-$([DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds())", 출고표 2번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$RunId
결과·효과
관찰 상태 F08-002가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
문자열 A/B를 long ID에 넣지 않는다
3줄F08-L03 [string]$StatePath = 'evidence\w24\demo-state.json', 출고표 3번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$StatePath, 'evidence\w24\demo-state.json'
결과·효과
관찰 상태 F08-003가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset만으로 transfer Green은 아니다
4줄F08-L04 [string]$BaseUrl = '' 출고표 4번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$BaseUrl
결과·효과
관찰 상태 F08-004가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
FCL_DEMO_PASSWORD는 환경변수로만 받는다
5줄F08-L05 ) 출고표 5번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F08-005가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
문자열 A/B를 long ID에 넣지 않는다
7줄F08-L07 $ErrorActionPreference = 'Stop' 출고표 7번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다.
입력
$ErrorActionPreference, 'Stop'
결과·효과
관찰 상태 F08-007가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
FCL_DEMO_PASSWORD는 환경변수로만 받는다
8줄F08-L08 $BaseUrl = if (-not [string]::IsNullOrWhiteSpace($BaseUrl)) { 출고표 8번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$BaseUrl, $BaseUrl
결과·효과
관찰 상태 F08-008가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
문자열 A/B를 long ID에 넣지 않는다
9줄F08-L09 $BaseUrl 출고표 9번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$BaseUrl
결과·효과
관찰 상태 F08-009가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset만으로 transfer Green은 아니다
10줄F08-L10 } elseif (-not [string]::IsNullOrWhiteSpace($env:FCL_BASE_URL)) { 출고표 10번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$env
결과·효과
관찰 상태 F08-010가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
FCL_DEMO_PASSWORD는 환경변수로만 받는다
11줄F08-L11 $env:FCL_BASE_URL 출고표 11번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$env
결과·효과
관찰 상태 F08-011가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
문자열 A/B를 long ID에 넣지 않는다
12줄F08-L12 } else { 출고표 12번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F08-012가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset만으로 transfer Green은 아니다
13줄F08-L13 'http://localhost:8080' 출고표 13번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
'http://localhost:8080'
결과·효과
관찰 상태 F08-013가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
FCL_DEMO_PASSWORD는 환경변수로만 받는다
14줄F08-L14 } 출고표 14번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F08-014가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
문자열 A/B를 long ID에 넣지 않는다
15줄F08-L15 $user = $env:FCL_DEMO_USER 출고표 15번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$user, $env
결과·효과
관찰 상태 F08-015가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset만으로 transfer Green은 아니다
16줄F08-L16 $password = $env:FCL_DEMO_PASSWORD 출고표 16번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$password, $env
결과·효과
관찰 상태 F08-016가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
FCL_DEMO_PASSWORD는 환경변수로만 받는다
17줄F08-L17 if ([string]::IsNullOrWhiteSpace($user) -or [string]::IsNullOrWhiteSpace($password)) { 출고표 17번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$user, $password
결과·효과
관찰 상태 F08-017가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
문자열 A/B를 long ID에 넣지 않는다
18줄F08-L18 throw 'Set FCL_DEMO_USER and FCL_DEMO_PASSWORD in this terminal only.' 출고표 18번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F08-018가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset만으로 transfer Green은 아니다
19줄F08-L19 } 출고표 19번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F08-019가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
FCL_DEMO_PASSWORD는 환경변수로만 받는다
20줄F08-L20 if ($RunId -notmatch '^[A-Za-z0-9-]{1,18}$') { 출고표 20번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$RunId, '^[A-Za-z0-9-]{1,18}$'
결과·효과
관찰 상태 F08-020가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
문자열 A/B를 long ID에 넣지 않는다
21줄F08-L21 throw 'RunId must be 1-18 ASCII letters, digits, or hyphens.' 출고표 21번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
1, 18
결과·효과
관찰 상태 F08-021가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset만으로 transfer Green은 아니다
22줄F08-L22 } 출고표 22번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F08-022가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
FCL_DEMO_PASSWORD는 환경변수로만 받는다
24줄F08-L24 $pair = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("${user}:${password}")) 출고표 24번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$pair, "${user}:${password}"
결과·효과
관찰 상태 F08-024가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset만으로 transfer Green은 아니다
25줄F08-L25 $headers = @{ Authorization = "Basic $pair" } 출고표 25번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 인증 header를 runtime에서 만들되 evidence에 원문 비밀을 남기지 않는다.
입력
$headers, "Basic $pair"
결과·효과
관찰 상태 F08-025가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
FCL_DEMO_PASSWORD는 환경변수로만 받는다
27줄F08-L27 function New-DemoAccount([string]$Suffix, [long]$OpeningBalance) { 출고표 27번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 demo 계좌의 재현 가능한 시작 잔액을 요청 body에 넣는다.
입력
$Suffix, $OpeningBalance
결과·효과
관찰 상태 F08-027가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset만으로 transfer Green은 아니다
28줄F08-L28 $accountNo = "DEMO-$RunId-$Suffix" 출고표 28번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$accountNo, "DEMO-$RunId-$Suffix"
결과·효과
관찰 상태 F08-028가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
FCL_DEMO_PASSWORD는 환경변수로만 받는다
29줄F08-L29 $body = @{ accountNo = $accountNo; openingBalance = $OpeningBalance } | 출고표 29번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 demo 계좌의 재현 가능한 시작 잔액을 요청 body에 넣는다.
입력
$body, $accountNo, $OpeningBalance
결과·효과
관찰 상태 F08-029가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
문자열 A/B를 long ID에 넣지 않는다
30줄F08-L30 ConvertTo-Json -Compress 출고표 30번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 검증된 object를 JSON evidence text로 직렬화한다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F08-030가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset만으로 transfer Green은 아니다
31줄F08-L31 $response = Invoke-RestMethod -Method Post -Uri "$BaseUrl/api/accounts" ` 출고표 31번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 HTTP API를 호출해 status와 JSON response를 받는다.
입력
$response, "$BaseUrl/api/accounts"
결과·효과
관찰 상태 F08-031가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
FCL_DEMO_PASSWORD는 환경변수로만 받는다
32줄F08-L32 -Headers ($headers + @{ 'X-Request-Id' = "w24-open-$Suffix-$RunId" }) ` 출고표 32번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$headers, 'X-Request-Id', "w24-open-$Suffix-$RunId"
결과·효과
관찰 상태 F08-032가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
문자열 A/B를 long ID에 넣지 않는다
33줄F08-L33 -ContentType 'application/json' -Body $body 출고표 33번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
'application/json', $body
결과·효과
관찰 상태 F08-033가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset만으로 transfer Green은 아니다
34줄F08-L34 if ([long]$response.accountId -le 0 -or $response.accountNo -cne $accountNo -or 출고표 34번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계좌 생성 응답의 numeric ID를 다음 transfer·대사 단계로 전달한다.
입력
$response, 0, $response
결과·효과
관찰 상태 F08-034가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
FCL_DEMO_PASSWORD는 환경변수로만 받는다
35줄F08-L35 [long]$response.balance -ne $OpeningBalance) { 출고표 35번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 demo 계좌의 재현 가능한 시작 잔액을 요청 body에 넣는다.
입력
$response, $OpeningBalance
결과·효과
관찰 상태 F08-035가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
문자열 A/B를 long ID에 넣지 않는다
36줄F08-L36 throw "account response mismatch: $($response | ConvertTo-Json -Compress)" 출고표 36번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 검증된 object를 JSON evidence text로 직렬화한다.
입력
$response
결과·효과
관찰 상태 F08-036가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset만으로 transfer Green은 아니다
37줄F08-L37 } 출고표 37번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F08-037가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
FCL_DEMO_PASSWORD는 환경변수로만 받는다
38줄F08-L38 return $response 출고표 38번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$response
결과·효과
관찰 상태 F08-038가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
문자열 A/B를 long ID에 넣지 않는다
39줄F08-L39 } 출고표 39번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F08-039가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset만으로 transfer Green은 아니다
41줄F08-L41 $from = New-DemoAccount -Suffix 'FROM' -OpeningBalance 10000 출고표 41번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 demo 계좌의 재현 가능한 시작 잔액을 요청 body에 넣는다.
입력
$from, 'FROM', 10000
결과·효과
관찰 상태 F08-041가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
문자열 A/B를 long ID에 넣지 않는다
42줄F08-L42 $to = New-DemoAccount -Suffix 'TO' -OpeningBalance 5000 출고표 42번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 demo 계좌의 재현 가능한 시작 잔액을 요청 body에 넣는다.
입력
$to, 'TO', 5000
결과·효과
관찰 상태 F08-042가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset만으로 transfer Green은 아니다
43줄F08-L43 $state = [ordered]@{ 출고표 43번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$state
결과·효과
관찰 상태 F08-043가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
FCL_DEMO_PASSWORD는 환경변수로만 받는다
44줄F08-L44 runId = $RunId 출고표 44번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$RunId
결과·효과
관찰 상태 F08-044가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
문자열 A/B를 long ID에 넣지 않는다
45줄F08-L45 baseUrl = $BaseUrl 출고표 45번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$BaseUrl
결과·효과
관찰 상태 F08-045가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset만으로 transfer Green은 아니다
46줄F08-L46 actor = $user 출고표 46번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$user
결과·효과
관찰 상태 F08-046가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
FCL_DEMO_PASSWORD는 환경변수로만 받는다
47줄F08-L47 fromAccountId = [long]$from.accountId 출고표 47번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계좌 생성 응답의 numeric ID를 다음 transfer·대사 단계로 전달한다.
입력
$from
결과·효과
관찰 상태 F08-047가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
문자열 A/B를 long ID에 넣지 않는다
48줄F08-L48 toAccountId = [long]$to.accountId 출고표 48번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계좌 생성 응답의 numeric ID를 다음 transfer·대사 단계로 전달한다.
입력
$to
결과·효과
관찰 상태 F08-048가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset만으로 transfer Green은 아니다
49줄F08-L49 fromOpeningBalance = 10000 출고표 49번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 demo 계좌의 재현 가능한 시작 잔액을 요청 body에 넣는다.
입력
10000
결과·효과
관찰 상태 F08-049가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
FCL_DEMO_PASSWORD는 환경변수로만 받는다
50줄F08-L50 toOpeningBalance = 5000 출고표 50번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 demo 계좌의 재현 가능한 시작 잔액을 요청 body에 넣는다.
입력
5000
결과·효과
관찰 상태 F08-050가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
문자열 A/B를 long ID에 넣지 않는다
51줄F08-L51 } 출고표 51번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F08-051가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset만으로 transfer Green은 아니다
52줄F08-L52 $parent = Split-Path -Parent $StatePath 출고표 52번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$parent, $StatePath
결과·효과
관찰 상태 F08-052가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
FCL_DEMO_PASSWORD는 환경변수로만 받는다
53줄F08-L53 if (-not [string]::IsNullOrWhiteSpace($parent)) { 출고표 53번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$parent
결과·효과
관찰 상태 F08-053가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
문자열 A/B를 long ID에 넣지 않는다
54줄F08-L54 New-Item -ItemType Directory -Force -Path $parent | Out-Null 출고표 54번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
입력
$parent
결과·효과
관찰 상태 F08-054가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset만으로 transfer Green은 아니다
55줄F08-L55 } 출고표 55번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 from=10000
결과·효과
관찰 상태 F08-055가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
FCL_DEMO_PASSWORD는 환경변수로만 받는다
56줄F08-L56 $state | ConvertTo-Json | Set-Content -LiteralPath $StatePath -Encoding utf8 출고표 56번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 검증된 object를 JSON evidence text로 직렬화한다.
입력
$state, $StatePath
결과·효과
관찰 상태 F08-056가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
문자열 A/B를 long ID에 넣지 않는다
57줄F08-L57 "DEMO_RESET_OK runId=$RunId from=$($state.fromAccountId) to=$($state.toAccountId)" 출고표 57번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계좌 생성 응답의 numeric ID를 다음 transfer·대사 단계로 전달한다.
입력
$RunId, $state, $state
결과·효과
관찰 상태 F08-057가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset만으로 transfer Green은 아니다
05

STEP 05 / 13

원본 코드 조각

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

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

F08-C01 · 원문 1–12줄1–12줄
1–12줄 원본
param(
  [string]$RunId = "w24-$([DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds())",
  [string]$StatePath = 'evidence\w24\demo-state.json',
  [string]$BaseUrl = ''
)

$ErrorActionPreference = 'Stop'
$BaseUrl = if (-not [string]::IsNullOrWhiteSpace($BaseUrl)) {
  $BaseUrl
} elseif (-not [string]::IsNullOrWhiteSpace($env:FCL_BASE_URL)) {
  $env:FCL_BASE_URL
} else {
F08-C02 · 원문 13–24줄13–24줄
13–24줄 원본
  'http://localhost:8080'
}
$user = $env:FCL_DEMO_USER
$password = $env:FCL_DEMO_PASSWORD
if ([string]::IsNullOrWhiteSpace($user) -or [string]::IsNullOrWhiteSpace($password)) {
  throw 'Set FCL_DEMO_USER and FCL_DEMO_PASSWORD in this terminal only.'
}
if ($RunId -notmatch '^[A-Za-z0-9-]{1,18}$') {
  throw 'RunId must be 1-18 ASCII letters, digits, or hyphens.'
}

$pair = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("${user}:${password}"))
F08-C03 · 원문 25–36줄25–36줄
25–36줄 원본
$headers = @{ Authorization = "Basic $pair" }

function New-DemoAccount([string]$Suffix, [long]$OpeningBalance) {
  $accountNo = "DEMO-$RunId-$Suffix"
  $body = @{ accountNo = $accountNo; openingBalance = $OpeningBalance } |
    ConvertTo-Json -Compress
  $response = Invoke-RestMethod -Method Post -Uri "$BaseUrl/api/accounts" `
    -Headers ($headers + @{ 'X-Request-Id' = "w24-open-$Suffix-$RunId" }) `
    -ContentType 'application/json' -Body $body
  if ([long]$response.accountId -le 0 -or $response.accountNo -cne $accountNo -or
      [long]$response.balance -ne $OpeningBalance) {
    throw "account response mismatch: $($response | ConvertTo-Json -Compress)"
F08-C04 · 원문 37–48줄37–48줄
37–48줄 원본
  }
  return $response
}

$from = New-DemoAccount -Suffix 'FROM' -OpeningBalance 10000
$to = New-DemoAccount -Suffix 'TO' -OpeningBalance 5000
$state = [ordered]@{
  runId = $RunId
  baseUrl = $BaseUrl
  actor = $user
  fromAccountId = [long]$from.accountId
  toAccountId = [long]$to.accountId
F08-C05 · 원문 49–57줄49–57줄
49–57줄 원본
  fromOpeningBalance = 10000
  toOpeningBalance = 5000
}
$parent = Split-Path -Parent $StatePath
if (-not [string]::IsNullOrWhiteSpace($parent)) {
  New-Item -ItemType Directory -Force -Path $parent | Out-Null
}
$state | ConvertTo-Json | Set-Content -LiteralPath $StatePath -Encoding utf8
"DEMO_RESET_OK runId=$RunId from=$($state.fromAccountId) to=$($state.toAccountId)"
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

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

전체 번역 53 / 53

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

원본한국어 번역
1param(실행 의미: PowerShell script가 받을 입력 계약을 연다.
2 [string]$RunId = "w24-$([DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds())",실행 의미: reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
3 [string]$StatePath = 'evidence\w24\demo-state.json',실행 의미: reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
4 [string]$BaseUrl = ''실행 의미: reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
5)실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
7$ErrorActionPreference = 'Stop'실행 의미: PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다.
8$BaseUrl = if (-not [string]::IsNullOrWhiteSpace($BaseUrl)) {실행 의미: 조건·반복·함수의 실행 block을 연다.
9 $BaseUrl실행 의미: reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
10} elseif (-not [string]::IsNullOrWhiteSpace($env:FCL_BASE_URL)) {실행 의미: 조건·반복·함수의 실행 block을 연다.
11 $env:FCL_BASE_URL실행 의미: reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
12} else {실행 의미: 조건·반복·함수의 실행 block을 연다.
13 'http://localhost:8080'실행 의미: reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
14}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
15$user = $env:FCL_DEMO_USER실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
16$password = $env:FCL_DEMO_PASSWORD실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
17if ([string]::IsNullOrWhiteSpace($user) -or [string]::IsNullOrWhiteSpace($password)) {실행 의미: 조건·반복·함수의 실행 block을 연다.
18 throw 'Set FCL_DEMO_USER and FCL_DEMO_PASSWORD in this terminal only.'실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
19}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
20if ($RunId -notmatch '^[A-Za-z0-9-]{1,18}$') {실행 의미: 조건·반복·함수의 실행 block을 연다.
21 throw 'RunId must be 1-18 ASCII letters, digits, or hyphens.'실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
22}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
24$pair = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("${user}:${password}"))실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
25$headers = @{ Authorization = "Basic $pair" }실행 의미: 인증 header를 runtime에서 만들되 evidence에 원문 비밀을 남기지 않는다.
27function New-DemoAccount([string]$Suffix, [long]$OpeningBalance) {실행 의미: demo 계좌의 재현 가능한 시작 잔액을 요청 body에 넣는다.
28 $accountNo = "DEMO-$RunId-$Suffix"실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
29 $body = @{ accountNo = $accountNo; openingBalance = $OpeningBalance } |실행 의미: demo 계좌의 재현 가능한 시작 잔액을 요청 body에 넣는다.
30 ConvertTo-Json -Compress실행 의미: 검증된 object를 JSON evidence text로 직렬화한다.
31 $response = Invoke-RestMethod -Method Post -Uri "$BaseUrl/api/accounts" `실행 의미: HTTP API를 호출해 status와 JSON response를 받는다.
32 -Headers ($headers + @{ 'X-Request-Id' = "w24-open-$Suffix-$RunId" }) `실행 의미: reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
33 -ContentType 'application/json' -Body $body실행 의미: reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
34 if ([long]$response.accountId -le 0 -or $response.accountNo -cne $accountNo -or실행 의미: 계좌 생성 응답의 numeric ID를 다음 transfer·대사 단계로 전달한다.
35 [long]$response.balance -ne $OpeningBalance) {실행 의미: demo 계좌의 재현 가능한 시작 잔액을 요청 body에 넣는다.
36 throw "account response mismatch: $($response | ConvertTo-Json -Compress)"실행 의미: 검증된 object를 JSON evidence text로 직렬화한다.
37 }실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
38 return $response실행 의미: reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
39}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
41$from = New-DemoAccount -Suffix 'FROM' -OpeningBalance 10000실행 의미: demo 계좌의 재현 가능한 시작 잔액을 요청 body에 넣는다.
42$to = New-DemoAccount -Suffix 'TO' -OpeningBalance 5000실행 의미: demo 계좌의 재현 가능한 시작 잔액을 요청 body에 넣는다.
43$state = [ordered]@{실행 의미: 조건·반복·함수의 실행 block을 연다.
44 runId = $RunId실행 의미: reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
45 baseUrl = $BaseUrl실행 의미: reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
46 actor = $user실행 의미: reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
47 fromAccountId = [long]$from.accountId실행 의미: 계좌 생성 응답의 numeric ID를 다음 transfer·대사 단계로 전달한다.
48 toAccountId = [long]$to.accountId실행 의미: 계좌 생성 응답의 numeric ID를 다음 transfer·대사 단계로 전달한다.
49 fromOpeningBalance = 10000실행 의미: demo 계좌의 재현 가능한 시작 잔액을 요청 body에 넣는다.
50 toOpeningBalance = 5000실행 의미: demo 계좌의 재현 가능한 시작 잔액을 요청 body에 넣는다.
51}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
52$parent = Split-Path -Parent $StatePath실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
53if (-not [string]::IsNullOrWhiteSpace($parent)) {실행 의미: 조건·반복·함수의 실행 block을 연다.
54 New-Item -ItemType Directory -Force -Path $parent | Out-Null실행 의미: Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
55}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
56$state | ConvertTo-Json | Set-Content -LiteralPath $StatePath -Encoding utf8실행 의미: 검증된 object를 JSON evidence text로 직렬화한다.
57"DEMO_RESET_OK runId=$RunId from=$($state.fromAccountId) to=$($state.toAccountId)"실행 의미: 계좌 생성 응답의 numeric ID를 다음 transfer·대사 단계로 전달한다.
07

STEP 07 / 13

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

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

한 줄로 읽기

reset-demo.ps1 — 계좌 응답의 numeric ID를 state로 연결는 customer-1 인증으로 두 계좌를 만들고 반환된 양의 정수 accountId와 시작 잔액을 비밀 없는 demo-state.json에 저장한다.

문법 해부

  • .ps1 문법에서 선언·조건·pipeline·block 경계를 먼저 나눈다.
  • expected 값과 actual 결과를 같은 이름처럼 보여도 서로 다른 source로 읽는다.
  • native exit·row count·hash·사람 판정을 서로 대체하지 않는다.

실행 순서

  1. 입력 경로·fixture·환경변수·expected 계약을 고정한다.
  2. source가 실행하는 native process·HTTP·SQL 또는 형식 검사를 따라간다.
  3. actual 값과 exact marker를 대조하고 실패면 성공 발행 전에 중단한다.
  4. finally cleanup과 비범위를 evidence에 남긴다.

W24 조각별 정밀 해설

F08-C01 · 원문 1–12줄
문법 해부
.ps1 문법으로 1–12줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
from=10000, to=5000, numeric accountId를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
FCL_DEMO_PASSWORD는 환경변수로만 받는다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
FCL_DEMO_PASSWORD는 환경변수로만 받는다; 문자열 A/B를 long ID에 넣지 않는다; reset만으로 transfer Green은 아니다
다음 연결
다음 조각 또는 F08 evidence 판정으로 상태를 넘긴다.
F08-C02 · 원문 13–24줄
문법 해부
.ps1 문법으로 13–24줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
from=10000, to=5000, numeric accountId를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
FCL_DEMO_PASSWORD는 환경변수로만 받는다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
FCL_DEMO_PASSWORD는 환경변수로만 받는다; 문자열 A/B를 long ID에 넣지 않는다; reset만으로 transfer Green은 아니다
다음 연결
다음 조각 또는 F08 evidence 판정으로 상태를 넘긴다.
F08-C03 · 원문 25–36줄
문법 해부
.ps1 문법으로 25–36줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
from=10000, to=5000, numeric accountId를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
FCL_DEMO_PASSWORD는 환경변수로만 받는다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
FCL_DEMO_PASSWORD는 환경변수로만 받는다; 문자열 A/B를 long ID에 넣지 않는다; reset만으로 transfer Green은 아니다
다음 연결
다음 조각 또는 F08 evidence 판정으로 상태를 넘긴다.
F08-C04 · 원문 37–48줄
문법 해부
.ps1 문법으로 37–48줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
from=10000, to=5000, numeric accountId를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
FCL_DEMO_PASSWORD는 환경변수로만 받는다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
FCL_DEMO_PASSWORD는 환경변수로만 받는다; 문자열 A/B를 long ID에 넣지 않는다; reset만으로 transfer Green은 아니다
다음 연결
다음 조각 또는 F08 evidence 판정으로 상태를 넘긴다.
F08-C05 · 원문 49–57줄
문법 해부
.ps1 문법으로 49–57줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
from=10000, to=5000, numeric accountId를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
FCL_DEMO_PASSWORD는 환경변수로만 받는다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
FCL_DEMO_PASSWORD는 환경변수로만 받는다; 문자열 A/B를 long ID에 넣지 않는다; reset만으로 transfer Green은 아니다
다음 연결
다음 조각 또는 F08 evidence 판정으로 상태를 넘긴다.
실행 순서 — reset-demo.ps1 — 계좌 응답의 numeric ID를 state로 연결히토리 → 니지카 → 료 → 키타
  1. 히토리

    to=5000가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 customer-1 인증으로 두 계좌를 만들고 반환된 양의 정수 accountId와 시작 잔액을 비밀 없는 demo-state.json에 저장한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘문자열 A/B를 long ID에 넣지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 to=5000와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

08

STEP 08 / 13

실제 값 따라가기

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

순서들어온 값코드가 하는 일나온 값·상태경계
입력from=10000source 계약에 대입F08 실행/설명 시작 상태FCL_DEMO_PASSWORD는 환경변수로만 받는다
검증to=5000expected와 actual 또는 형식 대조통과 또는 첫 mismatch문자열 A/B를 long ID에 넣지 않는다
증거DEMO_RESET_OKmarker·hash·row를 같은 run에 연결범위가 적힌 evidence 후보reset만으로 transfer Green은 아니다
실제 값 — reset-demo.ps1 — 계좌 응답의 numeric ID를 state로 연결히토리 → 니지카 → 료 → 키타
  1. 히토리

    numeric accountId가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 customer-1 인증으로 두 계좌를 만들고 반환된 양의 정수 accountId와 시작 잔액을 비밀 없는 demo-state.json에 저장한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘reset만으로 transfer Green은 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 numeric accountId와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

09

STEP 09 / 13

Gradle·PowerShell·HTTP·PostgreSQL 내부에서 벌어지는 일

Gradle·JUnit XML·PowerShell·HTTP·PostgreSQL·Docker에서 실제로 일어나는 일과 증명 범위를 구분합니다.

source/contract

reset-demo.ps1 bytes와 expected 값을 읽는다.

파일 존재만으로 runtime 성공은 아니다.
execution/evidence

native exit·HTTP status·JUnit XML·DB row·hash 중 이 파일이 소유한 값을 만든다.

FCL_DEMO_PASSWORD는 환경변수로만 받는다
release/human

관련 evidence와 사람 의미 검토를 release 후보에 연결한다.

reset만으로 transfer Green은 아니다
첫 실패 경계 — reset-demo.ps1 — 계좌 응답의 numeric ID를 state로 연결히토리 → 니지카 → 료 → 키타
  1. 히토리

    DEMO_RESET_OK가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 customer-1 인증으로 두 계좌를 만들고 반환된 양의 정수 accountId와 시작 잔액을 비밀 없는 demo-state.json에 저장한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘FCL_DEMO_PASSWORD는 환경변수로만 받는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 DEMO_RESET_OK와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

10

STEP 10 / 13

흔한 착각과 틀린 예

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

❌ from=10000 문자열이 source에 있으니 실제 실행도 Green이다.

왜 틀리나 source literal과 runtime 관찰값은 다른 증거다.

바르게 읽기 native exit·actual XML/HTTP/DB evidence를 별도로 확인한다.

반례 script가 실행 전 경로 오류로 멈춰도 literal은 그대로 남는다.

❌ 파일 SHA-256이 있으면 내용의 의미와 사실성도 검증됐다.

왜 틀리나 hash는 동일 bytes만 말한다.

바르게 읽기 schema·수치·질문·근거는 별도 자동 또는 사람 판정을 거친다.

반례 빈 review 질문을 가진 CSV도 안정된 hash를 가진다.

❌ LOCAL_ARTIFACT_VALIDATED는 release Green과 같다.

왜 틀리나 generic validator는 파일 shape만 확인한다.

바르게 읽기 HUMAN_SEMANTIC_REVIEW_REQUIRED를 유지한다.

반례 잘못된 track 점수표도 byte 수 조건은 통과할 수 있다.

❌ 이 파일이 W24 전체 lifecycle을 모두 소유한다.

왜 틀리나 각 source는 Gate·demo·cleanup·사람 review 중 일부만 담당한다.

바르게 읽기 owner와 non-responsibility를 release manifest에서 분리한다.

반례 D4 source audit에는 runtime_claim=false가 명시된다.

❌ 이전 주 Green이나 오래된 log를 현재 commit 결과로 재사용한다.

왜 틀리나 source·commit·actual result가 같은 실행에 묶이지 않는다.

바르게 읽기 release 후보에서 새 evidence와 hash를 만든다.

반례 expected JSON이 바뀌면 예전 XML은 exact inventory를 증명하지 못한다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

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

증명 범위

FCL_DEMO_PASSWORD는 환경변수로만 받는다

이 책임을 맡는 곳: runtime Gate
증명 범위

문자열 A/B를 long ID에 넣지 않는다

이 책임을 맡는 곳: external/human review
증명 범위

reset만으로 transfer Green은 아니다

이 책임을 맡는 곳: release manifest
증명 범위

FCL_DEMO_PASSWORD는 환경변수로만 받는다

이 책임을 맡는 곳: 운영 환경
증명하지 않는 범위 — reset-demo.ps1 — 계좌 응답의 numeric ID를 state로 연결히토리 → 니지카 → 료 → 키타
  1. 히토리

    from=10000가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 customer-1 인증으로 두 계좌를 만들고 반환된 양의 정수 accountId와 시작 잔액을 비밀 없는 demo-state.json에 저장한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘문자열 A/B를 long ID에 넣지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 from=10000와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

12

STEP 12 / 13

직접 다시 써보기

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

1단계 · 뜻부터 복원

  • customer-1 인증으로 두 계좌를 만들고 반환된 양의 정수 accountId와 시작 잔액을 비밀 없는 demo-state.json에 저장한다.
  • 핵심 값은 from=10000, to=5000, numeric accountId, DEMO_RESET_OK다.

2단계 · 코드 조각 재조립

  1. 1. PowerShell script가 받을 입력 계약을 연다
  2. 2. reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다
  3. 3. reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다
  4. 4. reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다
  5. 5. 앞에서 연 block 또는 호출 범위를 닫는다
  6. 7. PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다
  7. 8. 조건·반복·함수의 실행 block을 연다
  8. 9. reset-demo.ps1의 다음 검증 또는 설명 단계를 구성한다

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

scripts/reset-demo.ps1을 새 파일에 다시 쓰고 expected·actual·실패·cleanup·비범위를 주석으로 표시한다.

자가 점검
  • 비어 있지 않은 모든 source 줄을 한 번씩 읽었나?
  • source shape와 runtime Green을 분리했나?
  • 사람 검토·외부 상태를 자동 성공으로 꾸미지 않았나?
  • 첫 실패와 cleanup 책임을 설명할 수 있나?
13

STEP 13 / 13

전체 원본 source

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

원문 정본 전체 source 확인하기
PDF 전문 정본 · packaged PowerShell sourcescripts/reset-demo.ps1SHA-256 f8faf779549b6e089cf9c4827f155369517e68e15664e3a0fccf33936161e7fb
reset-demo.ps1 — 계좌 응답의 numeric ID를 state로 연결 전체
param(
  [string]$RunId = "w24-$([DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds())",
  [string]$StatePath = 'evidence\w24\demo-state.json',
  [string]$BaseUrl = ''
)

$ErrorActionPreference = 'Stop'
$BaseUrl = if (-not [string]::IsNullOrWhiteSpace($BaseUrl)) {
  $BaseUrl
} elseif (-not [string]::IsNullOrWhiteSpace($env:FCL_BASE_URL)) {
  $env:FCL_BASE_URL
} else {
  'http://localhost:8080'
}
$user = $env:FCL_DEMO_USER
$password = $env:FCL_DEMO_PASSWORD
if ([string]::IsNullOrWhiteSpace($user) -or [string]::IsNullOrWhiteSpace($password)) {
  throw 'Set FCL_DEMO_USER and FCL_DEMO_PASSWORD in this terminal only.'
}
if ($RunId -notmatch '^[A-Za-z0-9-]{1,18}$') {
  throw 'RunId must be 1-18 ASCII letters, digits, or hyphens.'
}

$pair = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("${user}:${password}"))
$headers = @{ Authorization = "Basic $pair" }

function New-DemoAccount([string]$Suffix, [long]$OpeningBalance) {
  $accountNo = "DEMO-$RunId-$Suffix"
  $body = @{ accountNo = $accountNo; openingBalance = $OpeningBalance } |
    ConvertTo-Json -Compress
  $response = Invoke-RestMethod -Method Post -Uri "$BaseUrl/api/accounts" `
    -Headers ($headers + @{ 'X-Request-Id' = "w24-open-$Suffix-$RunId" }) `
    -ContentType 'application/json' -Body $body
  if ([long]$response.accountId -le 0 -or $response.accountNo -cne $accountNo -or
      [long]$response.balance -ne $OpeningBalance) {
    throw "account response mismatch: $($response | ConvertTo-Json -Compress)"
  }
  return $response
}

$from = New-DemoAccount -Suffix 'FROM' -OpeningBalance 10000
$to = New-DemoAccount -Suffix 'TO' -OpeningBalance 5000
$state = [ordered]@{
  runId = $RunId
  baseUrl = $BaseUrl
  actor = $user
  fromAccountId = [long]$from.accountId
  toAccountId = [long]$to.accountId
  fromOpeningBalance = 10000
  toOpeningBalance = 5000
}
$parent = Split-Path -Parent $StatePath
if (-not [string]::IsNullOrWhiteSpace($parent)) {
  New-Item -ItemType Directory -Force -Path $parent | Out-Null
}
$state | ConvertTo-Json | Set-Content -LiteralPath $StatePath -Encoding utf8
"DEMO_RESET_OK runId=$RunId from=$($state.fromAccountId) to=$($state.toAccountId)"
09

run-transfer.ps1 — canonical JSON과 201·200·409 계약

scripts/run-transfer.ps1

PDF 전문 정본 · packaged PowerShell source · 정본 · W24-F09
58줄 연결58줄 번역6 chunks
01

STEP 01 / 13

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

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

오늘의 한 문장

state의 numeric accountId로 transfer JSON을 만들고 idempotency key·amount별 예상 HTTP status와 response를 기록한다.

  1. 201 first은 어느 source와 실제 결과에서 확인해야 할까?
  2. 첫 실패를 만드는 조건과 fail-closed 지점은 어디일까?
  3. 왜 ‘reset state가 없거나 ID가 잘못되면 실패한다’를 별도 경계로 남겨야 할까?
이 파일에서 끝까지 다시 쓰는 값201 first200 replay409 conflictamount 1000/2000
왜 필요한가 — run-transfer.ps1 — canonical JSON과 201·200·409 계약히토리 → 니지카 → 료 → 키타
  1. 히토리

    201 first가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 state의 numeric accountId로 transfer JSON을 만들고 idempotency key·amount별 예상 HTTP status와 response를 기록한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘reset state가 없거나 ID가 잘못되면 실패한다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 201 first와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

02

STEP 02 / 13

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

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

새 기능을 멈춘 팀이 코드·test·문서·demo를 같은 release 후보에 묶어 하나씩 검수한다.

검수 도장이 붙은 공통 거래 코어 출고 상자

이 파일은 state의 numeric accountId로 transfer JSON을 만들고 idempotency key·amount별 예상 HTTP status와 response를 기록한다. 눈으로 읽을 때는 각 줄을 검수표 한 칸처럼 보고, 입력과 다음 상태를 놓치지 않는다.

마지막 도장은 source shape와 실제 runtime·사람 검토를 구분한 뒤에만 찍는다. 특히 reset state가 없거나 ID가 잘못되면 실패한다

딱 여기까지만 비유는 실행 순서를 돕지만 실제 Gradle·Docker·DB·사람 review를 대신하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

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

값 1: 201 first

이 파일에서 계속 확인할 고정 단서가 201 first다.

코드 연결
F09 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
reset state가 없거나 ID가 잘못되면 실패한다

값 2: 200 replay

이 파일에서 계속 확인할 고정 단서가 200 replay다.

코드 연결
F09 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
비밀번호 원문을 evidence에 쓰지 않는다

값 3: 409 conflict

이 파일에서 계속 확인할 고정 단서가 409 conflict다.

코드 연결
F09 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
DB 대사는 별도 script 책임이다

값 4: amount 1000/2000

이 파일에서 계속 확인할 고정 단서가 amount 1000/2000다.

코드 연결
F09 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
reset state가 없거나 ID가 잘못되면 실패한다
04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

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

단어 몇 개만 뽑은 표가 아닙니다.PDF 전문 정본 · packaged PowerShell source에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.58 / 58 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F09-L01 param( 출고표 1번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 PowerShell script가 받을 입력 계약을 연다.
입력
이전 줄의 상태와 201 first
결과·효과
관찰 상태 F09-001가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset state가 없거나 ID가 잘못되면 실패한다
2줄F09-L02 [Parameter(Mandatory=$true)][string]$Key, 출고표 2번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 인자가 빠지면 실행 시작 전에 binding을 거절한다.
입력
$true, $Key
결과·효과
관찰 상태 F09-002가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
3줄F09-L03 [Parameter(Mandatory=$true)][long]$Amount, 출고표 3번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 인자가 빠지면 실행 시작 전에 binding을 거절한다.
입력
$true, $Amount
결과·효과
관찰 상태 F09-003가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB 대사는 별도 script 책임이다
4줄F09-L04 [Parameter(Mandatory=$true)][ValidateSet(200, 201, 409)][int]$ExpectedStatus, 출고표 4번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 인자가 빠지면 실행 시작 전에 binding을 거절한다.
입력
$true, 200, 201
결과·효과
관찰 상태 F09-004가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset state가 없거나 ID가 잘못되면 실패한다
5줄F09-L05 [string]$StatePath = 'evidence\w24\demo-state.json' 출고표 5번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 run-transfer.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$StatePath, 'evidence\w24\demo-state.json'
결과·효과
관찰 상태 F09-005가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
6줄F09-L06 ) 출고표 6번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 201 first
결과·효과
관찰 상태 F09-006가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB 대사는 별도 script 책임이다
8줄F09-L08 $ErrorActionPreference = 'Stop' 출고표 8번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다.
입력
$ErrorActionPreference, 'Stop'
결과·효과
관찰 상태 F09-008가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
9줄F09-L09 $user = $env:FCL_DEMO_USER 출고표 9번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$user, $env
결과·효과
관찰 상태 F09-009가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB 대사는 별도 script 책임이다
10줄F09-L10 $password = $env:FCL_DEMO_PASSWORD 출고표 10번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$password, $env
결과·효과
관찰 상태 F09-010가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset state가 없거나 ID가 잘못되면 실패한다
11줄F09-L11 if ([string]::IsNullOrWhiteSpace($user) -or [string]::IsNullOrWhiteSpace($password)) { 출고표 11번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$user, $password
결과·효과
관찰 상태 F09-011가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
12줄F09-L12 throw 'Set FCL_DEMO_USER and FCL_DEMO_PASSWORD in this terminal only.' 출고표 12번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
이전 줄의 상태와 201 first
결과·효과
관찰 상태 F09-012가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB 대사는 별도 script 책임이다
13줄F09-L13 } 출고표 13번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 201 first
결과·효과
관찰 상태 F09-013가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset state가 없거나 ID가 잘못되면 실패한다
14줄F09-L14 if (!(Test-Path -LiteralPath $StatePath -PathType Leaf)) { 출고표 14번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 필수 파일이나 경로가 실제로 있는지 확인한다.
입력
$StatePath
결과·효과
관찰 상태 F09-014가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
15줄F09-L15 throw "Run reset-demo.ps1 first; missing state: $StatePath" 출고표 15번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
$StatePath
결과·효과
관찰 상태 F09-015가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB 대사는 별도 script 책임이다
16줄F09-L16 } 출고표 16번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 201 first
결과·효과
관찰 상태 F09-016가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset state가 없거나 ID가 잘못되면 실패한다
17줄F09-L17 $state = Get-Content -LiteralPath $StatePath -Raw | ConvertFrom-Json 출고표 17번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 JSON text를 필드로 접근 가능한 PowerShell object로 바꾼다.
입력
$state, $StatePath
결과·효과
관찰 상태 F09-017가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
18줄F09-L18 if ([long]$state.fromAccountId -le 0 -or [long]$state.toAccountId -le 0) { 출고표 18번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계좌 생성 응답의 numeric ID를 다음 transfer·대사 단계로 전달한다.
입력
$state, 0, $state
결과·효과
관찰 상태 F09-018가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB 대사는 별도 script 책임이다
19줄F09-L19 throw 'demo state has invalid numeric account IDs' 출고표 19번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
이전 줄의 상태와 201 first
결과·효과
관찰 상태 F09-019가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset state가 없거나 ID가 잘못되면 실패한다
20줄F09-L20 } 출고표 20번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 201 first
결과·효과
관찰 상태 F09-020가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
22줄F09-L22 $pair = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("${user}:${password}")) 출고표 22번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$pair, "${user}:${password}"
결과·효과
관찰 상태 F09-022가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset state가 없거나 ID가 잘못되면 실패한다
23줄F09-L23 $headers = @{ Authorization = "Basic $pair"; 'X-Request-Id' = "w24-transfer-$Key-$Amount" } 출고표 23번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 인증 header를 runtime에서 만들되 evidence에 원문 비밀을 남기지 않는다.
입력
$headers, "Basic $pair", 'X-Request-Id'
결과·효과
관찰 상태 F09-023가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
24줄F09-L24 $payload = @{ 출고표 24번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$payload
결과·효과
관찰 상태 F09-024가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB 대사는 별도 script 책임이다
25줄F09-L25 transactionId = $Key 출고표 25번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 run-transfer.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$Key
결과·효과
관찰 상태 F09-025가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset state가 없거나 ID가 잘못되면 실패한다
26줄F09-L26 fromAccountId = [long]$state.fromAccountId 출고표 26번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계좌 생성 응답의 numeric ID를 다음 transfer·대사 단계로 전달한다.
입력
$state
결과·효과
관찰 상태 F09-026가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
27줄F09-L27 toAccountId = [long]$state.toAccountId 출고표 27번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계좌 생성 응답의 numeric ID를 다음 transfer·대사 단계로 전달한다.
입력
$state
결과·효과
관찰 상태 F09-027가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB 대사는 별도 script 책임이다
28줄F09-L28 amount = $Amount 출고표 28번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 run-transfer.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$Amount
결과·효과
관찰 상태 F09-028가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset state가 없거나 ID가 잘못되면 실패한다
29줄F09-L29 } | ConvertTo-Json -Compress 출고표 29번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 검증된 object를 JSON evidence text로 직렬화한다.
입력
이전 줄의 상태와 201 first
결과·효과
관찰 상태 F09-029가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
31줄F09-L31 $status = 0 출고표 31번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$status, 0
결과·효과
관찰 상태 F09-031가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset state가 없거나 ID가 잘못되면 실패한다
32줄F09-L32 $body = '' 출고표 32번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$body
결과·효과
관찰 상태 F09-032가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
33줄F09-L33 try { 출고표 33번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
이전 줄의 상태와 201 first
결과·효과
관찰 상태 F09-033가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB 대사는 별도 script 책임이다
34줄F09-L34 $response = Invoke-WebRequest -UseBasicParsing -Method Post -Uri "$($state.baseUrl)/api/transfers" ` 출고표 34번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$response, "$($state.baseUrl)/api/transfers"
결과·효과
관찰 상태 F09-034가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset state가 없거나 ID가 잘못되면 실패한다
35줄F09-L35 -Headers $headers -ContentType 'application/json' -Body $payload 출고표 35번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 run-transfer.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$headers, 'application/json', $payload
결과·효과
관찰 상태 F09-035가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
36줄F09-L36 $status = [int]$response.StatusCode 출고표 36번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$status, $response
결과·효과
관찰 상태 F09-036가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB 대사는 별도 script 책임이다
37줄F09-L37 $body = [string]$response.Content 출고표 37번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$body, $response
결과·효과
관찰 상태 F09-037가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset state가 없거나 ID가 잘못되면 실패한다
38줄F09-L38 } catch { 출고표 38번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 실패 object를 보존해 cleanup 뒤 다시 실패시키도록 잡는다.
입력
이전 줄의 상태와 201 first
결과·효과
관찰 상태 F09-038가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
39줄F09-L39 $httpResponse = $_.Exception.Response 출고표 39번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$httpResponse, $_
결과·효과
관찰 상태 F09-039가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB 대사는 별도 script 책임이다
40줄F09-L40 if ($null -eq $httpResponse) { throw } 출고표 40번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
$null, $httpResponse
결과·효과
관찰 상태 F09-040가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset state가 없거나 ID가 잘못되면 실패한다
41줄F09-L41 $status = [int]$httpResponse.StatusCode 출고표 41번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$status, $httpResponse
결과·효과
관찰 상태 F09-041가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
42줄F09-L42 $stream = $httpResponse.GetResponseStream() 출고표 42번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$stream, $httpResponse
결과·효과
관찰 상태 F09-042가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB 대사는 별도 script 책임이다
43줄F09-L43 $reader = New-Object System.IO.StreamReader($stream) 출고표 43번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$reader, $stream
결과·효과
관찰 상태 F09-043가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset state가 없거나 ID가 잘못되면 실패한다
44줄F09-L44 try { $body = $reader.ReadToEnd() } finally { $reader.Dispose(); $stream.Dispose() } 출고표 44번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 중간 실패가 있어도 반드시 실행할 cleanup 경계를 연다.
입력
$body, $reader, $reader
결과·효과
관찰 상태 F09-044가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
45줄F09-L45 } 출고표 45번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 201 first
결과·효과
관찰 상태 F09-045가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB 대사는 별도 script 책임이다
47줄F09-L47 if ($status -ne $ExpectedStatus) { 출고표 47번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 각 demo 단계가 반드시 반환해야 할 HTTP status를 입력으로 고정한다.
입력
$status, $ExpectedStatus
결과·효과
관찰 상태 F09-047가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
48줄F09-L48 throw "unexpected transfer status expected=$ExpectedStatus actual=$status body=$body" 출고표 48번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 각 demo 단계가 반드시 반환해야 할 HTTP status를 입력으로 고정한다.
입력
$ExpectedStatus, $status, $body
결과·효과
관찰 상태 F09-048가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB 대사는 별도 script 책임이다
49줄F09-L49 } 출고표 49번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 201 first
결과·효과
관찰 상태 F09-049가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset state가 없거나 ID가 잘못되면 실패한다
50줄F09-L50 $json = $body | ConvertFrom-Json 출고표 50번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 JSON text를 필드로 접근 가능한 PowerShell object로 바꾼다.
입력
$json, $body
결과·효과
관찰 상태 F09-050가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
51줄F09-L51 if ($ExpectedStatus -eq 201) { 출고표 51번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 각 demo 단계가 반드시 반환해야 할 HTTP status를 입력으로 고정한다.
입력
$ExpectedStatus, 201
결과·효과
관찰 상태 F09-051가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB 대사는 별도 script 책임이다
52줄F09-L52 if ($json.transactionId -cne $Key -or $json.status -cne 'COMPLETED' -or [bool]$json.replayed) { 출고표 52번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$json, $Key, $json
결과·효과
관찰 상태 F09-052가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset state가 없거나 ID가 잘못되면 실패한다
53줄F09-L53 throw "first response contract mismatch: $body" 출고표 53번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
"first response contract mismatch: $body"
결과·효과
관찰 상태 F09-053가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
54줄F09-L54 } 출고표 54번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 201 first
결과·효과
관찰 상태 F09-054가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB 대사는 별도 script 책임이다
55줄F09-L55 } elseif ($ExpectedStatus -eq 200) { 출고표 55번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 각 demo 단계가 반드시 반환해야 할 HTTP status를 입력으로 고정한다.
입력
$ExpectedStatus, 200
결과·효과
관찰 상태 F09-055가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset state가 없거나 ID가 잘못되면 실패한다
56줄F09-L56 if ($json.transactionId -cne $Key -or $json.status -cne 'COMPLETED' -or -not [bool]$json.replayed) { 출고표 56번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$json, $Key, $json
결과·효과
관찰 상태 F09-056가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
57줄F09-L57 throw "replay response contract mismatch: $body" 출고표 57번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
"replay response contract mismatch: $body"
결과·효과
관찰 상태 F09-057가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB 대사는 별도 script 책임이다
58줄F09-L58 } 출고표 58번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 201 first
결과·효과
관찰 상태 F09-058가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset state가 없거나 ID가 잘못되면 실패한다
59줄F09-L59 } elseif ($json.errorCode -cne 'IDEMPOTENCY_CONFLICT') { 출고표 59번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 같은 actor·operation·key의 요청을 최초·replay·conflict로 구분한다.
입력
$json, 'IDEMPOTENCY_CONFLICT'
결과·효과
관찰 상태 F09-059가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
60줄F09-L60 throw "conflict response contract mismatch: $body" 출고표 60번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
$body
결과·효과
관찰 상태 F09-060가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB 대사는 별도 script 책임이다
61줄F09-L61 } 출고표 61번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 201 first
결과·효과
관찰 상태 F09-061가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
reset state가 없거나 ID가 잘못되면 실패한다
62줄F09-L62 "DEMO_TRANSFER_OK key=$Key amount=$Amount status=$status" 출고표 62번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 한 transfer 호출이 기대 status와 일치했음을 transcript에 남긴다.
입력
$Key, $Amount, $status
결과·효과
관찰 상태 F09-062가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
비밀번호 원문을 evidence에 쓰지 않는다
05

STEP 05 / 13

원본 코드 조각

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

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

F09-C01 · 원문 1–12줄1–12줄
1–12줄 원본
param(
  [Parameter(Mandatory=$true)][string]$Key,
  [Parameter(Mandatory=$true)][long]$Amount,
  [Parameter(Mandatory=$true)][ValidateSet(200, 201, 409)][int]$ExpectedStatus,
  [string]$StatePath = 'evidence\w24\demo-state.json'
)

$ErrorActionPreference = 'Stop'
$user = $env:FCL_DEMO_USER
$password = $env:FCL_DEMO_PASSWORD
if ([string]::IsNullOrWhiteSpace($user) -or [string]::IsNullOrWhiteSpace($password)) {
  throw 'Set FCL_DEMO_USER and FCL_DEMO_PASSWORD in this terminal only.'
F09-C02 · 원문 13–24줄13–24줄
13–24줄 원본
}
if (!(Test-Path -LiteralPath $StatePath -PathType Leaf)) {
  throw "Run reset-demo.ps1 first; missing state: $StatePath"
}
$state = Get-Content -LiteralPath $StatePath -Raw | ConvertFrom-Json
if ([long]$state.fromAccountId -le 0 -or [long]$state.toAccountId -le 0) {
  throw 'demo state has invalid numeric account IDs'
}

$pair = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("${user}:${password}"))
$headers = @{ Authorization = "Basic $pair"; 'X-Request-Id' = "w24-transfer-$Key-$Amount" }
$payload = @{
F09-C03 · 원문 25–36줄25–36줄
25–36줄 원본
  transactionId = $Key
  fromAccountId = [long]$state.fromAccountId
  toAccountId = [long]$state.toAccountId
  amount = $Amount
} | ConvertTo-Json -Compress

$status = 0
$body = ''
try {
  $response = Invoke-WebRequest -UseBasicParsing -Method Post -Uri "$($state.baseUrl)/api/transfers" `
    -Headers $headers -ContentType 'application/json' -Body $payload
  $status = [int]$response.StatusCode
F09-C04 · 원문 37–48줄37–48줄
37–48줄 원본
  $body = [string]$response.Content
} catch {
  $httpResponse = $_.Exception.Response
  if ($null -eq $httpResponse) { throw }
  $status = [int]$httpResponse.StatusCode
  $stream = $httpResponse.GetResponseStream()
  $reader = New-Object System.IO.StreamReader($stream)
  try { $body = $reader.ReadToEnd() } finally { $reader.Dispose(); $stream.Dispose() }
}

if ($status -ne $ExpectedStatus) {
  throw "unexpected transfer status expected=$ExpectedStatus actual=$status body=$body"
F09-C05 · 원문 49–60줄49–60줄
49–60줄 원본
}
$json = $body | ConvertFrom-Json
if ($ExpectedStatus -eq 201) {
  if ($json.transactionId -cne $Key -or $json.status -cne 'COMPLETED' -or [bool]$json.replayed) {
    throw "first response contract mismatch: $body"
  }
} elseif ($ExpectedStatus -eq 200) {
  if ($json.transactionId -cne $Key -or $json.status -cne 'COMPLETED' -or -not [bool]$json.replayed) {
    throw "replay response contract mismatch: $body"
  }
} elseif ($json.errorCode -cne 'IDEMPOTENCY_CONFLICT') {
  throw "conflict response contract mismatch: $body"
F09-C06 · 원문 61–62줄61–62줄
61–62줄 원본
}
"DEMO_TRANSFER_OK key=$Key amount=$Amount status=$status"
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

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

전체 번역 58 / 58

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

원본한국어 번역
1param(실행 의미: PowerShell script가 받을 입력 계약을 연다.
2 [Parameter(Mandatory=$true)][string]$Key,실행 의미: 이 인자가 빠지면 실행 시작 전에 binding을 거절한다.
3 [Parameter(Mandatory=$true)][long]$Amount,실행 의미: 이 인자가 빠지면 실행 시작 전에 binding을 거절한다.
4 [Parameter(Mandatory=$true)][ValidateSet(200, 201, 409)][int]$ExpectedStatus,실행 의미: 이 인자가 빠지면 실행 시작 전에 binding을 거절한다.
5 [string]$StatePath = 'evidence\w24\demo-state.json'실행 의미: run-transfer.ps1의 다음 검증 또는 설명 단계를 구성한다.
6)실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
8$ErrorActionPreference = 'Stop'실행 의미: PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다.
9$user = $env:FCL_DEMO_USER실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
10$password = $env:FCL_DEMO_PASSWORD실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
11if ([string]::IsNullOrWhiteSpace($user) -or [string]::IsNullOrWhiteSpace($password)) {실행 의미: 조건·반복·함수의 실행 block을 연다.
12 throw 'Set FCL_DEMO_USER and FCL_DEMO_PASSWORD in this terminal only.'실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
13}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
14if (!(Test-Path -LiteralPath $StatePath -PathType Leaf)) {실행 의미: 필수 파일이나 경로가 실제로 있는지 확인한다.
15 throw "Run reset-demo.ps1 first; missing state: $StatePath"실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
16}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
17$state = Get-Content -LiteralPath $StatePath -Raw | ConvertFrom-Json실행 의미: JSON text를 필드로 접근 가능한 PowerShell object로 바꾼다.
18if ([long]$state.fromAccountId -le 0 -or [long]$state.toAccountId -le 0) {실행 의미: 계좌 생성 응답의 numeric ID를 다음 transfer·대사 단계로 전달한다.
19 throw 'demo state has invalid numeric account IDs'실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
20}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
22$pair = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("${user}:${password}"))실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
23$headers = @{ Authorization = "Basic $pair"; 'X-Request-Id' = "w24-transfer-$Key-$Amount" }실행 의미: 인증 header를 runtime에서 만들되 evidence에 원문 비밀을 남기지 않는다.
24$payload = @{실행 의미: 조건·반복·함수의 실행 block을 연다.
25 transactionId = $Key실행 의미: run-transfer.ps1의 다음 검증 또는 설명 단계를 구성한다.
26 fromAccountId = [long]$state.fromAccountId실행 의미: 계좌 생성 응답의 numeric ID를 다음 transfer·대사 단계로 전달한다.
27 toAccountId = [long]$state.toAccountId실행 의미: 계좌 생성 응답의 numeric ID를 다음 transfer·대사 단계로 전달한다.
28 amount = $Amount실행 의미: run-transfer.ps1의 다음 검증 또는 설명 단계를 구성한다.
29} | ConvertTo-Json -Compress실행 의미: 검증된 object를 JSON evidence text로 직렬화한다.
31$status = 0실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
32$body = ''실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
33try {실행 의미: 조건·반복·함수의 실행 block을 연다.
34 $response = Invoke-WebRequest -UseBasicParsing -Method Post -Uri "$($state.baseUrl)/api/transfers" `실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
35 -Headers $headers -ContentType 'application/json' -Body $payload실행 의미: run-transfer.ps1의 다음 검증 또는 설명 단계를 구성한다.
36 $status = [int]$response.StatusCode실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
37 $body = [string]$response.Content실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
38} catch {실행 의미: 실패 object를 보존해 cleanup 뒤 다시 실패시키도록 잡는다.
39 $httpResponse = $_.Exception.Response실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
40 if ($null -eq $httpResponse) { throw }실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
41 $status = [int]$httpResponse.StatusCode실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
42 $stream = $httpResponse.GetResponseStream()실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
43 $reader = New-Object System.IO.StreamReader($stream)실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
44 try { $body = $reader.ReadToEnd() } finally { $reader.Dispose(); $stream.Dispose() }실행 의미: 중간 실패가 있어도 반드시 실행할 cleanup 경계를 연다.
45}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
47if ($status -ne $ExpectedStatus) {실행 의미: 각 demo 단계가 반드시 반환해야 할 HTTP status를 입력으로 고정한다.
48 throw "unexpected transfer status expected=$ExpectedStatus actual=$status body=$body"실행 의미: 각 demo 단계가 반드시 반환해야 할 HTTP status를 입력으로 고정한다.
49}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
50$json = $body | ConvertFrom-Json실행 의미: JSON text를 필드로 접근 가능한 PowerShell object로 바꾼다.
51if ($ExpectedStatus -eq 201) {실행 의미: 각 demo 단계가 반드시 반환해야 할 HTTP status를 입력으로 고정한다.
52 if ($json.transactionId -cne $Key -or $json.status -cne 'COMPLETED' -or [bool]$json.replayed) {실행 의미: 조건·반복·함수의 실행 block을 연다.
53 throw "first response contract mismatch: $body"실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
54 }실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
55} elseif ($ExpectedStatus -eq 200) {실행 의미: 각 demo 단계가 반드시 반환해야 할 HTTP status를 입력으로 고정한다.
56 if ($json.transactionId -cne $Key -or $json.status -cne 'COMPLETED' -or -not [bool]$json.replayed) {실행 의미: 조건·반복·함수의 실행 block을 연다.
57 throw "replay response contract mismatch: $body"실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
58 }실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
59} elseif ($json.errorCode -cne 'IDEMPOTENCY_CONFLICT') {실행 의미: 같은 actor·operation·key의 요청을 최초·replay·conflict로 구분한다.
60 throw "conflict response contract mismatch: $body"실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
61}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
62"DEMO_TRANSFER_OK key=$Key amount=$Amount status=$status"실행 의미: 한 transfer 호출이 기대 status와 일치했음을 transcript에 남긴다.
07

STEP 07 / 13

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

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

한 줄로 읽기

run-transfer.ps1 — canonical JSON과 201·200·409 계약는 state의 numeric accountId로 transfer JSON을 만들고 idempotency key·amount별 예상 HTTP status와 response를 기록한다.

문법 해부

  • .ps1 문법에서 선언·조건·pipeline·block 경계를 먼저 나눈다.
  • expected 값과 actual 결과를 같은 이름처럼 보여도 서로 다른 source로 읽는다.
  • native exit·row count·hash·사람 판정을 서로 대체하지 않는다.

실행 순서

  1. 입력 경로·fixture·환경변수·expected 계약을 고정한다.
  2. source가 실행하는 native process·HTTP·SQL 또는 형식 검사를 따라간다.
  3. actual 값과 exact marker를 대조하고 실패면 성공 발행 전에 중단한다.
  4. finally cleanup과 비범위를 evidence에 남긴다.

W24 조각별 정밀 해설

F09-C01 · 원문 1–12줄
문법 해부
.ps1 문법으로 1–12줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
201 first, 200 replay, 409 conflict를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
reset state가 없거나 ID가 잘못되면 실패한다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
reset state가 없거나 ID가 잘못되면 실패한다; 비밀번호 원문을 evidence에 쓰지 않는다; DB 대사는 별도 script 책임이다
다음 연결
다음 조각 또는 F09 evidence 판정으로 상태를 넘긴다.
F09-C02 · 원문 13–24줄
문법 해부
.ps1 문법으로 13–24줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
201 first, 200 replay, 409 conflict를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
reset state가 없거나 ID가 잘못되면 실패한다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
reset state가 없거나 ID가 잘못되면 실패한다; 비밀번호 원문을 evidence에 쓰지 않는다; DB 대사는 별도 script 책임이다
다음 연결
다음 조각 또는 F09 evidence 판정으로 상태를 넘긴다.
F09-C03 · 원문 25–36줄
문법 해부
.ps1 문법으로 25–36줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
201 first, 200 replay, 409 conflict를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
reset state가 없거나 ID가 잘못되면 실패한다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
reset state가 없거나 ID가 잘못되면 실패한다; 비밀번호 원문을 evidence에 쓰지 않는다; DB 대사는 별도 script 책임이다
다음 연결
다음 조각 또는 F09 evidence 판정으로 상태를 넘긴다.
F09-C04 · 원문 37–48줄
문법 해부
.ps1 문법으로 37–48줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
201 first, 200 replay, 409 conflict를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
reset state가 없거나 ID가 잘못되면 실패한다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
reset state가 없거나 ID가 잘못되면 실패한다; 비밀번호 원문을 evidence에 쓰지 않는다; DB 대사는 별도 script 책임이다
다음 연결
다음 조각 또는 F09 evidence 판정으로 상태를 넘긴다.
F09-C05 · 원문 49–60줄
문법 해부
.ps1 문법으로 49–60줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
201 first, 200 replay, 409 conflict를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
reset state가 없거나 ID가 잘못되면 실패한다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
reset state가 없거나 ID가 잘못되면 실패한다; 비밀번호 원문을 evidence에 쓰지 않는다; DB 대사는 별도 script 책임이다
다음 연결
다음 조각 또는 F09 evidence 판정으로 상태를 넘긴다.
F09-C06 · 원문 61–62줄
문법 해부
.ps1 문법으로 61–62줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
201 first, 200 replay, 409 conflict를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
reset state가 없거나 ID가 잘못되면 실패한다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
reset state가 없거나 ID가 잘못되면 실패한다; 비밀번호 원문을 evidence에 쓰지 않는다; DB 대사는 별도 script 책임이다
다음 연결
다음 조각 또는 F09 evidence 판정으로 상태를 넘긴다.
실행 순서 — run-transfer.ps1 — canonical JSON과 201·200·409 계약히토리 → 니지카 → 료 → 키타
  1. 히토리

    200 replay가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 state의 numeric accountId로 transfer JSON을 만들고 idempotency key·amount별 예상 HTTP status와 response를 기록한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘비밀번호 원문을 evidence에 쓰지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 200 replay와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

08

STEP 08 / 13

실제 값 따라가기

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

순서들어온 값코드가 하는 일나온 값·상태경계
입력201 firstsource 계약에 대입F09 실행/설명 시작 상태reset state가 없거나 ID가 잘못되면 실패한다
검증200 replayexpected와 actual 또는 형식 대조통과 또는 첫 mismatch비밀번호 원문을 evidence에 쓰지 않는다
증거amount 1000/2000marker·hash·row를 같은 run에 연결범위가 적힌 evidence 후보DB 대사는 별도 script 책임이다
실제 값 — run-transfer.ps1 — canonical JSON과 201·200·409 계약히토리 → 니지카 → 료 → 키타
  1. 히토리

    409 conflict가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 state의 numeric accountId로 transfer JSON을 만들고 idempotency key·amount별 예상 HTTP status와 response를 기록한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘DB 대사는 별도 script 책임이다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 409 conflict와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

09

STEP 09 / 13

Gradle·PowerShell·HTTP·PostgreSQL 내부에서 벌어지는 일

Gradle·JUnit XML·PowerShell·HTTP·PostgreSQL·Docker에서 실제로 일어나는 일과 증명 범위를 구분합니다.

source/contract

run-transfer.ps1 bytes와 expected 값을 읽는다.

파일 존재만으로 runtime 성공은 아니다.
execution/evidence

native exit·HTTP status·JUnit XML·DB row·hash 중 이 파일이 소유한 값을 만든다.

reset state가 없거나 ID가 잘못되면 실패한다
release/human

관련 evidence와 사람 의미 검토를 release 후보에 연결한다.

DB 대사는 별도 script 책임이다
첫 실패 경계 — run-transfer.ps1 — canonical JSON과 201·200·409 계약히토리 → 니지카 → 료 → 키타
  1. 히토리

    amount 1000/2000가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 state의 numeric accountId로 transfer JSON을 만들고 idempotency key·amount별 예상 HTTP status와 response를 기록한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘reset state가 없거나 ID가 잘못되면 실패한다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 amount 1000/2000와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

10

STEP 10 / 13

흔한 착각과 틀린 예

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

❌ 201 first 문자열이 source에 있으니 실제 실행도 Green이다.

왜 틀리나 source literal과 runtime 관찰값은 다른 증거다.

바르게 읽기 native exit·actual XML/HTTP/DB evidence를 별도로 확인한다.

반례 script가 실행 전 경로 오류로 멈춰도 literal은 그대로 남는다.

❌ 파일 SHA-256이 있으면 내용의 의미와 사실성도 검증됐다.

왜 틀리나 hash는 동일 bytes만 말한다.

바르게 읽기 schema·수치·질문·근거는 별도 자동 또는 사람 판정을 거친다.

반례 빈 review 질문을 가진 CSV도 안정된 hash를 가진다.

❌ LOCAL_ARTIFACT_VALIDATED는 release Green과 같다.

왜 틀리나 generic validator는 파일 shape만 확인한다.

바르게 읽기 HUMAN_SEMANTIC_REVIEW_REQUIRED를 유지한다.

반례 잘못된 track 점수표도 byte 수 조건은 통과할 수 있다.

❌ 이 파일이 W24 전체 lifecycle을 모두 소유한다.

왜 틀리나 각 source는 Gate·demo·cleanup·사람 review 중 일부만 담당한다.

바르게 읽기 owner와 non-responsibility를 release manifest에서 분리한다.

반례 D4 source audit에는 runtime_claim=false가 명시된다.

❌ 이전 주 Green이나 오래된 log를 현재 commit 결과로 재사용한다.

왜 틀리나 source·commit·actual result가 같은 실행에 묶이지 않는다.

바르게 읽기 release 후보에서 새 evidence와 hash를 만든다.

반례 expected JSON이 바뀌면 예전 XML은 exact inventory를 증명하지 못한다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

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

증명 범위

reset state가 없거나 ID가 잘못되면 실패한다

이 책임을 맡는 곳: runtime Gate
증명 범위

비밀번호 원문을 evidence에 쓰지 않는다

이 책임을 맡는 곳: external/human review
증명 범위

DB 대사는 별도 script 책임이다

이 책임을 맡는 곳: release manifest
증명 범위

reset state가 없거나 ID가 잘못되면 실패한다

이 책임을 맡는 곳: 운영 환경
증명하지 않는 범위 — run-transfer.ps1 — canonical JSON과 201·200·409 계약히토리 → 니지카 → 료 → 키타
  1. 히토리

    201 first가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 state의 numeric accountId로 transfer JSON을 만들고 idempotency key·amount별 예상 HTTP status와 response를 기록한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘비밀번호 원문을 evidence에 쓰지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 201 first와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

12

STEP 12 / 13

직접 다시 써보기

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

1단계 · 뜻부터 복원

  • state의 numeric accountId로 transfer JSON을 만들고 idempotency key·amount별 예상 HTTP status와 response를 기록한다.
  • 핵심 값은 201 first, 200 replay, 409 conflict, amount 1000/2000다.

2단계 · 코드 조각 재조립

  1. 1. PowerShell script가 받을 입력 계약을 연다
  2. 2. 이 인자가 빠지면 실행 시작 전에 binding을 거절한다
  3. 3. 이 인자가 빠지면 실행 시작 전에 binding을 거절한다
  4. 4. 이 인자가 빠지면 실행 시작 전에 binding을 거절한다
  5. 5. run-transfer.ps1의 다음 검증 또는 설명 단계를 구성한다
  6. 6. 앞에서 연 block 또는 호출 범위를 닫는다
  7. 8. PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다
  8. 9. 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다

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

scripts/run-transfer.ps1을 새 파일에 다시 쓰고 expected·actual·실패·cleanup·비범위를 주석으로 표시한다.

자가 점검
  • 비어 있지 않은 모든 source 줄을 한 번씩 읽었나?
  • source shape와 runtime Green을 분리했나?
  • 사람 검토·외부 상태를 자동 성공으로 꾸미지 않았나?
  • 첫 실패와 cleanup 책임을 설명할 수 있나?
13

STEP 13 / 13

전체 원본 source

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

원문 정본 전체 source 확인하기
PDF 전문 정본 · packaged PowerShell sourcescripts/run-transfer.ps1SHA-256 9562572c975baa6a844087eaff27ad7dfa499cb9a397e01e612563984f862284
run-transfer.ps1 — canonical JSON과 201·200·409 계약 전체
param(
  [Parameter(Mandatory=$true)][string]$Key,
  [Parameter(Mandatory=$true)][long]$Amount,
  [Parameter(Mandatory=$true)][ValidateSet(200, 201, 409)][int]$ExpectedStatus,
  [string]$StatePath = 'evidence\w24\demo-state.json'
)

$ErrorActionPreference = 'Stop'
$user = $env:FCL_DEMO_USER
$password = $env:FCL_DEMO_PASSWORD
if ([string]::IsNullOrWhiteSpace($user) -or [string]::IsNullOrWhiteSpace($password)) {
  throw 'Set FCL_DEMO_USER and FCL_DEMO_PASSWORD in this terminal only.'
}
if (!(Test-Path -LiteralPath $StatePath -PathType Leaf)) {
  throw "Run reset-demo.ps1 first; missing state: $StatePath"
}
$state = Get-Content -LiteralPath $StatePath -Raw | ConvertFrom-Json
if ([long]$state.fromAccountId -le 0 -or [long]$state.toAccountId -le 0) {
  throw 'demo state has invalid numeric account IDs'
}

$pair = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("${user}:${password}"))
$headers = @{ Authorization = "Basic $pair"; 'X-Request-Id' = "w24-transfer-$Key-$Amount" }
$payload = @{
  transactionId = $Key
  fromAccountId = [long]$state.fromAccountId
  toAccountId = [long]$state.toAccountId
  amount = $Amount
} | ConvertTo-Json -Compress

$status = 0
$body = ''
try {
  $response = Invoke-WebRequest -UseBasicParsing -Method Post -Uri "$($state.baseUrl)/api/transfers" `
    -Headers $headers -ContentType 'application/json' -Body $payload
  $status = [int]$response.StatusCode
  $body = [string]$response.Content
} catch {
  $httpResponse = $_.Exception.Response
  if ($null -eq $httpResponse) { throw }
  $status = [int]$httpResponse.StatusCode
  $stream = $httpResponse.GetResponseStream()
  $reader = New-Object System.IO.StreamReader($stream)
  try { $body = $reader.ReadToEnd() } finally { $reader.Dispose(); $stream.Dispose() }
}

if ($status -ne $ExpectedStatus) {
  throw "unexpected transfer status expected=$ExpectedStatus actual=$status body=$body"
}
$json = $body | ConvertFrom-Json
if ($ExpectedStatus -eq 201) {
  if ($json.transactionId -cne $Key -or $json.status -cne 'COMPLETED' -or [bool]$json.replayed) {
    throw "first response contract mismatch: $body"
  }
} elseif ($ExpectedStatus -eq 200) {
  if ($json.transactionId -cne $Key -or $json.status -cne 'COMPLETED' -or -not [bool]$json.replayed) {
    throw "replay response contract mismatch: $body"
  }
} elseif ($json.errorCode -cne 'IDEMPOTENCY_CONFLICT') {
  throw "conflict response contract mismatch: $body"
}
"DEMO_TRANSFER_OK key=$Key amount=$Amount status=$status"
10

reconcile-demo.ps1 — account와 ledger 합계 mismatch 0 검증

scripts/reconcile-demo.ps1

PDF 전문 정본 · packaged PowerShell source · 정본 · W24-F10
29줄 연결29줄 번역3 chunks
01

STEP 01 / 13

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

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

오늘의 한 문장

demo의 두 accountId를 대상으로 account.balance와 ledger_entry 합계를 비교해 mismatch가 정확히 0인지 확인한다.

  1. mismatches=0은 어느 source와 실제 결과에서 확인해야 할까?
  2. 첫 실패를 만드는 조건과 fail-closed 지점은 어디일까?
  3. 왜 ‘두 demo 계좌만 검증한다’를 별도 경계로 남겨야 할까?
이 파일에서 끝까지 다시 쓰는 값mismatches=0V001 accountledger_entryDEMO_RECONCILIATION_GREEN
왜 필요한가 — reconcile-demo.ps1 — account와 ledger 합계 mismatch 0 검증히토리 → 니지카 → 료 → 키타
  1. 히토리

    mismatches=0가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 demo의 두 accountId를 대상으로 account.balance와 ledger_entry 합계를 비교해 mismatch가 정확히 0인지 확인한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘두 demo 계좌만 검증한다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 mismatches=0와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

02

STEP 02 / 13

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

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

새 기능을 멈춘 팀이 코드·test·문서·demo를 같은 release 후보에 묶어 하나씩 검수한다.

검수 도장이 붙은 공통 거래 코어 출고 상자

이 파일은 demo의 두 accountId를 대상으로 account.balance와 ledger_entry 합계를 비교해 mismatch가 정확히 0인지 확인한다. 눈으로 읽을 때는 각 줄을 검수표 한 칸처럼 보고, 입력과 다음 상태를 놓치지 않는다.

마지막 도장은 source shape와 실제 runtime·사람 검토를 구분한 뒤에만 찍는다. 특히 두 demo 계좌만 검증한다

딱 여기까지만 비유는 실행 순서를 돕지만 실제 Gradle·Docker·DB·사람 review를 대신하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

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

값 1: mismatches=0

이 파일에서 계속 확인할 고정 단서가 mismatches=0다.

코드 연결
F10 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
두 demo 계좌만 검증한다

값 2: V001 account

이 파일에서 계속 확인할 고정 단서가 V001 account다.

코드 연결
F10 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
컨테이너·DB가 실제 실행 중이어야 한다

값 3: ledger_entry

이 파일에서 계속 확인할 고정 단서가 ledger_entry다.

코드 연결
F10 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
운영 전사 대사를 증명하지 않는다

값 4: DEMO_RECONCILIATION_GREEN

이 파일에서 계속 확인할 고정 단서가 DEMO_RECONCILIATION_GREEN다.

코드 연결
F10 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
두 demo 계좌만 검증한다
04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

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

단어 몇 개만 뽑은 표가 아닙니다.PDF 전문 정본 · packaged PowerShell source에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.29 / 29 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F10-L01 param( 출고표 1번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 PowerShell script가 받을 입력 계약을 연다.
입력
이전 줄의 상태와 mismatches=0
결과·효과
관찰 상태 F10-001가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 demo 계좌만 검증한다
2줄F10-L02 [string]$StatePath = 'evidence\w24\demo-state.json', 출고표 2번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 reconcile-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$StatePath, 'evidence\w24\demo-state.json'
결과·효과
관찰 상태 F10-002가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
컨테이너·DB가 실제 실행 중이어야 한다
3줄F10-L03 [Parameter(Mandatory=$true)][string]$Container 출고표 3번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 인자가 빠지면 실행 시작 전에 binding을 거절한다.
입력
$true, $Container
결과·효과
관찰 상태 F10-003가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
운영 전사 대사를 증명하지 않는다
4줄F10-L04 ) 출고표 4번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 mismatches=0
결과·효과
관찰 상태 F10-004가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 demo 계좌만 검증한다
6줄F10-L06 $ErrorActionPreference = 'Stop' 출고표 6번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다.
입력
$ErrorActionPreference, 'Stop'
결과·효과
관찰 상태 F10-006가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
운영 전사 대사를 증명하지 않는다
7줄F10-L07 if (!(Test-Path -LiteralPath $StatePath -PathType Leaf)) { 출고표 7번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 필수 파일이나 경로가 실제로 있는지 확인한다.
입력
$StatePath
결과·효과
관찰 상태 F10-007가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 demo 계좌만 검증한다
8줄F10-L08 throw "Run reset-demo.ps1 first; missing state: $StatePath" 출고표 8번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
$StatePath
결과·효과
관찰 상태 F10-008가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
컨테이너·DB가 실제 실행 중이어야 한다
9줄F10-L09 } 출고표 9번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 mismatches=0
결과·효과
관찰 상태 F10-009가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
운영 전사 대사를 증명하지 않는다
10줄F10-L10 $state = Get-Content -LiteralPath $StatePath -Raw | ConvertFrom-Json 출고표 10번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 JSON text를 필드로 접근 가능한 PowerShell object로 바꾼다.
입력
$state, $StatePath
결과·효과
관찰 상태 F10-010가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 demo 계좌만 검증한다
11줄F10-L11 $fromId = [long]$state.fromAccountId 출고표 11번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계좌 생성 응답의 numeric ID를 다음 transfer·대사 단계로 전달한다.
입력
$fromId, $state
결과·효과
관찰 상태 F10-011가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
컨테이너·DB가 실제 실행 중이어야 한다
12줄F10-L12 $toId = [long]$state.toAccountId 출고표 12번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계좌 생성 응답의 numeric ID를 다음 transfer·대사 단계로 전달한다.
입력
$toId, $state
결과·효과
관찰 상태 F10-012가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
운영 전사 대사를 증명하지 않는다
13줄F10-L13 if ($fromId -le 0 -or $toId -le 0) { throw 'demo state has invalid account IDs' } 출고표 13번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
$fromId, 0, $toId
결과·효과
관찰 상태 F10-013가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 demo 계좌만 검증한다
15줄F10-L15 $sql = @" 출고표 15번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$sql
결과·효과
관찰 상태 F10-015가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
운영 전사 대사를 증명하지 않는다
16줄F10-L16 SELECT COUNT(*) 출고표 16번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 mismatches=0
결과·효과
관찰 상태 F10-016가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 demo 계좌만 검증한다
17줄F10-L17 FROM ( 출고표 17번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 mismatches=0
결과·효과
관찰 상태 F10-017가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
컨테이너·DB가 실제 실행 중이어야 한다
18줄F10-L18 SELECT a.id 출고표 18번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 mismatches=0
결과·효과
관찰 상태 F10-018가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
운영 전사 대사를 증명하지 않는다
19줄F10-L19 FROM account a 출고표 19번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 mismatches=0
결과·효과
관찰 상태 F10-019가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 demo 계좌만 검증한다
20줄F10-L20 LEFT JOIN ledger_entry l ON l.account_id = a.id 출고표 20번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 reconcile-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 mismatches=0
결과·효과
관찰 상태 F10-020가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
컨테이너·DB가 실제 실행 중이어야 한다
21줄F10-L21 WHERE a.id IN ($fromId, $toId) 출고표 21번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
$fromId, $toId
결과·효과
관찰 상태 F10-021가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
운영 전사 대사를 증명하지 않는다
22줄F10-L22 GROUP BY a.id, a.balance 출고표 22번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 reconcile-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 mismatches=0
결과·효과
관찰 상태 F10-022가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 demo 계좌만 검증한다
23줄F10-L23 HAVING a.balance <> COALESCE(SUM(l.signed_amount), 0) 출고표 23번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 reconcile-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
0
결과·효과
관찰 상태 F10-023가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
컨테이너·DB가 실제 실행 중이어야 한다
24줄F10-L24 ) mismatch; 출고표 24번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 reconcile-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 mismatches=0
결과·효과
관찰 상태 F10-024가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
운영 전사 대사를 증명하지 않는다
25줄F10-L25 "@ 출고표 25번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 reconcile-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 mismatches=0
결과·효과
관찰 상태 F10-025가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 demo 계좌만 검증한다
26줄F10-L26 $raw = @($sql | docker exec -i $Container psql -X -qAt -v ON_ERROR_STOP=1 -U app -d financial_core 2>&1) 출고표 26번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
입력
$raw, $sql, $Container
결과·효과
관찰 상태 F10-026가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
컨테이너·DB가 실제 실행 중이어야 한다
27줄F10-L27 $exitCode = $LASTEXITCODE 출고표 27번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 native process 종료 코드를 검사해 실패를 놓치지 않는다.
입력
$exitCode, $LASTEXITCODE
결과·효과
관찰 상태 F10-027가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
운영 전사 대사를 증명하지 않는다
28줄F10-L28 if ($exitCode -ne 0) { throw "reconciliation query failed: $($raw -join "`n")" } 출고표 28번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 account balance와 ledger 합계를 비교해 mismatch를 찾는다.
입력
$exitCode, 0, $raw
결과·효과
관찰 상태 F10-028가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 demo 계좌만 검증한다
29줄F10-L29 $value = (@($raw | ForEach-Object { [string]$_ }) -join '').Trim() 출고표 29번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 고정 목록의 각 항목에 같은 검사를 반복 적용한다.
입력
$value, $raw, $_
결과·효과
관찰 상태 F10-029가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
컨테이너·DB가 실제 실행 중이어야 한다
30줄F10-L30 if ($value -cne '0') { throw "reconciliation mismatch count=$value" } 출고표 30번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 account balance와 ledger 합계를 비교해 mismatch를 찾는다.
입력
$value, '0', "reconciliation mismatch count=$value"
결과·효과
관찰 상태 F10-030가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
운영 전사 대사를 증명하지 않는다
31줄F10-L31 'DEMO_RECONCILIATION_GREEN mismatches=0' 출고표 31번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 account balance와 ledger 합계를 비교해 mismatch를 찾는다.
입력
'DEMO_RECONCILIATION_GREEN mismatches=0'
결과·효과
관찰 상태 F10-031가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 demo 계좌만 검증한다
05

STEP 05 / 13

원본 코드 조각

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

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

F10-C01 · 원문 1–12줄1–12줄
1–12줄 원본
param(
  [string]$StatePath = 'evidence\w24\demo-state.json',
  [Parameter(Mandatory=$true)][string]$Container
)

$ErrorActionPreference = 'Stop'
if (!(Test-Path -LiteralPath $StatePath -PathType Leaf)) {
  throw "Run reset-demo.ps1 first; missing state: $StatePath"
}
$state = Get-Content -LiteralPath $StatePath -Raw | ConvertFrom-Json
$fromId = [long]$state.fromAccountId
$toId = [long]$state.toAccountId
F10-C02 · 원문 13–24줄13–24줄
13–24줄 원본
if ($fromId -le 0 -or $toId -le 0) { throw 'demo state has invalid account IDs' }

$sql = @"
SELECT COUNT(*)
FROM (
  SELECT a.id
  FROM account a
  LEFT JOIN ledger_entry l ON l.account_id = a.id
  WHERE a.id IN ($fromId, $toId)
  GROUP BY a.id, a.balance
  HAVING a.balance <> COALESCE(SUM(l.signed_amount), 0)
) mismatch;
F10-C03 · 원문 25–31줄25–31줄
25–31줄 원본
"@
$raw = @($sql | docker exec -i $Container psql -X -qAt -v ON_ERROR_STOP=1 -U app -d financial_core 2>&1)
$exitCode = $LASTEXITCODE
if ($exitCode -ne 0) { throw "reconciliation query failed: $($raw -join "`n")" }
$value = (@($raw | ForEach-Object { [string]$_ }) -join '').Trim()
if ($value -cne '0') { throw "reconciliation mismatch count=$value" }
'DEMO_RECONCILIATION_GREEN mismatches=0'
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

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

전체 번역 29 / 29

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

원본한국어 번역
1param(실행 의미: PowerShell script가 받을 입력 계약을 연다.
2 [string]$StatePath = 'evidence\w24\demo-state.json',실행 의미: reconcile-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
3 [Parameter(Mandatory=$true)][string]$Container실행 의미: 이 인자가 빠지면 실행 시작 전에 binding을 거절한다.
4)실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
6$ErrorActionPreference = 'Stop'실행 의미: PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다.
7if (!(Test-Path -LiteralPath $StatePath -PathType Leaf)) {실행 의미: 필수 파일이나 경로가 실제로 있는지 확인한다.
8 throw "Run reset-demo.ps1 first; missing state: $StatePath"실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
9}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
10$state = Get-Content -LiteralPath $StatePath -Raw | ConvertFrom-Json실행 의미: JSON text를 필드로 접근 가능한 PowerShell object로 바꾼다.
11$fromId = [long]$state.fromAccountId실행 의미: 계좌 생성 응답의 numeric ID를 다음 transfer·대사 단계로 전달한다.
12$toId = [long]$state.toAccountId실행 의미: 계좌 생성 응답의 numeric ID를 다음 transfer·대사 단계로 전달한다.
13if ($fromId -le 0 -or $toId -le 0) { throw 'demo state has invalid account IDs' }실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
15$sql = @"실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
16SELECT COUNT(*)실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
17FROM (실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
18 SELECT a.id실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
19 FROM account a실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
20 LEFT JOIN ledger_entry l ON l.account_id = a.id실행 의미: reconcile-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
21 WHERE a.id IN ($fromId, $toId)실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
22 GROUP BY a.id, a.balance실행 의미: reconcile-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
23 HAVING a.balance <> COALESCE(SUM(l.signed_amount), 0)실행 의미: reconcile-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
24) mismatch;실행 의미: reconcile-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
25"@실행 의미: reconcile-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
26$raw = @($sql | docker exec -i $Container psql -X -qAt -v ON_ERROR_STOP=1 -U app -d financial_core 2>&1)실행 의미: Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
27$exitCode = $LASTEXITCODE실행 의미: native process 종료 코드를 검사해 실패를 놓치지 않는다.
28if ($exitCode -ne 0) { throw "reconciliation query failed: $($raw -join "`n")" }실행 의미: account balance와 ledger 합계를 비교해 mismatch를 찾는다.
29$value = (@($raw | ForEach-Object { [string]$_ }) -join '').Trim()실행 의미: 고정 목록의 각 항목에 같은 검사를 반복 적용한다.
30if ($value -cne '0') { throw "reconciliation mismatch count=$value" }실행 의미: account balance와 ledger 합계를 비교해 mismatch를 찾는다.
31'DEMO_RECONCILIATION_GREEN mismatches=0'실행 의미: account balance와 ledger 합계를 비교해 mismatch를 찾는다.
07

STEP 07 / 13

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

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

한 줄로 읽기

reconcile-demo.ps1 — account와 ledger 합계 mismatch 0 검증는 demo의 두 accountId를 대상으로 account.balance와 ledger_entry 합계를 비교해 mismatch가 정확히 0인지 확인한다.

문법 해부

  • .ps1 문법에서 선언·조건·pipeline·block 경계를 먼저 나눈다.
  • expected 값과 actual 결과를 같은 이름처럼 보여도 서로 다른 source로 읽는다.
  • native exit·row count·hash·사람 판정을 서로 대체하지 않는다.

실행 순서

  1. 입력 경로·fixture·환경변수·expected 계약을 고정한다.
  2. source가 실행하는 native process·HTTP·SQL 또는 형식 검사를 따라간다.
  3. actual 값과 exact marker를 대조하고 실패면 성공 발행 전에 중단한다.
  4. finally cleanup과 비범위를 evidence에 남긴다.

W24 조각별 정밀 해설

F10-C01 · 원문 1–12줄
문법 해부
.ps1 문법으로 1–12줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
mismatches=0, V001 account, ledger_entry를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
두 demo 계좌만 검증한다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
두 demo 계좌만 검증한다; 컨테이너·DB가 실제 실행 중이어야 한다; 운영 전사 대사를 증명하지 않는다
다음 연결
다음 조각 또는 F10 evidence 판정으로 상태를 넘긴다.
F10-C02 · 원문 13–24줄
문법 해부
.ps1 문법으로 13–24줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
mismatches=0, V001 account, ledger_entry를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
두 demo 계좌만 검증한다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
두 demo 계좌만 검증한다; 컨테이너·DB가 실제 실행 중이어야 한다; 운영 전사 대사를 증명하지 않는다
다음 연결
다음 조각 또는 F10 evidence 판정으로 상태를 넘긴다.
F10-C03 · 원문 25–31줄
문법 해부
.ps1 문법으로 25–31줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
mismatches=0, V001 account, ledger_entry를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
두 demo 계좌만 검증한다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
두 demo 계좌만 검증한다; 컨테이너·DB가 실제 실행 중이어야 한다; 운영 전사 대사를 증명하지 않는다
다음 연결
다음 조각 또는 F10 evidence 판정으로 상태를 넘긴다.
실행 순서 — reconcile-demo.ps1 — account와 ledger 합계 mismatch 0 검증히토리 → 니지카 → 료 → 키타
  1. 히토리

    V001 account가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 demo의 두 accountId를 대상으로 account.balance와 ledger_entry 합계를 비교해 mismatch가 정확히 0인지 확인한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘컨테이너·DB가 실제 실행 중이어야 한다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 V001 account와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

08

STEP 08 / 13

실제 값 따라가기

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

순서들어온 값코드가 하는 일나온 값·상태경계
입력mismatches=0source 계약에 대입F10 실행/설명 시작 상태두 demo 계좌만 검증한다
검증V001 accountexpected와 actual 또는 형식 대조통과 또는 첫 mismatch컨테이너·DB가 실제 실행 중이어야 한다
증거DEMO_RECONCILIATION_GREENmarker·hash·row를 같은 run에 연결범위가 적힌 evidence 후보운영 전사 대사를 증명하지 않는다
실제 값 — reconcile-demo.ps1 — account와 ledger 합계 mismatch 0 검증히토리 → 니지카 → 료 → 키타
  1. 히토리

    ledger_entry가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 demo의 두 accountId를 대상으로 account.balance와 ledger_entry 합계를 비교해 mismatch가 정확히 0인지 확인한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘운영 전사 대사를 증명하지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 ledger_entry와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

09

STEP 09 / 13

Gradle·PowerShell·HTTP·PostgreSQL 내부에서 벌어지는 일

Gradle·JUnit XML·PowerShell·HTTP·PostgreSQL·Docker에서 실제로 일어나는 일과 증명 범위를 구분합니다.

source/contract

reconcile-demo.ps1 bytes와 expected 값을 읽는다.

파일 존재만으로 runtime 성공은 아니다.
execution/evidence

native exit·HTTP status·JUnit XML·DB row·hash 중 이 파일이 소유한 값을 만든다.

두 demo 계좌만 검증한다
release/human

관련 evidence와 사람 의미 검토를 release 후보에 연결한다.

운영 전사 대사를 증명하지 않는다
첫 실패 경계 — reconcile-demo.ps1 — account와 ledger 합계 mismatch 0 검증히토리 → 니지카 → 료 → 키타
  1. 히토리

    DEMO_RECONCILIATION_GREEN가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 demo의 두 accountId를 대상으로 account.balance와 ledger_entry 합계를 비교해 mismatch가 정확히 0인지 확인한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘두 demo 계좌만 검증한다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 DEMO_RECONCILIATION_GREEN와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

10

STEP 10 / 13

흔한 착각과 틀린 예

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

❌ mismatches=0 문자열이 source에 있으니 실제 실행도 Green이다.

왜 틀리나 source literal과 runtime 관찰값은 다른 증거다.

바르게 읽기 native exit·actual XML/HTTP/DB evidence를 별도로 확인한다.

반례 script가 실행 전 경로 오류로 멈춰도 literal은 그대로 남는다.

❌ 파일 SHA-256이 있으면 내용의 의미와 사실성도 검증됐다.

왜 틀리나 hash는 동일 bytes만 말한다.

바르게 읽기 schema·수치·질문·근거는 별도 자동 또는 사람 판정을 거친다.

반례 빈 review 질문을 가진 CSV도 안정된 hash를 가진다.

❌ LOCAL_ARTIFACT_VALIDATED는 release Green과 같다.

왜 틀리나 generic validator는 파일 shape만 확인한다.

바르게 읽기 HUMAN_SEMANTIC_REVIEW_REQUIRED를 유지한다.

반례 잘못된 track 점수표도 byte 수 조건은 통과할 수 있다.

❌ 이 파일이 W24 전체 lifecycle을 모두 소유한다.

왜 틀리나 각 source는 Gate·demo·cleanup·사람 review 중 일부만 담당한다.

바르게 읽기 owner와 non-responsibility를 release manifest에서 분리한다.

반례 D4 source audit에는 runtime_claim=false가 명시된다.

❌ 이전 주 Green이나 오래된 log를 현재 commit 결과로 재사용한다.

왜 틀리나 source·commit·actual result가 같은 실행에 묶이지 않는다.

바르게 읽기 release 후보에서 새 evidence와 hash를 만든다.

반례 expected JSON이 바뀌면 예전 XML은 exact inventory를 증명하지 못한다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

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

증명 범위

두 demo 계좌만 검증한다

이 책임을 맡는 곳: runtime Gate
증명 범위

컨테이너·DB가 실제 실행 중이어야 한다

이 책임을 맡는 곳: external/human review
증명 범위

운영 전사 대사를 증명하지 않는다

이 책임을 맡는 곳: release manifest
증명 범위

두 demo 계좌만 검증한다

이 책임을 맡는 곳: 운영 환경
증명하지 않는 범위 — reconcile-demo.ps1 — account와 ledger 합계 mismatch 0 검증히토리 → 니지카 → 료 → 키타
  1. 히토리

    mismatches=0가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 demo의 두 accountId를 대상으로 account.balance와 ledger_entry 합계를 비교해 mismatch가 정확히 0인지 확인한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘컨테이너·DB가 실제 실행 중이어야 한다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 mismatches=0와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

12

STEP 12 / 13

직접 다시 써보기

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

1단계 · 뜻부터 복원

  • demo의 두 accountId를 대상으로 account.balance와 ledger_entry 합계를 비교해 mismatch가 정확히 0인지 확인한다.
  • 핵심 값은 mismatches=0, V001 account, ledger_entry, DEMO_RECONCILIATION_GREEN다.

2단계 · 코드 조각 재조립

  1. 1. PowerShell script가 받을 입력 계약을 연다
  2. 2. reconcile-demo.ps1의 다음 검증 또는 설명 단계를 구성한다
  3. 3. 이 인자가 빠지면 실행 시작 전에 binding을 거절한다
  4. 4. 앞에서 연 block 또는 호출 범위를 닫는다
  5. 6. PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다
  6. 7. 필수 파일이나 경로가 실제로 있는지 확인한다
  7. 8. 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다
  8. 9. 앞에서 연 block 또는 호출 범위를 닫는다

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

scripts/reconcile-demo.ps1을 새 파일에 다시 쓰고 expected·actual·실패·cleanup·비범위를 주석으로 표시한다.

자가 점검
  • 비어 있지 않은 모든 source 줄을 한 번씩 읽었나?
  • source shape와 runtime Green을 분리했나?
  • 사람 검토·외부 상태를 자동 성공으로 꾸미지 않았나?
  • 첫 실패와 cleanup 책임을 설명할 수 있나?
13

STEP 13 / 13

전체 원본 source

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

원문 정본 전체 source 확인하기
PDF 전문 정본 · packaged PowerShell sourcescripts/reconcile-demo.ps1SHA-256 238769bb69ee689eef76275cd6c6e88af91137505926d44f83e5a2bffe90b646
reconcile-demo.ps1 — account와 ledger 합계 mismatch 0 검증 전체
param(
  [string]$StatePath = 'evidence\w24\demo-state.json',
  [Parameter(Mandatory=$true)][string]$Container
)

$ErrorActionPreference = 'Stop'
if (!(Test-Path -LiteralPath $StatePath -PathType Leaf)) {
  throw "Run reset-demo.ps1 first; missing state: $StatePath"
}
$state = Get-Content -LiteralPath $StatePath -Raw | ConvertFrom-Json
$fromId = [long]$state.fromAccountId
$toId = [long]$state.toAccountId
if ($fromId -le 0 -or $toId -le 0) { throw 'demo state has invalid account IDs' }

$sql = @"
SELECT COUNT(*)
FROM (
  SELECT a.id
  FROM account a
  LEFT JOIN ledger_entry l ON l.account_id = a.id
  WHERE a.id IN ($fromId, $toId)
  GROUP BY a.id, a.balance
  HAVING a.balance <> COALESCE(SUM(l.signed_amount), 0)
) mismatch;
"@
$raw = @($sql | docker exec -i $Container psql -X -qAt -v ON_ERROR_STOP=1 -U app -d financial_core 2>&1)
$exitCode = $LASTEXITCODE
if ($exitCode -ne 0) { throw "reconciliation query failed: $($raw -join "`n")" }
$value = (@($raw | ForEach-Object { [string]$_ }) -join '').Trim()
if ($value -cne '0') { throw "reconciliation mismatch count=$value" }
'DEMO_RECONCILIATION_GREEN mismatches=0'
11

run-w24-demo.ps1 — reset→201→200→409→대사0 orchestration

scripts/run-w24-demo.ps1

PDF 전문 정본 · packaged PowerShell source · 정본 · W24-F11
50줄 연결50줄 번역5 chunks
01

STEP 01 / 13

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

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

오늘의 한 문장

네 packaged script를 같은 runId·state·transcript로 묶고 모든 exact marker가 있을 때만 W24_DEMO_GREEN을 발행한다.

  1. first=201은 어느 source와 실제 결과에서 확인해야 할까?
  2. 첫 실패를 만드는 조건과 fail-closed 지점은 어디일까?
  3. 왜 ‘앱/DB lifecycle은 D7이 소유한다’를 별도 경계로 남겨야 할까?
이 파일에서 끝까지 다시 쓰는 값first=201replay=200conflict=409mismatches=0same runId
왜 필요한가 — run-w24-demo.ps1 — reset→201→200→409→대사0 orchestration히토리 → 니지카 → 료 → 키타
  1. 히토리

    first=201가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 네 packaged script를 같은 runId·state·transcript로 묶고 모든 exact marker가 있을 때만 W24_DEMO_GREEN을 발행한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘앱/DB lifecycle은 D7이 소유한다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 first=201와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

02

STEP 02 / 13

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

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

새 기능을 멈춘 팀이 코드·test·문서·demo를 같은 release 후보에 묶어 하나씩 검수한다.

검수 도장이 붙은 공통 거래 코어 출고 상자

이 파일은 네 packaged script를 같은 runId·state·transcript로 묶고 모든 exact marker가 있을 때만 W24_DEMO_GREEN을 발행한다. 눈으로 읽을 때는 각 줄을 검수표 한 칸처럼 보고, 입력과 다음 상태를 놓치지 않는다.

마지막 도장은 source shape와 실제 runtime·사람 검토를 구분한 뒤에만 찍는다. 특히 앱/DB lifecycle은 D7이 소유한다

딱 여기까지만 비유는 실행 순서를 돕지만 실제 Gradle·Docker·DB·사람 review를 대신하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

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

값 1: first=201

이 파일에서 계속 확인할 고정 단서가 first=201다.

코드 연결
F11 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
앱/DB lifecycle은 D7이 소유한다

값 2: replay=200

이 파일에서 계속 확인할 고정 단서가 replay=200다.

코드 연결
F11 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
marker 하나라도 없으면 실패한다

값 3: conflict=409

이 파일에서 계속 확인할 고정 단서가 conflict=409다.

코드 연결
F11 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
source audit만으로 runtime Green이 아니다

값 4: mismatches=0

이 파일에서 계속 확인할 고정 단서가 mismatches=0다.

코드 연결
F11 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
앱/DB lifecycle은 D7이 소유한다

값 5: same runId

이 파일에서 계속 확인할 고정 단서가 same runId다.

코드 연결
F11 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
marker 하나라도 없으면 실패한다
04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

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

단어 몇 개만 뽑은 표가 아닙니다.PDF 전문 정본 · packaged PowerShell source에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.50 / 50 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F11-L01 param( 출고표 1번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 PowerShell script가 받을 입력 계약을 연다.
입력
이전 줄의 상태와 first=201
결과·효과
관찰 상태 F11-001가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
앱/DB lifecycle은 D7이 소유한다
2줄F11-L02 [string]$RunId = "w24-$([DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds())", 출고표 2번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 run-w24-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$RunId
결과·효과
관찰 상태 F11-002가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
marker 하나라도 없으면 실패한다
3줄F11-L03 [string]$EvidencePath = 'evidence\w24\demo-run.txt', 출고표 3번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 run-w24-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$EvidencePath, 'evidence\w24\demo-run.txt'
결과·효과
관찰 상태 F11-003가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
source audit만으로 runtime Green이 아니다
4줄F11-L04 [string]$BaseUrl = '', 출고표 4번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 run-w24-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$BaseUrl
결과·효과
관찰 상태 F11-004가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
앱/DB lifecycle은 D7이 소유한다
5줄F11-L05 [Parameter(Mandatory=$true)][string]$Container 출고표 5번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 인자가 빠지면 실행 시작 전에 binding을 거절한다.
입력
$true, $Container
결과·효과
관찰 상태 F11-005가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
marker 하나라도 없으면 실패한다
6줄F11-L06 ) 출고표 6번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 first=201
결과·효과
관찰 상태 F11-006가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
source audit만으로 runtime Green이 아니다
8줄F11-L08 $ErrorActionPreference = 'Stop' 출고표 8번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다.
입력
$ErrorActionPreference, 'Stop'
결과·효과
관찰 상태 F11-008가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
marker 하나라도 없으면 실패한다
9줄F11-L09 $project = Split-Path -Parent $PSScriptRoot 출고표 9번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$project, $PSScriptRoot
결과·효과
관찰 상태 F11-009가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
source audit만으로 runtime Green이 아니다
10줄F11-L10 Push-Location $project 출고표 10번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 run-w24-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$project
결과·효과
관찰 상태 F11-010가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
앱/DB lifecycle은 D7이 소유한다
11줄F11-L11 try { 출고표 11번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
이전 줄의 상태와 first=201
결과·효과
관찰 상태 F11-011가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
marker 하나라도 없으면 실패한다
12줄F11-L12 $EvidencePath = [IO.Path]::GetFullPath($EvidencePath) 출고표 12번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$EvidencePath, $EvidencePath
결과·효과
관찰 상태 F11-012가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
source audit만으로 runtime Green이 아니다
13줄F11-L13 $parent = Split-Path -Parent $EvidencePath 출고표 13번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$parent, $EvidencePath
결과·효과
관찰 상태 F11-013가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
앱/DB lifecycle은 D7이 소유한다
14줄F11-L14 if (-not [string]::IsNullOrWhiteSpace($parent)) { 출고표 14번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$parent
결과·효과
관찰 상태 F11-014가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
marker 하나라도 없으면 실패한다
15줄F11-L15 New-Item -ItemType Directory -Force -Path $parent | Out-Null 출고표 15번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
입력
$parent
결과·효과
관찰 상태 F11-015가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
source audit만으로 runtime Green이 아니다
16줄F11-L16 } 출고표 16번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 first=201
결과·효과
관찰 상태 F11-016가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
앱/DB lifecycle은 D7이 소유한다
17줄F11-L17 Set-Content -LiteralPath $EvidencePath -Value "W24_DEMO_START runId=$RunId" -Encoding utf8 출고표 17번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 run-w24-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$EvidencePath, "W24_DEMO_START runId=$RunId"
결과·효과
관찰 상태 F11-017가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
marker 하나라도 없으면 실패한다
19줄F11-L19 function Invoke-DemoStep([string]$Script, [string[]]$Arguments) { 출고표 19번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$Script, $Arguments
결과·효과
관찰 상태 F11-019가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
앱/DB lifecycle은 D7이 소유한다
20줄F11-L20 $raw = @(& powershell.exe -NoProfile -ExecutionPolicy Bypass -File $Script @Arguments 2>&1) 출고표 20번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$raw, $Script, 2
결과·효과
관찰 상태 F11-020가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
marker 하나라도 없으면 실패한다
21줄F11-L21 $exitCode = $LASTEXITCODE 출고표 21번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 native process 종료 코드를 검사해 실패를 놓치지 않는다.
입력
$exitCode, $LASTEXITCODE
결과·효과
관찰 상태 F11-021가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
source audit만으로 runtime Green이 아니다
22줄F11-L22 $raw | Add-Content -LiteralPath $EvidencePath -Encoding utf8 출고표 22번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
입력
$raw, $EvidencePath
결과·효과
관찰 상태 F11-022가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
앱/DB lifecycle은 D7이 소유한다
23줄F11-L23 if ($exitCode -ne 0) { 출고표 23번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$exitCode, 0
결과·효과
관찰 상태 F11-023가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
marker 하나라도 없으면 실패한다
24줄F11-L24 throw "$Script failed exit=$exitCode`n$($raw -join "`n")" 출고표 24번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
$Script, $exitCode, $raw
결과·효과
관찰 상태 F11-024가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
source audit만으로 runtime Green이 아니다
25줄F11-L25 } 출고표 25번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 first=201
결과·효과
관찰 상태 F11-025가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
앱/DB lifecycle은 D7이 소유한다
26줄F11-L26 return @($raw | ForEach-Object { [string]$_ }) 출고표 26번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 고정 목록의 각 항목에 같은 검사를 반복 적용한다.
입력
$raw, $_
결과·효과
관찰 상태 F11-026가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
marker 하나라도 없으면 실패한다
27줄F11-L27 } 출고표 27번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 first=201
결과·효과
관찰 상태 F11-027가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
source audit만으로 runtime Green이 아니다
29줄F11-L29 $state = Join-Path (Split-Path -Parent $EvidencePath) 'demo-state.json' 출고표 29번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$state, $EvidencePath, 'demo-state.json'
결과·효과
관찰 상태 F11-029가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
marker 하나라도 없으면 실패한다
30줄F11-L30 $key = "demo-$RunId" 출고표 30번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$key, "demo-$RunId"
결과·효과
관찰 상태 F11-030가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
source audit만으로 runtime Green이 아니다
31줄F11-L31 $resetArguments = @('-RunId', $RunId, '-StatePath', $state) 출고표 31번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$resetArguments, '-RunId', $RunId
결과·효과
관찰 상태 F11-031가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
앱/DB lifecycle은 D7이 소유한다
32줄F11-L32 if (-not [string]::IsNullOrWhiteSpace($BaseUrl)) { $resetArguments += @('-BaseUrl', $BaseUrl) } 출고표 32번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 run-w24-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$BaseUrl, $resetArguments, '-BaseUrl'
결과·효과
관찰 상태 F11-032가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
marker 하나라도 없으면 실패한다
33줄F11-L33 Invoke-DemoStep '.\scripts\reset-demo.ps1' $resetArguments | Out-Null 출고표 33번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
입력
'.\scripts\reset-demo.ps1', $resetArguments
결과·효과
관찰 상태 F11-033가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
source audit만으로 runtime Green이 아니다
34줄F11-L34 Invoke-DemoStep '.\scripts\run-transfer.ps1' @('-Key', $key, '-Amount', '1000', '-ExpectedStatus', '201', '-StatePath', $state) | Out-Null 출고표 34번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 각 demo 단계가 반드시 반환해야 할 HTTP status를 입력으로 고정한다.
입력
'.\scripts\run-transfer.ps1', '-Key', $key
결과·효과
관찰 상태 F11-034가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
앱/DB lifecycle은 D7이 소유한다
35줄F11-L35 Invoke-DemoStep '.\scripts\run-transfer.ps1' @('-Key', $key, '-Amount', '1000', '-ExpectedStatus', '200', '-StatePath', $state) | Out-Null 출고표 35번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 각 demo 단계가 반드시 반환해야 할 HTTP status를 입력으로 고정한다.
입력
'.\scripts\run-transfer.ps1', '-Key', $key
결과·효과
관찰 상태 F11-035가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
marker 하나라도 없으면 실패한다
36줄F11-L36 Invoke-DemoStep '.\scripts\run-transfer.ps1' @('-Key', $key, '-Amount', '2000', '-ExpectedStatus', '409', '-StatePath', $state) | Out-Null 출고표 36번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 각 demo 단계가 반드시 반환해야 할 HTTP status를 입력으로 고정한다.
입력
'.\scripts\run-transfer.ps1', '-Key', $key
결과·효과
관찰 상태 F11-036가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
source audit만으로 runtime Green이 아니다
37줄F11-L37 Invoke-DemoStep '.\scripts\reconcile-demo.ps1' @('-StatePath', $state, '-Container', $Container) | Out-Null 출고표 37번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
입력
'.\scripts\reconcile-demo.ps1', '-StatePath', $state
결과·효과
관찰 상태 F11-037가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
앱/DB lifecycle은 D7이 소유한다
39줄F11-L39 $text = Get-Content -LiteralPath $EvidencePath -Raw 출고표 39번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$text, $EvidencePath
결과·효과
관찰 상태 F11-039가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
source audit만으로 runtime Green이 아니다
40줄F11-L40 foreach ($marker in @( 출고표 40번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 고정 목록의 각 항목에 같은 검사를 반복 적용한다.
입력
$marker
결과·효과
관찰 상태 F11-040가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
앱/DB lifecycle은 D7이 소유한다
41줄F11-L41 'DEMO_RESET_OK', 출고표 41번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 두 numeric account ID가 state에 저장된 reset 완료 marker를 낸다.
입력
'DEMO_RESET_OK'
결과·효과
관찰 상태 F11-041가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
marker 하나라도 없으면 실패한다
42줄F11-L42 "DEMO_TRANSFER_OK key=$key amount=1000 status=201", 출고표 42번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 한 transfer 호출이 기대 status와 일치했음을 transcript에 남긴다.
입력
$key, 1000, 201
결과·효과
관찰 상태 F11-042가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
source audit만으로 runtime Green이 아니다
43줄F11-L43 "DEMO_TRANSFER_OK key=$key amount=1000 status=200", 출고표 43번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 한 transfer 호출이 기대 status와 일치했음을 transcript에 남긴다.
입력
$key, 1000, 200
결과·효과
관찰 상태 F11-043가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
앱/DB lifecycle은 D7이 소유한다
44줄F11-L44 "DEMO_TRANSFER_OK key=$key amount=2000 status=409", 출고표 44번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 한 transfer 호출이 기대 status와 일치했음을 transcript에 남긴다.
입력
$key, 2000, 409
결과·효과
관찰 상태 F11-044가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
marker 하나라도 없으면 실패한다
45줄F11-L45 'DEMO_RECONCILIATION_GREEN mismatches=0' 출고표 45번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 account balance와 ledger 합계를 비교해 mismatch를 찾는다.
입력
'DEMO_RECONCILIATION_GREEN mismatches=0'
결과·효과
관찰 상태 F11-045가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
source audit만으로 runtime Green이 아니다
46줄F11-L46 )) { 출고표 46번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
이전 줄의 상태와 first=201
결과·효과
관찰 상태 F11-046가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
앱/DB lifecycle은 D7이 소유한다
47줄F11-L47 if ($text -cnotmatch [regex]::Escape($marker)) { throw "missing demo marker: $marker" } 출고표 47번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
$text, $marker, "missing demo marker: $marker"
결과·효과
관찰 상태 F11-047가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
marker 하나라도 없으면 실패한다
48줄F11-L48 } 출고표 48번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 first=201
결과·효과
관찰 상태 F11-048가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
source audit만으로 runtime Green이 아니다
49줄F11-L49 $summary = 'W24_DEMO_GREEN first=201 replay=200 conflict=409 mismatches=0' 출고표 49번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 201→200→409→대사0 exact marker가 모두 있을 때 demo 범위를 닫는다.
입력
$summary, 201, 200
결과·효과
관찰 상태 F11-049가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
앱/DB lifecycle은 D7이 소유한다
50줄F11-L50 $summary | Add-Content -LiteralPath $EvidencePath -Encoding utf8 출고표 50번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
입력
$summary, $EvidencePath
결과·효과
관찰 상태 F11-050가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
marker 하나라도 없으면 실패한다
51줄F11-L51 $summary 출고표 51번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 run-w24-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$summary
결과·효과
관찰 상태 F11-051가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
source audit만으로 runtime Green이 아니다
52줄F11-L52 } finally { 출고표 52번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 중간 실패가 있어도 반드시 실행할 cleanup 경계를 연다.
입력
이전 줄의 상태와 first=201
결과·효과
관찰 상태 F11-052가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
앱/DB lifecycle은 D7이 소유한다
53줄F11-L53 Pop-Location 출고표 53번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 run-w24-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 first=201
결과·효과
관찰 상태 F11-053가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
marker 하나라도 없으면 실패한다
54줄F11-L54 } 출고표 54번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 first=201
결과·효과
관찰 상태 F11-054가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
source audit만으로 runtime Green이 아니다
05

STEP 05 / 13

원본 코드 조각

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

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

F11-C01 · 원문 1–12줄1–12줄
1–12줄 원본
param(
  [string]$RunId = "w24-$([DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds())",
  [string]$EvidencePath = 'evidence\w24\demo-run.txt',
  [string]$BaseUrl = '',
  [Parameter(Mandatory=$true)][string]$Container
)

$ErrorActionPreference = 'Stop'
$project = Split-Path -Parent $PSScriptRoot
Push-Location $project
try {
  $EvidencePath = [IO.Path]::GetFullPath($EvidencePath)
F11-C02 · 원문 13–24줄13–24줄
13–24줄 원본
  $parent = Split-Path -Parent $EvidencePath
  if (-not [string]::IsNullOrWhiteSpace($parent)) {
    New-Item -ItemType Directory -Force -Path $parent | Out-Null
  }
  Set-Content -LiteralPath $EvidencePath -Value "W24_DEMO_START runId=$RunId" -Encoding utf8

  function Invoke-DemoStep([string]$Script, [string[]]$Arguments) {
    $raw = @(& powershell.exe -NoProfile -ExecutionPolicy Bypass -File $Script @Arguments 2>&1)
    $exitCode = $LASTEXITCODE
    $raw | Add-Content -LiteralPath $EvidencePath -Encoding utf8
    if ($exitCode -ne 0) {
      throw "$Script failed exit=$exitCode`n$($raw -join "`n")"
F11-C03 · 원문 25–36줄25–36줄
25–36줄 원본
    }
    return @($raw | ForEach-Object { [string]$_ })
  }

  $state = Join-Path (Split-Path -Parent $EvidencePath) 'demo-state.json'
  $key = "demo-$RunId"
  $resetArguments = @('-RunId', $RunId, '-StatePath', $state)
  if (-not [string]::IsNullOrWhiteSpace($BaseUrl)) { $resetArguments += @('-BaseUrl', $BaseUrl) }
  Invoke-DemoStep '.\scripts\reset-demo.ps1' $resetArguments | Out-Null
  Invoke-DemoStep '.\scripts\run-transfer.ps1' @('-Key', $key, '-Amount', '1000', '-ExpectedStatus', '201', '-StatePath', $state) | Out-Null
  Invoke-DemoStep '.\scripts\run-transfer.ps1' @('-Key', $key, '-Amount', '1000', '-ExpectedStatus', '200', '-StatePath', $state) | Out-Null
  Invoke-DemoStep '.\scripts\run-transfer.ps1' @('-Key', $key, '-Amount', '2000', '-ExpectedStatus', '409', '-StatePath', $state) | Out-Null
F11-C04 · 원문 37–48줄37–48줄
37–48줄 원본
  Invoke-DemoStep '.\scripts\reconcile-demo.ps1' @('-StatePath', $state, '-Container', $Container) | Out-Null

  $text = Get-Content -LiteralPath $EvidencePath -Raw
  foreach ($marker in @(
      'DEMO_RESET_OK',
      "DEMO_TRANSFER_OK key=$key amount=1000 status=201",
      "DEMO_TRANSFER_OK key=$key amount=1000 status=200",
      "DEMO_TRANSFER_OK key=$key amount=2000 status=409",
      'DEMO_RECONCILIATION_GREEN mismatches=0'
  )) {
    if ($text -cnotmatch [regex]::Escape($marker)) { throw "missing demo marker: $marker" }
  }
F11-C05 · 원문 49–54줄49–54줄
49–54줄 원본
  $summary = 'W24_DEMO_GREEN first=201 replay=200 conflict=409 mismatches=0'
  $summary | Add-Content -LiteralPath $EvidencePath -Encoding utf8
  $summary
} finally {
  Pop-Location
}
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

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

전체 번역 50 / 50

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

원본한국어 번역
1param(실행 의미: PowerShell script가 받을 입력 계약을 연다.
2 [string]$RunId = "w24-$([DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds())",실행 의미: run-w24-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
3 [string]$EvidencePath = 'evidence\w24\demo-run.txt',실행 의미: run-w24-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
4 [string]$BaseUrl = '',실행 의미: run-w24-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
5 [Parameter(Mandatory=$true)][string]$Container실행 의미: 이 인자가 빠지면 실행 시작 전에 binding을 거절한다.
6)실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
8$ErrorActionPreference = 'Stop'실행 의미: PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다.
9$project = Split-Path -Parent $PSScriptRoot실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
10Push-Location $project실행 의미: run-w24-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
11try {실행 의미: 조건·반복·함수의 실행 block을 연다.
12 $EvidencePath = [IO.Path]::GetFullPath($EvidencePath)실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
13 $parent = Split-Path -Parent $EvidencePath실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
14 if (-not [string]::IsNullOrWhiteSpace($parent)) {실행 의미: 조건·반복·함수의 실행 block을 연다.
15 New-Item -ItemType Directory -Force -Path $parent | Out-Null실행 의미: Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
16 }실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
17 Set-Content -LiteralPath $EvidencePath -Value "W24_DEMO_START runId=$RunId" -Encoding utf8실행 의미: run-w24-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
19 function Invoke-DemoStep([string]$Script, [string[]]$Arguments) {실행 의미: 조건·반복·함수의 실행 block을 연다.
20 $raw = @(& powershell.exe -NoProfile -ExecutionPolicy Bypass -File $Script @Arguments 2>&1)실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
21 $exitCode = $LASTEXITCODE실행 의미: native process 종료 코드를 검사해 실패를 놓치지 않는다.
22 $raw | Add-Content -LiteralPath $EvidencePath -Encoding utf8실행 의미: Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
23 if ($exitCode -ne 0) {실행 의미: 조건·반복·함수의 실행 block을 연다.
24 throw "$Script failed exit=$exitCode`n$($raw -join "`n")"실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
25 }실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
26 return @($raw | ForEach-Object { [string]$_ })실행 의미: 고정 목록의 각 항목에 같은 검사를 반복 적용한다.
27 }실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
29 $state = Join-Path (Split-Path -Parent $EvidencePath) 'demo-state.json'실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
30 $key = "demo-$RunId"실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
31 $resetArguments = @('-RunId', $RunId, '-StatePath', $state)실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
32 if (-not [string]::IsNullOrWhiteSpace($BaseUrl)) { $resetArguments += @('-BaseUrl', $BaseUrl) }실행 의미: run-w24-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
33 Invoke-DemoStep '.\scripts\reset-demo.ps1' $resetArguments | Out-Null실행 의미: Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
34 Invoke-DemoStep '.\scripts\run-transfer.ps1' @('-Key', $key, '-Amount', '1000', '-ExpectedStatus', '201', '-StatePath', $state) | Out-Null실행 의미: 각 demo 단계가 반드시 반환해야 할 HTTP status를 입력으로 고정한다.
35 Invoke-DemoStep '.\scripts\run-transfer.ps1' @('-Key', $key, '-Amount', '1000', '-ExpectedStatus', '200', '-StatePath', $state) | Out-Null실행 의미: 각 demo 단계가 반드시 반환해야 할 HTTP status를 입력으로 고정한다.
36 Invoke-DemoStep '.\scripts\run-transfer.ps1' @('-Key', $key, '-Amount', '2000', '-ExpectedStatus', '409', '-StatePath', $state) | Out-Null실행 의미: 각 demo 단계가 반드시 반환해야 할 HTTP status를 입력으로 고정한다.
37 Invoke-DemoStep '.\scripts\reconcile-demo.ps1' @('-StatePath', $state, '-Container', $Container) | Out-Null실행 의미: Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
39 $text = Get-Content -LiteralPath $EvidencePath -Raw실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
40 foreach ($marker in @(실행 의미: 고정 목록의 각 항목에 같은 검사를 반복 적용한다.
41 'DEMO_RESET_OK',실행 의미: 두 numeric account ID가 state에 저장된 reset 완료 marker를 낸다.
42 "DEMO_TRANSFER_OK key=$key amount=1000 status=201",실행 의미: 한 transfer 호출이 기대 status와 일치했음을 transcript에 남긴다.
43 "DEMO_TRANSFER_OK key=$key amount=1000 status=200",실행 의미: 한 transfer 호출이 기대 status와 일치했음을 transcript에 남긴다.
44 "DEMO_TRANSFER_OK key=$key amount=2000 status=409",실행 의미: 한 transfer 호출이 기대 status와 일치했음을 transcript에 남긴다.
45 'DEMO_RECONCILIATION_GREEN mismatches=0'실행 의미: account balance와 ledger 합계를 비교해 mismatch를 찾는다.
46 )) {실행 의미: 조건·반복·함수의 실행 block을 연다.
47 if ($text -cnotmatch [regex]::Escape($marker)) { throw "missing demo marker: $marker" }실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
48 }실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
49 $summary = 'W24_DEMO_GREEN first=201 replay=200 conflict=409 mismatches=0'실행 의미: 201→200→409→대사0 exact marker가 모두 있을 때 demo 범위를 닫는다.
50 $summary | Add-Content -LiteralPath $EvidencePath -Encoding utf8실행 의미: Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
51 $summary실행 의미: run-w24-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
52} finally {실행 의미: 중간 실패가 있어도 반드시 실행할 cleanup 경계를 연다.
53 Pop-Location실행 의미: run-w24-demo.ps1의 다음 검증 또는 설명 단계를 구성한다.
54}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
07

STEP 07 / 13

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

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

한 줄로 읽기

run-w24-demo.ps1 — reset→201→200→409→대사0 orchestration는 네 packaged script를 같은 runId·state·transcript로 묶고 모든 exact marker가 있을 때만 W24_DEMO_GREEN을 발행한다.

문법 해부

  • .ps1 문법에서 선언·조건·pipeline·block 경계를 먼저 나눈다.
  • expected 값과 actual 결과를 같은 이름처럼 보여도 서로 다른 source로 읽는다.
  • native exit·row count·hash·사람 판정을 서로 대체하지 않는다.

실행 순서

  1. 입력 경로·fixture·환경변수·expected 계약을 고정한다.
  2. source가 실행하는 native process·HTTP·SQL 또는 형식 검사를 따라간다.
  3. actual 값과 exact marker를 대조하고 실패면 성공 발행 전에 중단한다.
  4. finally cleanup과 비범위를 evidence에 남긴다.

W24 조각별 정밀 해설

F11-C01 · 원문 1–12줄
문법 해부
.ps1 문법으로 1–12줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
first=201, replay=200, conflict=409를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
앱/DB lifecycle은 D7이 소유한다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
앱/DB lifecycle은 D7이 소유한다; marker 하나라도 없으면 실패한다; source audit만으로 runtime Green이 아니다
다음 연결
다음 조각 또는 F11 evidence 판정으로 상태를 넘긴다.
F11-C02 · 원문 13–24줄
문법 해부
.ps1 문법으로 13–24줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
first=201, replay=200, conflict=409를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
앱/DB lifecycle은 D7이 소유한다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
앱/DB lifecycle은 D7이 소유한다; marker 하나라도 없으면 실패한다; source audit만으로 runtime Green이 아니다
다음 연결
다음 조각 또는 F11 evidence 판정으로 상태를 넘긴다.
F11-C03 · 원문 25–36줄
문법 해부
.ps1 문법으로 25–36줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
first=201, replay=200, conflict=409를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
앱/DB lifecycle은 D7이 소유한다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
앱/DB lifecycle은 D7이 소유한다; marker 하나라도 없으면 실패한다; source audit만으로 runtime Green이 아니다
다음 연결
다음 조각 또는 F11 evidence 판정으로 상태를 넘긴다.
F11-C04 · 원문 37–48줄
문법 해부
.ps1 문법으로 37–48줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
first=201, replay=200, conflict=409를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
앱/DB lifecycle은 D7이 소유한다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
앱/DB lifecycle은 D7이 소유한다; marker 하나라도 없으면 실패한다; source audit만으로 runtime Green이 아니다
다음 연결
다음 조각 또는 F11 evidence 판정으로 상태를 넘긴다.
F11-C05 · 원문 49–54줄
문법 해부
.ps1 문법으로 49–54줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
first=201, replay=200, conflict=409를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
앱/DB lifecycle은 D7이 소유한다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
앱/DB lifecycle은 D7이 소유한다; marker 하나라도 없으면 실패한다; source audit만으로 runtime Green이 아니다
다음 연결
다음 조각 또는 F11 evidence 판정으로 상태를 넘긴다.
실행 순서 — run-w24-demo.ps1 — reset→201→200→409→대사0 orchestration히토리 → 니지카 → 료 → 키타
  1. 히토리

    replay=200가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 네 packaged script를 같은 runId·state·transcript로 묶고 모든 exact marker가 있을 때만 W24_DEMO_GREEN을 발행한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘marker 하나라도 없으면 실패한다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 replay=200와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

08

STEP 08 / 13

실제 값 따라가기

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

순서들어온 값코드가 하는 일나온 값·상태경계
입력first=201source 계약에 대입F11 실행/설명 시작 상태앱/DB lifecycle은 D7이 소유한다
검증replay=200expected와 actual 또는 형식 대조통과 또는 첫 mismatchmarker 하나라도 없으면 실패한다
증거same runIdmarker·hash·row를 같은 run에 연결범위가 적힌 evidence 후보source audit만으로 runtime Green이 아니다
실제 값 — run-w24-demo.ps1 — reset→201→200→409→대사0 orchestration히토리 → 니지카 → 료 → 키타
  1. 히토리

    conflict=409가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 네 packaged script를 같은 runId·state·transcript로 묶고 모든 exact marker가 있을 때만 W24_DEMO_GREEN을 발행한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘source audit만으로 runtime Green이 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 conflict=409와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

09

STEP 09 / 13

Gradle·PowerShell·HTTP·PostgreSQL 내부에서 벌어지는 일

Gradle·JUnit XML·PowerShell·HTTP·PostgreSQL·Docker에서 실제로 일어나는 일과 증명 범위를 구분합니다.

source/contract

run-w24-demo.ps1 bytes와 expected 값을 읽는다.

파일 존재만으로 runtime 성공은 아니다.
execution/evidence

native exit·HTTP status·JUnit XML·DB row·hash 중 이 파일이 소유한 값을 만든다.

앱/DB lifecycle은 D7이 소유한다
release/human

관련 evidence와 사람 의미 검토를 release 후보에 연결한다.

source audit만으로 runtime Green이 아니다
첫 실패 경계 — run-w24-demo.ps1 — reset→201→200→409→대사0 orchestration히토리 → 니지카 → 료 → 키타
  1. 히토리

    mismatches=0가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 네 packaged script를 같은 runId·state·transcript로 묶고 모든 exact marker가 있을 때만 W24_DEMO_GREEN을 발행한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘앱/DB lifecycle은 D7이 소유한다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 mismatches=0와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

10

STEP 10 / 13

흔한 착각과 틀린 예

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

❌ first=201 문자열이 source에 있으니 실제 실행도 Green이다.

왜 틀리나 source literal과 runtime 관찰값은 다른 증거다.

바르게 읽기 native exit·actual XML/HTTP/DB evidence를 별도로 확인한다.

반례 script가 실행 전 경로 오류로 멈춰도 literal은 그대로 남는다.

❌ 파일 SHA-256이 있으면 내용의 의미와 사실성도 검증됐다.

왜 틀리나 hash는 동일 bytes만 말한다.

바르게 읽기 schema·수치·질문·근거는 별도 자동 또는 사람 판정을 거친다.

반례 빈 review 질문을 가진 CSV도 안정된 hash를 가진다.

❌ LOCAL_ARTIFACT_VALIDATED는 release Green과 같다.

왜 틀리나 generic validator는 파일 shape만 확인한다.

바르게 읽기 HUMAN_SEMANTIC_REVIEW_REQUIRED를 유지한다.

반례 잘못된 track 점수표도 byte 수 조건은 통과할 수 있다.

❌ 이 파일이 W24 전체 lifecycle을 모두 소유한다.

왜 틀리나 각 source는 Gate·demo·cleanup·사람 review 중 일부만 담당한다.

바르게 읽기 owner와 non-responsibility를 release manifest에서 분리한다.

반례 D4 source audit에는 runtime_claim=false가 명시된다.

❌ 이전 주 Green이나 오래된 log를 현재 commit 결과로 재사용한다.

왜 틀리나 source·commit·actual result가 같은 실행에 묶이지 않는다.

바르게 읽기 release 후보에서 새 evidence와 hash를 만든다.

반례 expected JSON이 바뀌면 예전 XML은 exact inventory를 증명하지 못한다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

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

증명 범위

앱/DB lifecycle은 D7이 소유한다

이 책임을 맡는 곳: runtime Gate
증명 범위

marker 하나라도 없으면 실패한다

이 책임을 맡는 곳: external/human review
증명 범위

source audit만으로 runtime Green이 아니다

이 책임을 맡는 곳: release manifest
증명 범위

앱/DB lifecycle은 D7이 소유한다

이 책임을 맡는 곳: 운영 환경
증명하지 않는 범위 — run-w24-demo.ps1 — reset→201→200→409→대사0 orchestration히토리 → 니지카 → 료 → 키타
  1. 히토리

    same runId가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 네 packaged script를 같은 runId·state·transcript로 묶고 모든 exact marker가 있을 때만 W24_DEMO_GREEN을 발행한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘marker 하나라도 없으면 실패한다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 same runId와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

12

STEP 12 / 13

직접 다시 써보기

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

1단계 · 뜻부터 복원

  • 네 packaged script를 같은 runId·state·transcript로 묶고 모든 exact marker가 있을 때만 W24_DEMO_GREEN을 발행한다.
  • 핵심 값은 first=201, replay=200, conflict=409, mismatches=0, same runId다.

2단계 · 코드 조각 재조립

  1. 1. PowerShell script가 받을 입력 계약을 연다
  2. 2. run-w24-demo.ps1의 다음 검증 또는 설명 단계를 구성한다
  3. 3. run-w24-demo.ps1의 다음 검증 또는 설명 단계를 구성한다
  4. 4. run-w24-demo.ps1의 다음 검증 또는 설명 단계를 구성한다
  5. 5. 이 인자가 빠지면 실행 시작 전에 binding을 거절한다
  6. 6. 앞에서 연 block 또는 호출 범위를 닫는다
  7. 8. PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다
  8. 9. 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다

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

scripts/run-w24-demo.ps1을 새 파일에 다시 쓰고 expected·actual·실패·cleanup·비범위를 주석으로 표시한다.

자가 점검
  • 비어 있지 않은 모든 source 줄을 한 번씩 읽었나?
  • source shape와 runtime Green을 분리했나?
  • 사람 검토·외부 상태를 자동 성공으로 꾸미지 않았나?
  • 첫 실패와 cleanup 책임을 설명할 수 있나?
13

STEP 13 / 13

전체 원본 source

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

원문 정본 전체 source 확인하기
PDF 전문 정본 · packaged PowerShell sourcescripts/run-w24-demo.ps1SHA-256 6d44ed281081a752d957a3518f9895b8d8d1df4f8dfd2c04c1ab8a1bbd72948b
run-w24-demo.ps1 — reset→201→200→409→대사0 orchestration 전체
param(
  [string]$RunId = "w24-$([DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds())",
  [string]$EvidencePath = 'evidence\w24\demo-run.txt',
  [string]$BaseUrl = '',
  [Parameter(Mandatory=$true)][string]$Container
)

$ErrorActionPreference = 'Stop'
$project = Split-Path -Parent $PSScriptRoot
Push-Location $project
try {
  $EvidencePath = [IO.Path]::GetFullPath($EvidencePath)
  $parent = Split-Path -Parent $EvidencePath
  if (-not [string]::IsNullOrWhiteSpace($parent)) {
    New-Item -ItemType Directory -Force -Path $parent | Out-Null
  }
  Set-Content -LiteralPath $EvidencePath -Value "W24_DEMO_START runId=$RunId" -Encoding utf8

  function Invoke-DemoStep([string]$Script, [string[]]$Arguments) {
    $raw = @(& powershell.exe -NoProfile -ExecutionPolicy Bypass -File $Script @Arguments 2>&1)
    $exitCode = $LASTEXITCODE
    $raw | Add-Content -LiteralPath $EvidencePath -Encoding utf8
    if ($exitCode -ne 0) {
      throw "$Script failed exit=$exitCode`n$($raw -join "`n")"
    }
    return @($raw | ForEach-Object { [string]$_ })
  }

  $state = Join-Path (Split-Path -Parent $EvidencePath) 'demo-state.json'
  $key = "demo-$RunId"
  $resetArguments = @('-RunId', $RunId, '-StatePath', $state)
  if (-not [string]::IsNullOrWhiteSpace($BaseUrl)) { $resetArguments += @('-BaseUrl', $BaseUrl) }
  Invoke-DemoStep '.\scripts\reset-demo.ps1' $resetArguments | Out-Null
  Invoke-DemoStep '.\scripts\run-transfer.ps1' @('-Key', $key, '-Amount', '1000', '-ExpectedStatus', '201', '-StatePath', $state) | Out-Null
  Invoke-DemoStep '.\scripts\run-transfer.ps1' @('-Key', $key, '-Amount', '1000', '-ExpectedStatus', '200', '-StatePath', $state) | Out-Null
  Invoke-DemoStep '.\scripts\run-transfer.ps1' @('-Key', $key, '-Amount', '2000', '-ExpectedStatus', '409', '-StatePath', $state) | Out-Null
  Invoke-DemoStep '.\scripts\reconcile-demo.ps1' @('-StatePath', $state, '-Container', $Container) | Out-Null

  $text = Get-Content -LiteralPath $EvidencePath -Raw
  foreach ($marker in @(
      'DEMO_RESET_OK',
      "DEMO_TRANSFER_OK key=$key amount=1000 status=201",
      "DEMO_TRANSFER_OK key=$key amount=1000 status=200",
      "DEMO_TRANSFER_OK key=$key amount=2000 status=409",
      'DEMO_RECONCILIATION_GREEN mismatches=0'
  )) {
    if ($text -cnotmatch [regex]::Escape($marker)) { throw "missing demo marker: $marker" }
  }
  $summary = 'W24_DEMO_GREEN first=201 replay=200 conflict=409 mismatches=0'
  $summary | Add-Content -LiteralPath $EvidencePath -Encoding utf8
  $summary
} finally {
  Pop-Location
}
12

W24 D4 source audit — 4개 demo script hash와 literal secret 검사

illustrative/powershell/W24-D4-demo-source-audit.ps1

학습용 예시 · PDF inline PowerShell · 정본 답안 아님 · 비실행 · 학습용 예시 · 정본 답안 아님 · W24-F12
23줄 연결23줄 번역2 chunks
01

STEP 01 / 13

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

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

오늘의 한 문장

packaged demo source 4개의 존재·bytes·SHA-256과 단순 literal secret 패턴만 검사해 runtime_claim=false evidence를 만든다.

  1. files=4은 어느 source와 실제 결과에서 확인해야 할까?
  2. 첫 실패를 만드는 조건과 fail-closed 지점은 어디일까?
  3. 왜 ‘PDF-only 학습 예시다’를 별도 경계로 남겨야 할까?
이 파일에서 끝까지 다시 쓰는 값files=4literal_secrets=0hashes=4runtime_claim=false
왜 필요한가 — W24 D4 source audit — 4개 demo script hash와 literal secret 검사히토리 → 니지카 → 료 → 키타
  1. 히토리

    files=4가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 packaged demo source 4개의 존재·bytes·SHA-256과 단순 literal secret 패턴만 검사해 runtime_claim=false evidence를 만든다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘PDF-only 학습 예시다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 files=4와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

02

STEP 02 / 13

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

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

새 기능을 멈춘 팀이 코드·test·문서·demo를 같은 release 후보에 묶어 하나씩 검수한다.

검수 도장이 붙은 공통 거래 코어 출고 상자

이 파일은 packaged demo source 4개의 존재·bytes·SHA-256과 단순 literal secret 패턴만 검사해 runtime_claim=false evidence를 만든다. 눈으로 읽을 때는 각 줄을 검수표 한 칸처럼 보고, 입력과 다음 상태를 놓치지 않는다.

마지막 도장은 source shape와 실제 runtime·사람 검토를 구분한 뒤에만 찍는다. 특히 PDF-only 학습 예시다

딱 여기까지만 비유는 실행 순서를 돕지만 실제 Gradle·Docker·DB·사람 review를 대신하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

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

값 1: files=4

이 파일에서 계속 확인할 고정 단서가 files=4다.

코드 연결
F12 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
PDF-only 학습 예시다

값 2: literal_secrets=0

이 파일에서 계속 확인할 고정 단서가 literal_secrets=0다.

코드 연결
F12 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
DB/app을 실행하지 않는다

값 3: hashes=4

이 파일에서 계속 확인할 고정 단서가 hashes=4다.

코드 연결
F12 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
실제 201→200→409→대사0 Green은 D7 책임이다

값 4: runtime_claim=false

이 파일에서 계속 확인할 고정 단서가 runtime_claim=false다.

코드 연결
F12 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
PDF-only 학습 예시다
04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

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

단어 몇 개만 뽑은 표가 아닙니다.학습용 예시 · PDF inline PowerShell · 정본 답안 아님 · 비실행에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.23 / 23 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F12-L01 # W24 PDF p804의 source-only Gate를 읽기 좋게 정리한 학습용 예시다. 출고표 1번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
이전 줄의 상태와 files=4
결과·효과
관찰 상태 F12-001가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시다
2줄F12-L02 # 이 검사는 active DB/app lifecycle을 실행하지 않으며 runtime Green을 주장하지 않는다. 출고표 2번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
이전 줄의 상태와 files=4
결과·효과
관찰 상태 F12-002가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB/app을 실행하지 않는다
3줄F12-L03 $Names = @('reset-demo.ps1', 'run-transfer.ps1', 'reconcile-demo.ps1', 'run-w24-demo.ps1') 출고표 3번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Names, 'reset-demo.ps1', 'run-transfer.ps1'
결과·효과
관찰 상태 F12-003가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 201→200→409→대사0 Green은 D7 책임이다
4줄F12-L04 $Rows = @() 출고표 4번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Rows
결과·효과
관찰 상태 F12-004가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시다
5줄F12-L05 foreach ($Name in $Names) { 출고표 5번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 고정 목록의 각 항목에 같은 검사를 반복 적용한다.
입력
$Name, $Names
결과·효과
관찰 상태 F12-005가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB/app을 실행하지 않는다
6줄F12-L06 $Path = Join-Path $ReferenceRoot ('scripts\' + $Name) 출고표 6번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Path, $ReferenceRoot, 'scripts\'
결과·효과
관찰 상태 F12-006가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 201→200→409→대사0 Green은 D7 책임이다
7줄F12-L07 if (!(Test-Path -LiteralPath $Path -PathType Leaf)) { 출고표 7번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 필수 파일이나 경로가 실제로 있는지 확인한다.
입력
$Path
결과·효과
관찰 상태 F12-007가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시다
8줄F12-L08 throw "missing packaged demo script: $Name" 출고표 8번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
"missing packaged demo script: $Name"
결과·효과
관찰 상태 F12-008가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB/app을 실행하지 않는다
9줄F12-L09 } 출고표 9번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 files=4
결과·효과
관찰 상태 F12-009가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 201→200→409→대사0 Green은 D7 책임이다
10줄F12-L10 $Text = Get-Content -Raw -LiteralPath $Path 출고표 10번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Text, $Path
결과·효과
관찰 상태 F12-010가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시다
11줄F12-L11 if ($Text -cmatch '(?i)(password\s*=\s*["''][^$]|Authorization:\s*Basic\s+[A-Za-z0-9])') { 출고표 11번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 인증 header를 runtime에서 만들되 evidence에 원문 비밀을 남기지 않는다.
입력
$Text, '(?i)(password\s*=\s*[", 9
결과·효과
관찰 상태 F12-011가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB/app을 실행하지 않는다
12줄F12-L12 throw "literal secret in $Name" 출고표 12번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
"literal secret in $Name"
결과·효과
관찰 상태 F12-012가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 201→200→409→대사0 Green은 D7 책임이다
13줄F12-L13 } 출고표 13번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 files=4
결과·효과
관찰 상태 F12-013가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시다
14줄F12-L14 $Rows += [ordered]@{ 출고표 14번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$Rows
결과·효과
관찰 상태 F12-014가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB/app을 실행하지 않는다
15줄F12-L15 file = $Name 출고표 15번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D4-demo-source-audit.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$Name
결과·효과
관찰 상태 F12-015가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 201→200→409→대사0 Green은 D7 책임이다
16줄F12-L16 bytes = (Get-Item -LiteralPath $Path).Length 출고표 16번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D4-demo-source-audit.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$Path
결과·효과
관찰 상태 F12-016가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시다
17줄F12-L17 sha256 = (Get-FileHash -LiteralPath $Path -Algorithm SHA256).Hash.ToLowerInvariant() 출고표 17번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 현재 bytes를 64자리 digest로 evidence에 결박한다.
입력
$Path
결과·효과
관찰 상태 F12-017가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB/app을 실행하지 않는다
18줄F12-L18 } 출고표 18번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 files=4
결과·효과
관찰 상태 F12-018가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 201→200→409→대사0 Green은 D7 책임이다
19줄F12-L19 } 출고표 19번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 files=4
결과·효과
관찰 상태 F12-019가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시다
21줄F12-L21 $Out = Join-Path $LearnerRoot 'evidence\w24\demo-script-review.json' 출고표 21번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Out, $LearnerRoot, 'evidence\w24\demo-script-review.json'
결과·효과
관찰 상태 F12-021가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 201→200→409→대사0 Green은 D7 책임이다
22줄F12-L22 New-Item -ItemType Directory -Force (Split-Path -Parent $Out) | Out-Null 출고표 22번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
입력
$Out
결과·효과
관찰 상태 F12-022가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
PDF-only 학습 예시다
23줄F12-L23 $Rows | ConvertTo-Json | Set-Content -Encoding utf8 $Out 출고표 23번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 검증된 object를 JSON evidence text로 직렬화한다.
입력
$Rows, $Out
결과·효과
관찰 상태 F12-023가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
DB/app을 실행하지 않는다
24줄F12-L24 'W24_DEMO_SOURCE_AUDIT files=4 literal_secrets=0 hashes=4 runtime_claim=false' 출고표 24번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D4-demo-source-audit.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
4, 0, 4
결과·효과
관찰 상태 F12-024가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 201→200→409→대사0 Green은 D7 책임이다
05

STEP 05 / 13

원본 코드 조각

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

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

F12-C01 · 원문 1–12줄1–12줄
1–12줄 원본
# W24 PDF p804의 source-only Gate를 읽기 좋게 정리한 학습용 예시다.
# 이 검사는 active DB/app lifecycle을 실행하지 않으며 runtime Green을 주장하지 않는다.
$Names = @('reset-demo.ps1', 'run-transfer.ps1', 'reconcile-demo.ps1', 'run-w24-demo.ps1')
$Rows = @()
foreach ($Name in $Names) {
  $Path = Join-Path $ReferenceRoot ('scripts\' + $Name)
  if (!(Test-Path -LiteralPath $Path -PathType Leaf)) {
    throw "missing packaged demo script: $Name"
  }
  $Text = Get-Content -Raw -LiteralPath $Path
  if ($Text -cmatch '(?i)(password\s*=\s*["''][^$]|Authorization:\s*Basic\s+[A-Za-z0-9])') {
    throw "literal secret in $Name"
F12-C02 · 원문 13–24줄13–24줄
13–24줄 원본
  }
  $Rows += [ordered]@{
    file = $Name
    bytes = (Get-Item -LiteralPath $Path).Length
    sha256 = (Get-FileHash -LiteralPath $Path -Algorithm SHA256).Hash.ToLowerInvariant()
  }
}

$Out = Join-Path $LearnerRoot 'evidence\w24\demo-script-review.json'
New-Item -ItemType Directory -Force (Split-Path -Parent $Out) | Out-Null
$Rows | ConvertTo-Json | Set-Content -Encoding utf8 $Out
'W24_DEMO_SOURCE_AUDIT files=4 literal_secrets=0 hashes=4 runtime_claim=false'
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

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

전체 번역 23 / 23

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

원본한국어 번역
1# W24 PDF p804의 source-only Gate를 읽기 좋게 정리한 학습용 예시다.문서 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
2# 이 검사는 active DB/app lifecycle을 실행하지 않으며 runtime Green을 주장하지 않는다.문서 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
3$Names = @('reset-demo.ps1', 'run-transfer.ps1', 'reconcile-demo.ps1', 'run-w24-demo.ps1')실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
4$Rows = @()실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
5foreach ($Name in $Names) {실행 의미: 고정 목록의 각 항목에 같은 검사를 반복 적용한다.
6 $Path = Join-Path $ReferenceRoot ('scripts\' + $Name)실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
7 if (!(Test-Path -LiteralPath $Path -PathType Leaf)) {실행 의미: 필수 파일이나 경로가 실제로 있는지 확인한다.
8 throw "missing packaged demo script: $Name"실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
9 }실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
10 $Text = Get-Content -Raw -LiteralPath $Path실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
11 if ($Text -cmatch '(?i)(password\s*=\s*["''][^$]|Authorization:\s*Basic\s+[A-Za-z0-9])') {실행 의미: 인증 header를 runtime에서 만들되 evidence에 원문 비밀을 남기지 않는다.
12 throw "literal secret in $Name"실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
13 }실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
14 $Rows += [ordered]@{실행 의미: 조건·반복·함수의 실행 block을 연다.
15 file = $Name실행 의미: W24-D4-demo-source-audit.ps1의 다음 검증 또는 설명 단계를 구성한다.
16 bytes = (Get-Item -LiteralPath $Path).Length실행 의미: W24-D4-demo-source-audit.ps1의 다음 검증 또는 설명 단계를 구성한다.
17 sha256 = (Get-FileHash -LiteralPath $Path -Algorithm SHA256).Hash.ToLowerInvariant()실행 의미: 현재 bytes를 64자리 digest로 evidence에 결박한다.
18 }실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
19}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
21$Out = Join-Path $LearnerRoot 'evidence\w24\demo-script-review.json'실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
22New-Item -ItemType Directory -Force (Split-Path -Parent $Out) | Out-Null실행 의미: Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
23$Rows | ConvertTo-Json | Set-Content -Encoding utf8 $Out실행 의미: 검증된 object를 JSON evidence text로 직렬화한다.
24'W24_DEMO_SOURCE_AUDIT files=4 literal_secrets=0 hashes=4 runtime_claim=false'실행 의미: W24-D4-demo-source-audit.ps1의 다음 검증 또는 설명 단계를 구성한다.
07

STEP 07 / 13

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

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

한 줄로 읽기

W24 D4 source audit — 4개 demo script hash와 literal secret 검사는 packaged demo source 4개의 존재·bytes·SHA-256과 단순 literal secret 패턴만 검사해 runtime_claim=false evidence를 만든다.

문법 해부

  • .ps1 문법에서 선언·조건·pipeline·block 경계를 먼저 나눈다.
  • expected 값과 actual 결과를 같은 이름처럼 보여도 서로 다른 source로 읽는다.
  • native exit·row count·hash·사람 판정을 서로 대체하지 않는다.

실행 순서

  1. 입력 경로·fixture·환경변수·expected 계약을 고정한다.
  2. source가 실행하는 native process·HTTP·SQL 또는 형식 검사를 따라간다.
  3. actual 값과 exact marker를 대조하고 실패면 성공 발행 전에 중단한다.
  4. finally cleanup과 비범위를 evidence에 남긴다.

W24 조각별 정밀 해설

F12-C01 · 원문 1–12줄
문법 해부
.ps1 문법으로 1–12줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
files=4, literal_secrets=0, hashes=4를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
PDF-only 학습 예시다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
PDF-only 학습 예시다; DB/app을 실행하지 않는다; 실제 201→200→409→대사0 Green은 D7 책임이다
다음 연결
다음 조각 또는 F12 evidence 판정으로 상태를 넘긴다.
F12-C02 · 원문 13–24줄
문법 해부
.ps1 문법으로 13–24줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
files=4, literal_secrets=0, hashes=4를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
PDF-only 학습 예시다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
PDF-only 학습 예시다; DB/app을 실행하지 않는다; 실제 201→200→409→대사0 Green은 D7 책임이다
다음 연결
다음 조각 또는 F12 evidence 판정으로 상태를 넘긴다.
실행 순서 — W24 D4 source audit — 4개 demo script hash와 literal secret 검사히토리 → 니지카 → 료 → 키타
  1. 히토리

    literal_secrets=0가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 packaged demo source 4개의 존재·bytes·SHA-256과 단순 literal secret 패턴만 검사해 runtime_claim=false evidence를 만든다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘DB/app을 실행하지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 literal_secrets=0와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

08

STEP 08 / 13

실제 값 따라가기

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

순서들어온 값코드가 하는 일나온 값·상태경계
입력files=4source 계약에 대입F12 실행/설명 시작 상태PDF-only 학습 예시다
검증literal_secrets=0expected와 actual 또는 형식 대조통과 또는 첫 mismatchDB/app을 실행하지 않는다
증거runtime_claim=falsemarker·hash·row를 같은 run에 연결범위가 적힌 evidence 후보실제 201→200→409→대사0 Green은 D7 책임이다
실제 값 — W24 D4 source audit — 4개 demo script hash와 literal secret 검사히토리 → 니지카 → 료 → 키타
  1. 히토리

    hashes=4가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 packaged demo source 4개의 존재·bytes·SHA-256과 단순 literal secret 패턴만 검사해 runtime_claim=false evidence를 만든다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘실제 201→200→409→대사0 Green은 D7 책임이다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 hashes=4와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

09

STEP 09 / 13

Gradle·PowerShell·HTTP·PostgreSQL 내부에서 벌어지는 일

Gradle·JUnit XML·PowerShell·HTTP·PostgreSQL·Docker에서 실제로 일어나는 일과 증명 범위를 구분합니다.

source/contract

W24-D4-demo-source-audit.ps1 bytes와 expected 값을 읽는다.

파일 존재만으로 runtime 성공은 아니다.
execution/evidence

native exit·HTTP status·JUnit XML·DB row·hash 중 이 파일이 소유한 값을 만든다.

PDF-only 학습 예시다
release/human

관련 evidence와 사람 의미 검토를 release 후보에 연결한다.

실제 201→200→409→대사0 Green은 D7 책임이다
첫 실패 경계 — W24 D4 source audit — 4개 demo script hash와 literal secret 검사히토리 → 니지카 → 료 → 키타
  1. 히토리

    runtime_claim=false가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 packaged demo source 4개의 존재·bytes·SHA-256과 단순 literal secret 패턴만 검사해 runtime_claim=false evidence를 만든다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘PDF-only 학습 예시다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 runtime_claim=false와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

10

STEP 10 / 13

흔한 착각과 틀린 예

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

❌ files=4 문자열이 source에 있으니 실제 실행도 Green이다.

왜 틀리나 source literal과 runtime 관찰값은 다른 증거다.

바르게 읽기 native exit·actual XML/HTTP/DB evidence를 별도로 확인한다.

반례 script가 실행 전 경로 오류로 멈춰도 literal은 그대로 남는다.

❌ 파일 SHA-256이 있으면 내용의 의미와 사실성도 검증됐다.

왜 틀리나 hash는 동일 bytes만 말한다.

바르게 읽기 schema·수치·질문·근거는 별도 자동 또는 사람 판정을 거친다.

반례 빈 review 질문을 가진 CSV도 안정된 hash를 가진다.

❌ LOCAL_ARTIFACT_VALIDATED는 release Green과 같다.

왜 틀리나 generic validator는 파일 shape만 확인한다.

바르게 읽기 HUMAN_SEMANTIC_REVIEW_REQUIRED를 유지한다.

반례 잘못된 track 점수표도 byte 수 조건은 통과할 수 있다.

❌ 이 파일이 W24 전체 lifecycle을 모두 소유한다.

왜 틀리나 각 source는 Gate·demo·cleanup·사람 review 중 일부만 담당한다.

바르게 읽기 owner와 non-responsibility를 release manifest에서 분리한다.

반례 D4 source audit에는 runtime_claim=false가 명시된다.

❌ 이전 주 Green이나 오래된 log를 현재 commit 결과로 재사용한다.

왜 틀리나 source·commit·actual result가 같은 실행에 묶이지 않는다.

바르게 읽기 release 후보에서 새 evidence와 hash를 만든다.

반례 expected JSON이 바뀌면 예전 XML은 exact inventory를 증명하지 못한다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

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

증명 범위

PDF-only 학습 예시다

이 책임을 맡는 곳: runtime Gate
증명 범위

DB/app을 실행하지 않는다

이 책임을 맡는 곳: external/human review
증명 범위

실제 201→200→409→대사0 Green은 D7 책임이다

이 책임을 맡는 곳: release manifest
증명 범위

PDF-only 학습 예시다

이 책임을 맡는 곳: 운영 환경
증명하지 않는 범위 — W24 D4 source audit — 4개 demo script hash와 literal secret 검사히토리 → 니지카 → 료 → 키타
  1. 히토리

    files=4가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 packaged demo source 4개의 존재·bytes·SHA-256과 단순 literal secret 패턴만 검사해 runtime_claim=false evidence를 만든다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘DB/app을 실행하지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 files=4와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

12

STEP 12 / 13

직접 다시 써보기

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

1단계 · 뜻부터 복원

  • packaged demo source 4개의 존재·bytes·SHA-256과 단순 literal secret 패턴만 검사해 runtime_claim=false evidence를 만든다.
  • 핵심 값은 files=4, literal_secrets=0, hashes=4, runtime_claim=false다.

2단계 · 코드 조각 재조립

  1. 1. 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다
  2. 2. 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다
  3. 3. 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다
  4. 4. 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다
  5. 5. 고정 목록의 각 항목에 같은 검사를 반복 적용한다
  6. 6. 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다
  7. 7. 필수 파일이나 경로가 실제로 있는지 확인한다
  8. 8. 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다

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

illustrative/powershell/W24-D4-demo-source-audit.ps1을 새 파일에 다시 쓰고 expected·actual·실패·cleanup·비범위를 주석으로 표시한다.

자가 점검
  • 비어 있지 않은 모든 source 줄을 한 번씩 읽었나?
  • source shape와 runtime Green을 분리했나?
  • 사람 검토·외부 상태를 자동 성공으로 꾸미지 않았나?
  • 첫 실패와 cleanup 책임을 설명할 수 있나?
13

STEP 13 / 13

전체 원본 source

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

학습용 예시 전체 확인하기 · 정본 답안 아님
학습용 예시 · PDF inline PowerShell · 정본 답안 아님 · 비실행illustrative/powershell/W24-D4-demo-source-audit.ps1SHA-256 f96208ca2eee1d3e47e5521d3ecb2345358866dcb666cf7111387391fc195879
W24 D4 source audit — 4개 demo script hash와 literal secret 검사 전체
# W24 PDF p804의 source-only Gate를 읽기 좋게 정리한 학습용 예시다.
# 이 검사는 active DB/app lifecycle을 실행하지 않으며 runtime Green을 주장하지 않는다.
$Names = @('reset-demo.ps1', 'run-transfer.ps1', 'reconcile-demo.ps1', 'run-w24-demo.ps1')
$Rows = @()
foreach ($Name in $Names) {
  $Path = Join-Path $ReferenceRoot ('scripts\' + $Name)
  if (!(Test-Path -LiteralPath $Path -PathType Leaf)) {
    throw "missing packaged demo script: $Name"
  }
  $Text = Get-Content -Raw -LiteralPath $Path
  if ($Text -cmatch '(?i)(password\s*=\s*["''][^$]|Authorization:\s*Basic\s+[A-Za-z0-9])') {
    throw "literal secret in $Name"
  }
  $Rows += [ordered]@{
    file = $Name
    bytes = (Get-Item -LiteralPath $Path).Length
    sha256 = (Get-FileHash -LiteralPath $Path -Algorithm SHA256).Hash.ToLowerInvariant()
  }
}

$Out = Join-Path $LearnerRoot 'evidence\w24\demo-script-review.json'
New-Item -ItemType Directory -Force (Split-Path -Parent $Out) | Out-Null
$Rows | ConvertTo-Json | Set-Content -Encoding utf8 $Out
'W24_DEMO_SOURCE_AUDIT files=4 literal_secrets=0 hashes=4 runtime_claim=false'
13

W24 D5 external review — 형식 검사와 사람 의미 검증 분리

illustrative/markdown/W24-D5-external-review.md

학습용 예시 · PDF template/validator · 정본 답안 아님 · 학습용 예시 · 정본 답안 아님 · W24-F13
31줄 연결31줄 번역4 chunks
01

STEP 01 / 13

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

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

오늘의 한 문장

reviewer 질문·decision·reason·commit/issue CSV 골격과 generic bytes/hash 검사를 보여 주고, 행별 사실성은 사람에게 남긴다.

  1. minimum 5 questions은 어느 source와 실제 결과에서 확인해야 할까?
  2. 첫 실패를 만드는 조건과 fail-closed 지점은 어디일까?
  3. 왜 ‘실제 external review가 아니다’를 별도 경계로 남겨야 할까?
이 파일에서 끝까지 다시 쓰는 값minimum 5 questionsaccept/reject/deferLOCAL_ARTIFACT_VALIDATEDHUMAN_SEMANTIC_REVIEW_REQUIRED
왜 필요한가 — W24 D5 external review — 형식 검사와 사람 의미 검증 분리히토리 → 니지카 → 료 → 키타
  1. 히토리

    minimum 5 questions가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 reviewer 질문·decision·reason·commit/issue CSV 골격과 generic bytes/hash 검사를 보여 주고, 행별 사실성은 사람에게 남긴다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘실제 external review가 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 minimum 5 questions와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

02

STEP 02 / 13

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

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

새 기능을 멈춘 팀이 코드·test·문서·demo를 같은 release 후보에 묶어 하나씩 검수한다.

검수 도장이 붙은 공통 거래 코어 출고 상자

이 파일은 reviewer 질문·decision·reason·commit/issue CSV 골격과 generic bytes/hash 검사를 보여 주고, 행별 사실성은 사람에게 남긴다. 눈으로 읽을 때는 각 줄을 검수표 한 칸처럼 보고, 입력과 다음 상태를 놓치지 않는다.

마지막 도장은 source shape와 실제 runtime·사람 검토를 구분한 뒤에만 찍는다. 특히 실제 external review가 아니다

딱 여기까지만 비유는 실행 순서를 돕지만 실제 Gradle·Docker·DB·사람 review를 대신하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

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

값 1: minimum 5 questions

이 파일에서 계속 확인할 고정 단서가 minimum 5 questions다.

코드 연결
F13 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
실제 external review가 아니다

값 2: accept/reject/defer

이 파일에서 계속 확인할 고정 단서가 accept/reject/defer다.

코드 연결
F13 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
self-review로 대체하지 않는다

값 3: LOCAL_ARTIFACT_VALIDATED

이 파일에서 계속 확인할 고정 단서가 LOCAL_ARTIFACT_VALIDATED다.

코드 연결
F13 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
빈 행 수를 review 품질로 세지 않는다

값 4: HUMAN_SEMANTIC_REVIEW_REQUIRED

이 파일에서 계속 확인할 고정 단서가 HUMAN_SEMANTIC_REVIEW_REQUIRED다.

코드 연결
F13 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
실제 external review가 아니다
04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

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

단어 몇 개만 뽑은 표가 아닙니다.학습용 예시 · PDF template/validator · 정본 답안 아님에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.31 / 31 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F13-L01 # W24 D5 external review 학습 골격 출고표 1번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
이전 줄의 상태와 minimum 5 questions
결과·효과
관찰 상태 F13-001가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 external review가 아니다
3줄F13-L03 > PDF p806–807의 TEMPLATE와 generic validator를 한 파일에 모았다. 실제 외부 reviewer가 작성한 기록도, 사람 의미 검토 완료 증거도 아니다. 출고표 3번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D5-external-review.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 minimum 5 questions
결과·효과
관찰 상태 F13-003가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
빈 행 수를 review 품질로 세지 않는다
5줄F13-L05 ## Review CSV template 출고표 5번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
이전 줄의 상태와 minimum 5 questions
결과·효과
관찰 상태 F13-005가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
self-review로 대체하지 않는다
7줄F13-L07 id,reviewer_question,category,decision,reason,commit_or_issue 출고표 7번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D5-external-review.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 minimum 5 questions
결과·효과
관찰 상태 F13-007가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 external review가 아니다
8줄F13-L08 R1,,correctness,accept,, 출고표 8번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D5-external-review.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 minimum 5 questions
결과·효과
관찰 상태 F13-008가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
self-review로 대체하지 않는다
9줄F13-L09 R2,,scope,reject,, 출고표 9번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D5-external-review.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 minimum 5 questions
결과·효과
관찰 상태 F13-009가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
빈 행 수를 review 품질로 세지 않는다
10줄F13-L10 R3,,reproducibility,defer,, 출고표 10번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D5-external-review.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 minimum 5 questions
결과·효과
관찰 상태 F13-010가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 external review가 아니다
12줄F13-L12 ## 파일·hash 보조 검사 출고표 12번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
이전 줄의 상태와 minimum 5 questions
결과·효과
관찰 상태 F13-012가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
빈 행 수를 review 품질로 세지 않는다
14줄F13-L14 $Artifact = Join-Path $LearnerRoot 'evidence\w24\external-review.csv' 출고표 14번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Artifact, $LearnerRoot, 'evidence\w24\external-review.csv'
결과·효과
관찰 상태 F13-014가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
self-review로 대체하지 않는다
15줄F13-L15 if (!(Test-Path -LiteralPath $Artifact -PathType Leaf)) { 출고표 15번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 필수 파일이나 경로가 실제로 있는지 확인한다.
입력
$Artifact
결과·효과
관찰 상태 F13-015가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
빈 행 수를 review 품질로 세지 않는다
16줄F13-L16 throw "learner artifact missing: $Artifact" 출고표 16번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
"learner artifact missing: $Artifact"
결과·효과
관찰 상태 F13-016가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 external review가 아니다
17줄F13-L17 } 출고표 17번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 minimum 5 questions
결과·효과
관찰 상태 F13-017가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
self-review로 대체하지 않는다
18줄F13-L18 $Item = Get-Item -LiteralPath $Artifact 출고표 18번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Item, $Artifact
결과·효과
관찰 상태 F13-018가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
빈 행 수를 review 품질로 세지 않는다
19줄F13-L19 if ($Item.Length -lt 40) { 출고표 19번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$Item, 40
결과·효과
관찰 상태 F13-019가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 external review가 아니다
20줄F13-L20 throw "artifact is too small to support the claim: bytes=$($Item.Length)" 출고표 20번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
$Item
결과·효과
관찰 상태 F13-020가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
self-review로 대체하지 않는다
21줄F13-L21 } 출고표 21번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 minimum 5 questions
결과·효과
관찰 상태 F13-021가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
빈 행 수를 review 품질로 세지 않는다
22줄F13-L22 $Text = Get-Content -LiteralPath $Artifact -Raw 출고표 22번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Text, $Artifact
결과·효과
관찰 상태 F13-022가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 external review가 아니다
23줄F13-L23 if ($Text -match '(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b') { 출고표 23번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
입력
$Text, '(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b'
결과·효과
관찰 상태 F13-023가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
self-review로 대체하지 않는다
24줄F13-L24 throw 'unresolved placeholder in learner artifact' 출고표 24번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
이전 줄의 상태와 minimum 5 questions
결과·효과
관찰 상태 F13-024가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
빈 행 수를 review 품질로 세지 않는다
25줄F13-L25 } 출고표 25번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 minimum 5 questions
결과·효과
관찰 상태 F13-025가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 external review가 아니다
26줄F13-L26 $NonBlank = @($Text -split '[\r\n]+' | Where-Object { $_.Trim().Length -gt 0 }) 출고표 26번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건을 만족하는 row만 필터링한다.
입력
$NonBlank, $Text, '[\r\n]+'
결과·효과
관찰 상태 F13-026가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
self-review로 대체하지 않는다
27줄F13-L27 if ($NonBlank.Count -lt 3) { 출고표 27번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$NonBlank, 3
결과·효과
관찰 상태 F13-027가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
빈 행 수를 review 품질로 세지 않는다
28줄F13-L28 throw "artifact needs at least three nonblank evidence lines: $($NonBlank.Count)" 출고표 28번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
$NonBlank
결과·효과
관찰 상태 F13-028가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 external review가 아니다
29줄F13-L29 } 출고표 29번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 minimum 5 questions
결과·효과
관찰 상태 F13-029가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
self-review로 대체하지 않는다
30줄F13-L30 $Hash = (Get-FileHash -LiteralPath $Artifact -Algorithm SHA256).Hash.ToLowerInvariant() 출고표 30번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 현재 bytes를 64자리 digest로 evidence에 결박한다.
입력
$Hash, $Artifact
결과·효과
관찰 상태 F13-030가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
빈 행 수를 review 품질로 세지 않는다
31줄F13-L31 "LOCAL_ARTIFACT_VALIDATED W24D5 bytes=$($Item.Length) sha256=$Hash" 출고표 31번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 파일 bytes·기본 형식·hash만 통과한 보조 marker를 낸다.
입력
$Item, $Hash
결과·효과
관찰 상태 F13-031가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 external review가 아니다
33줄F13-L33 ## 반드시 남는 사람 판정 출고표 33번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
이전 줄의 상태와 minimum 5 questions
결과·효과
관찰 상태 F13-033가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
빈 행 수를 review 품질로 세지 않는다
35줄F13-L35 - 실제 reviewer identity·review 시각·대상 commit을 확인한다. 출고표 35번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D5-external-review.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 minimum 5 questions
결과·효과
관찰 상태 F13-035가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
self-review로 대체하지 않는다
36줄F13-L36 - 최소 다섯 질문의 decision·reason·commit/issue 연결을 원본과 대조한다. 출고표 36번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D5-external-review.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 minimum 5 questions
결과·효과
관찰 상태 F13-036가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
빈 행 수를 review 품질로 세지 않는다
37줄F13-L37 - LOCAL_ARTIFACT_VALIDATED는 Green이 아니다. 출고표 37번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 파일 bytes·기본 형식·hash만 통과한 보조 marker를 낸다.
입력
이전 줄의 상태와 minimum 5 questions
결과·효과
관찰 상태 F13-037가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 external review가 아니다
38줄F13-L38 - 서명 전 상태는 HUMAN_SEMANTIC_REVIEW_REQUIRED다. 출고표 38번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 review·점수·근거의 사실성을 사람이 대조해야 함을 고정한다.
입력
이전 줄의 상태와 minimum 5 questions
결과·효과
관찰 상태 F13-038가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
self-review로 대체하지 않는다
05

STEP 05 / 13

원본 코드 조각

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

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

F13-C01 · 원문 1–12줄1–12줄
1–12줄 원본
# W24 D5 external review 학습 골격

> PDF p806–807의 TEMPLATE와 generic validator를 한 파일에 모았다. 실제 외부 reviewer가 작성한 기록도, 사람 의미 검토 완료 증거도 아니다.

## Review CSV template

id,reviewer_question,category,decision,reason,commit_or_issue
R1,,correctness,accept,,
R2,,scope,reject,,
R3,,reproducibility,defer,,

## 파일·hash 보조 검사
F13-C02 · 원문 13–24줄13–24줄
13–24줄 원본

    $Artifact = Join-Path $LearnerRoot 'evidence\w24\external-review.csv'
    if (!(Test-Path -LiteralPath $Artifact -PathType Leaf)) {
      throw "learner artifact missing: $Artifact"
    }
    $Item = Get-Item -LiteralPath $Artifact
    if ($Item.Length -lt 40) {
      throw "artifact is too small to support the claim: bytes=$($Item.Length)"
    }
    $Text = Get-Content -LiteralPath $Artifact -Raw
    if ($Text -match '(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b') {
      throw 'unresolved placeholder in learner artifact'
F13-C03 · 원문 25–36줄25–36줄
25–36줄 원본
    }
    $NonBlank = @($Text -split '[\r\n]+' | Where-Object { $_.Trim().Length -gt 0 })
    if ($NonBlank.Count -lt 3) {
      throw "artifact needs at least three nonblank evidence lines: $($NonBlank.Count)"
    }
    $Hash = (Get-FileHash -LiteralPath $Artifact -Algorithm SHA256).Hash.ToLowerInvariant()
    "LOCAL_ARTIFACT_VALIDATED W24D5 bytes=$($Item.Length) sha256=$Hash"

## 반드시 남는 사람 판정

- 실제 reviewer identity·review 시각·대상 commit을 확인한다.
- 최소 다섯 질문의 decision·reason·commit/issue 연결을 원본과 대조한다.
F13-C04 · 원문 37–38줄37–38줄
37–38줄 원본
- LOCAL_ARTIFACT_VALIDATED는 Green이 아니다.
- 서명 전 상태는 HUMAN_SEMANTIC_REVIEW_REQUIRED다.
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

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

전체 번역 31 / 31

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

원본한국어 번역
1# W24 D5 external review 학습 골격문서 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
3> PDF p806–807의 TEMPLATE와 generic validator를 한 파일에 모았다. 실제 외부 reviewer가 작성한 기록도, 사람 의미 검토 완료 증거도 아니다.문서 의미: W24-D5-external-review.md의 다음 검증 또는 설명 단계를 구성한다.
5## Review CSV template문서 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
7id,reviewer_question,category,decision,reason,commit_or_issue문서 의미: W24-D5-external-review.md의 다음 검증 또는 설명 단계를 구성한다.
8R1,,correctness,accept,,문서 의미: W24-D5-external-review.md의 다음 검증 또는 설명 단계를 구성한다.
9R2,,scope,reject,,문서 의미: W24-D5-external-review.md의 다음 검증 또는 설명 단계를 구성한다.
10R3,,reproducibility,defer,,문서 의미: W24-D5-external-review.md의 다음 검증 또는 설명 단계를 구성한다.
12## 파일·hash 보조 검사문서 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
14 $Artifact = Join-Path $LearnerRoot 'evidence\w24\external-review.csv'문서 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
15 if (!(Test-Path -LiteralPath $Artifact -PathType Leaf)) {문서 의미: 필수 파일이나 경로가 실제로 있는지 확인한다.
16 throw "learner artifact missing: $Artifact"문서 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
17 }문서 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
18 $Item = Get-Item -LiteralPath $Artifact문서 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
19 if ($Item.Length -lt 40) {문서 의미: 조건·반복·함수의 실행 block을 연다.
20 throw "artifact is too small to support the claim: bytes=$($Item.Length)"문서 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
21 }문서 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
22 $Text = Get-Content -LiteralPath $Artifact -Raw문서 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
23 if ($Text -match '(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b') {문서 의미: Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
24 throw 'unresolved placeholder in learner artifact'문서 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
25 }문서 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
26 $NonBlank = @($Text -split '[\r\n]+' | Where-Object { $_.Trim().Length -gt 0 })문서 의미: 조건을 만족하는 row만 필터링한다.
27 if ($NonBlank.Count -lt 3) {문서 의미: 조건·반복·함수의 실행 block을 연다.
28 throw "artifact needs at least three nonblank evidence lines: $($NonBlank.Count)"문서 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
29 }문서 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
30 $Hash = (Get-FileHash -LiteralPath $Artifact -Algorithm SHA256).Hash.ToLowerInvariant()문서 의미: 현재 bytes를 64자리 digest로 evidence에 결박한다.
31 "LOCAL_ARTIFACT_VALIDATED W24D5 bytes=$($Item.Length) sha256=$Hash"문서 의미: 파일 bytes·기본 형식·hash만 통과한 보조 marker를 낸다.
33## 반드시 남는 사람 판정문서 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
35- 실제 reviewer identity·review 시각·대상 commit을 확인한다.문서 의미: W24-D5-external-review.md의 다음 검증 또는 설명 단계를 구성한다.
36- 최소 다섯 질문의 decision·reason·commit/issue 연결을 원본과 대조한다.문서 의미: W24-D5-external-review.md의 다음 검증 또는 설명 단계를 구성한다.
37- LOCAL_ARTIFACT_VALIDATED는 Green이 아니다.문서 의미: 파일 bytes·기본 형식·hash만 통과한 보조 marker를 낸다.
38- 서명 전 상태는 HUMAN_SEMANTIC_REVIEW_REQUIRED다.문서 의미: review·점수·근거의 사실성을 사람이 대조해야 함을 고정한다.
07

STEP 07 / 13

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

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

한 줄로 읽기

W24 D5 external review — 형식 검사와 사람 의미 검증 분리는 reviewer 질문·decision·reason·commit/issue CSV 골격과 generic bytes/hash 검사를 보여 주고, 행별 사실성은 사람에게 남긴다.

문법 해부

  • .md 문법에서 선언·조건·pipeline·block 경계를 먼저 나눈다.
  • expected 값과 actual 결과를 같은 이름처럼 보여도 서로 다른 source로 읽는다.
  • native exit·row count·hash·사람 판정을 서로 대체하지 않는다.

실행 순서

  1. 입력 경로·fixture·환경변수·expected 계약을 고정한다.
  2. source가 실행하는 native process·HTTP·SQL 또는 형식 검사를 따라간다.
  3. actual 값과 exact marker를 대조하고 실패면 성공 발행 전에 중단한다.
  4. finally cleanup과 비범위를 evidence에 남긴다.

W24 조각별 정밀 해설

F13-C01 · 원문 1–12줄
문법 해부
.md 문법으로 1–12줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
minimum 5 questions, accept/reject/defer, LOCAL_ARTIFACT_VALIDATED를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
실제 external review가 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
실제 external review가 아니다; self-review로 대체하지 않는다; 빈 행 수를 review 품질로 세지 않는다
다음 연결
다음 조각 또는 F13 evidence 판정으로 상태를 넘긴다.
F13-C02 · 원문 13–24줄
문법 해부
.md 문법으로 13–24줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
minimum 5 questions, accept/reject/defer, LOCAL_ARTIFACT_VALIDATED를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
실제 external review가 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
실제 external review가 아니다; self-review로 대체하지 않는다; 빈 행 수를 review 품질로 세지 않는다
다음 연결
다음 조각 또는 F13 evidence 판정으로 상태를 넘긴다.
F13-C03 · 원문 25–36줄
문법 해부
.md 문법으로 25–36줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
minimum 5 questions, accept/reject/defer, LOCAL_ARTIFACT_VALIDATED를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
실제 external review가 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
실제 external review가 아니다; self-review로 대체하지 않는다; 빈 행 수를 review 품질로 세지 않는다
다음 연결
다음 조각 또는 F13 evidence 판정으로 상태를 넘긴다.
F13-C04 · 원문 37–38줄
문법 해부
.md 문법으로 37–38줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
minimum 5 questions, accept/reject/defer, LOCAL_ARTIFACT_VALIDATED를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
실제 external review가 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
실제 external review가 아니다; self-review로 대체하지 않는다; 빈 행 수를 review 품질로 세지 않는다
다음 연결
다음 조각 또는 F13 evidence 판정으로 상태를 넘긴다.
실행 순서 — W24 D5 external review — 형식 검사와 사람 의미 검증 분리히토리 → 니지카 → 료 → 키타
  1. 히토리

    accept/reject/defer가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 reviewer 질문·decision·reason·commit/issue CSV 골격과 generic bytes/hash 검사를 보여 주고, 행별 사실성은 사람에게 남긴다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘self-review로 대체하지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 accept/reject/defer와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

08

STEP 08 / 13

실제 값 따라가기

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

순서들어온 값코드가 하는 일나온 값·상태경계
입력minimum 5 questionssource 계약에 대입F13 실행/설명 시작 상태실제 external review가 아니다
검증accept/reject/deferexpected와 actual 또는 형식 대조통과 또는 첫 mismatchself-review로 대체하지 않는다
증거HUMAN_SEMANTIC_REVIEW_REQUIREDmarker·hash·row를 같은 run에 연결범위가 적힌 evidence 후보빈 행 수를 review 품질로 세지 않는다
실제 값 — W24 D5 external review — 형식 검사와 사람 의미 검증 분리히토리 → 니지카 → 료 → 키타
  1. 히토리

    LOCAL_ARTIFACT_VALIDATED가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 reviewer 질문·decision·reason·commit/issue CSV 골격과 generic bytes/hash 검사를 보여 주고, 행별 사실성은 사람에게 남긴다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘빈 행 수를 review 품질로 세지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 LOCAL_ARTIFACT_VALIDATED와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

09

STEP 09 / 13

Gradle·PowerShell·HTTP·PostgreSQL 내부에서 벌어지는 일

Gradle·JUnit XML·PowerShell·HTTP·PostgreSQL·Docker에서 실제로 일어나는 일과 증명 범위를 구분합니다.

source/contract

W24-D5-external-review.md bytes와 expected 값을 읽는다.

파일 존재만으로 runtime 성공은 아니다.
execution/evidence

native exit·HTTP status·JUnit XML·DB row·hash 중 이 파일이 소유한 값을 만든다.

실제 external review가 아니다
release/human

관련 evidence와 사람 의미 검토를 release 후보에 연결한다.

빈 행 수를 review 품질로 세지 않는다
첫 실패 경계 — W24 D5 external review — 형식 검사와 사람 의미 검증 분리히토리 → 니지카 → 료 → 키타
  1. 히토리

    HUMAN_SEMANTIC_REVIEW_REQUIRED가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 reviewer 질문·decision·reason·commit/issue CSV 골격과 generic bytes/hash 검사를 보여 주고, 행별 사실성은 사람에게 남긴다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘실제 external review가 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 HUMAN_SEMANTIC_REVIEW_REQUIRED와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

10

STEP 10 / 13

흔한 착각과 틀린 예

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

❌ minimum 5 questions 문자열이 source에 있으니 실제 실행도 Green이다.

왜 틀리나 source literal과 runtime 관찰값은 다른 증거다.

바르게 읽기 native exit·actual XML/HTTP/DB evidence를 별도로 확인한다.

반례 script가 실행 전 경로 오류로 멈춰도 literal은 그대로 남는다.

❌ 파일 SHA-256이 있으면 내용의 의미와 사실성도 검증됐다.

왜 틀리나 hash는 동일 bytes만 말한다.

바르게 읽기 schema·수치·질문·근거는 별도 자동 또는 사람 판정을 거친다.

반례 빈 review 질문을 가진 CSV도 안정된 hash를 가진다.

❌ LOCAL_ARTIFACT_VALIDATED는 release Green과 같다.

왜 틀리나 generic validator는 파일 shape만 확인한다.

바르게 읽기 HUMAN_SEMANTIC_REVIEW_REQUIRED를 유지한다.

반례 잘못된 track 점수표도 byte 수 조건은 통과할 수 있다.

❌ 이 파일이 W24 전체 lifecycle을 모두 소유한다.

왜 틀리나 각 source는 Gate·demo·cleanup·사람 review 중 일부만 담당한다.

바르게 읽기 owner와 non-responsibility를 release manifest에서 분리한다.

반례 D4 source audit에는 runtime_claim=false가 명시된다.

❌ 이전 주 Green이나 오래된 log를 현재 commit 결과로 재사용한다.

왜 틀리나 source·commit·actual result가 같은 실행에 묶이지 않는다.

바르게 읽기 release 후보에서 새 evidence와 hash를 만든다.

반례 expected JSON이 바뀌면 예전 XML은 exact inventory를 증명하지 못한다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

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

증명 범위

실제 external review가 아니다

이 책임을 맡는 곳: runtime Gate
증명 범위

self-review로 대체하지 않는다

이 책임을 맡는 곳: external/human review
증명 범위

빈 행 수를 review 품질로 세지 않는다

이 책임을 맡는 곳: release manifest
증명 범위

실제 external review가 아니다

이 책임을 맡는 곳: 운영 환경
증명하지 않는 범위 — W24 D5 external review — 형식 검사와 사람 의미 검증 분리히토리 → 니지카 → 료 → 키타
  1. 히토리

    minimum 5 questions가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 reviewer 질문·decision·reason·commit/issue CSV 골격과 generic bytes/hash 검사를 보여 주고, 행별 사실성은 사람에게 남긴다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘self-review로 대체하지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 minimum 5 questions와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

12

STEP 12 / 13

직접 다시 써보기

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

1단계 · 뜻부터 복원

  • reviewer 질문·decision·reason·commit/issue CSV 골격과 generic bytes/hash 검사를 보여 주고, 행별 사실성은 사람에게 남긴다.
  • 핵심 값은 minimum 5 questions, accept/reject/defer, LOCAL_ARTIFACT_VALIDATED, HUMAN_SEMANTIC_REVIEW_REQUIRED다.

2단계 · 코드 조각 재조립

  1. 1. 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다
  2. 3. W24-D5-external-review.md의 다음 검증 또는 설명 단계를 구성한다
  3. 5. 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다
  4. 7. W24-D5-external-review.md의 다음 검증 또는 설명 단계를 구성한다
  5. 8. W24-D5-external-review.md의 다음 검증 또는 설명 단계를 구성한다
  6. 9. W24-D5-external-review.md의 다음 검증 또는 설명 단계를 구성한다
  7. 10. W24-D5-external-review.md의 다음 검증 또는 설명 단계를 구성한다
  8. 12. 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다

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

illustrative/markdown/W24-D5-external-review.md을 새 파일에 다시 쓰고 expected·actual·실패·cleanup·비범위를 주석으로 표시한다.

자가 점검
  • 비어 있지 않은 모든 source 줄을 한 번씩 읽었나?
  • source shape와 runtime Green을 분리했나?
  • 사람 검토·외부 상태를 자동 성공으로 꾸미지 않았나?
  • 첫 실패와 cleanup 책임을 설명할 수 있나?
13

STEP 13 / 13

전체 원본 source

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

학습용 예시 전체 확인하기 · 정본 답안 아님
학습용 예시 · PDF template/validator · 정본 답안 아님illustrative/markdown/W24-D5-external-review.mdSHA-256 ad8138e360a03731d9ff9800c592160c2ed503bf83bc63a690959362083128ef
W24 D5 external review — 형식 검사와 사람 의미 검증 분리 전체
# W24 D5 external review 학습 골격

> PDF p806–807의 TEMPLATE와 generic validator를 한 파일에 모았다. 실제 외부 reviewer가 작성한 기록도, 사람 의미 검토 완료 증거도 아니다.

## Review CSV template

id,reviewer_question,category,decision,reason,commit_or_issue
R1,,correctness,accept,,
R2,,scope,reject,,
R3,,reproducibility,defer,,

## 파일·hash 보조 검사

    $Artifact = Join-Path $LearnerRoot 'evidence\w24\external-review.csv'
    if (!(Test-Path -LiteralPath $Artifact -PathType Leaf)) {
      throw "learner artifact missing: $Artifact"
    }
    $Item = Get-Item -LiteralPath $Artifact
    if ($Item.Length -lt 40) {
      throw "artifact is too small to support the claim: bytes=$($Item.Length)"
    }
    $Text = Get-Content -LiteralPath $Artifact -Raw
    if ($Text -match '(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b') {
      throw 'unresolved placeholder in learner artifact'
    }
    $NonBlank = @($Text -split '[\r\n]+' | Where-Object { $_.Trim().Length -gt 0 })
    if ($NonBlank.Count -lt 3) {
      throw "artifact needs at least three nonblank evidence lines: $($NonBlank.Count)"
    }
    $Hash = (Get-FileHash -LiteralPath $Artifact -Algorithm SHA256).Hash.ToLowerInvariant()
    "LOCAL_ARTIFACT_VALIDATED W24D5 bytes=$($Item.Length) sha256=$Hash"

## 반드시 남는 사람 판정

- 실제 reviewer identity·review 시각·대상 commit을 확인한다.
- 최소 다섯 질문의 decision·reason·commit/issue 연결을 원본과 대조한다.
- LOCAL_ARTIFACT_VALIDATED는 Green이 아니다.
- 서명 전 상태는 HUMAN_SEMANTIC_REVIEW_REQUIRED다.
14

W24-SQL-Q40 — 상태별 상위 10% 고액 거래

illustrative/sql/W24-SQL-Q40.sql

학습용 예시 · Q39/Q40 prompt 기반 SQL · 정본 답안 아님 · workbook 제공 정답 아님 · 학습용 예시 · 정본 답안 아님 · W24-F14
28줄 연결28줄 번역3 chunks
01

STEP 01 / 13

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

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

오늘의 한 문장

status별 PERCENT_RANK를 계산해 고액 상위 후보를 고르고 작은 표본과 cutoff 동률이 결과 cardinality에 미치는 영향을 드러낸다.

  1. PERCENT_RANK은 어느 source와 실제 결과에서 확인해야 할까?
  2. 첫 실패를 만드는 조건과 fail-closed 지점은 어디일까?
  3. 왜 ‘workbook 제공 정답이 아니다’를 별도 경계로 남겨야 할까?
이 파일에서 끝까지 다시 쓰는 값PERCENT_RANKPARTITION BY status<=0.10small sampleties
왜 필요한가 — W24-SQL-Q40 — 상태별 상위 10% 고액 거래히토리 → 니지카 → 료 → 키타
  1. 히토리

    PERCENT_RANK가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 status별 PERCENT_RANK를 계산해 고액 상위 후보를 고르고 작은 표본과 cutoff 동률이 결과 cardinality에 미치는 영향을 드러낸다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘workbook 제공 정답이 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 PERCENT_RANK와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

02

STEP 02 / 13

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

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

새 기능을 멈춘 팀이 코드·test·문서·demo를 같은 release 후보에 묶어 하나씩 검수한다.

검수 도장이 붙은 공통 거래 코어 출고 상자

이 파일은 status별 PERCENT_RANK를 계산해 고액 상위 후보를 고르고 작은 표본과 cutoff 동률이 결과 cardinality에 미치는 영향을 드러낸다. 눈으로 읽을 때는 각 줄을 검수표 한 칸처럼 보고, 입력과 다음 상태를 놓치지 않는다.

마지막 도장은 source shape와 실제 runtime·사람 검토를 구분한 뒤에만 찍는다. 특히 workbook 제공 정답이 아니다

딱 여기까지만 비유는 실행 순서를 돕지만 실제 Gradle·Docker·DB·사람 review를 대신하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

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

값 1: PERCENT_RANK

이 파일에서 계속 확인할 고정 단서가 PERCENT_RANK다.

코드 연결
F14 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
workbook 제공 정답이 아니다

값 2: PARTITION BY status

이 파일에서 계속 확인할 고정 단서가 PARTITION BY status다.

코드 연결
F14 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
정확히 10% 행 수를 보장하지 않는다

값 3: <=0.10

이 파일에서 계속 확인할 고정 단서가 <=0.10다.

코드 연결
F14 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
실제 PostgreSQL 실행 결과가 아니다

값 4: small sample

이 파일에서 계속 확인할 고정 단서가 small sample다.

코드 연결
F14 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
workbook 제공 정답이 아니다

값 5: ties

이 파일에서 계속 확인할 고정 단서가 ties다.

코드 연결
F14 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
정확히 10% 행 수를 보장하지 않는다
04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

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

단어 몇 개만 뽑은 표가 아닙니다.학습용 예시 · Q39/Q40 prompt 기반 SQL · 정본 답안 아님 · workbook 제공 정답 아님에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.28 / 28 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F14-L01 -- W24-SQL-Q40 학습용 예시이며 workbook 제공 정답이 아니다. 출고표 1번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-001가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
2줄F14-L02 -- 입력 grain: business_tx 한 행 = 거래 한 건. 출력 grain: 상태별 상위 10% 후보 거래 한 행. 출고표 2번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
10
결과·효과
관찰 상태 F14-002가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
정확히 10% 행 수를 보장하지 않는다
3줄F14-L03 -- PERCENT_RANK는 같은 amount의 동률을 같은 순위로 보존하므로 결과가 정확히 10% 행 수가 아닐 수 있다. 출고표 3번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 상태 partition 안에서 금액의 상대 순위를 0부터 계산한다.
입력
10
결과·효과
관찰 상태 F14-003가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
4줄F14-L04 WITH ranked AS ( 출고표 4번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-004가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
5줄F14-L05 SELECT 출고표 5번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-005가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
정확히 10% 행 수를 보장하지 않는다
6줄F14-L06 tx_id, 출고표 6번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-006가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
7줄F14-L07 status, 출고표 7번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-007가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
8줄F14-L08 amount, 출고표 8번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-008가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
정확히 10% 행 수를 보장하지 않는다
9줄F14-L09 occurred_at, 출고표 9번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-009가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
10줄F14-L10 PERCENT_RANK() OVER ( 출고표 10번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 상태 partition 안에서 금액의 상대 순위를 0부터 계산한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-010가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
11줄F14-L11 PARTITION BY status 출고표 11번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 각 status를 서로 독립된 window 집합으로 나눈다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-011가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
정확히 10% 행 수를 보장하지 않는다
12줄F14-L12 ORDER BY amount DESC 출고표 12번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 출력 또는 window 계산 순서를 안정적으로 정한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-012가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
13줄F14-L13 ) AS amount_percent_rank, 출고표 13번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 상태 partition 안에서 금액의 상대 순위를 0부터 계산한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-013가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
14줄F14-L14 COUNT(*) OVER (PARTITION BY status) AS status_rows 출고표 14번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 각 status를 서로 독립된 window 집합으로 나눈다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-014가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
정확히 10% 행 수를 보장하지 않는다
15줄F14-L15 FROM business_tx 출고표 15번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-015가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
16줄F14-L16 ) 출고표 16번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-016가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
17줄F14-L17 SELECT 출고표 17번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-017가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
정확히 10% 행 수를 보장하지 않는다
18줄F14-L18 tx_id, 출고표 18번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-018가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
19줄F14-L19 status, 출고표 19번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-019가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
20줄F14-L20 amount, 출고표 20번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-020가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
정확히 10% 행 수를 보장하지 않는다
21줄F14-L21 occurred_at, 출고표 21번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-021가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
22줄F14-L22 amount_percent_rank, 출고표 22번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 상태 partition 안에서 금액의 상대 순위를 0부터 계산한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-022가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
23줄F14-L23 status_rows 출고표 23번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-023가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
정확히 10% 행 수를 보장하지 않는다
24줄F14-L24 FROM ranked 출고표 24번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 SQL 집합의 입력·변환·필터 단계를 선언한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-024가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 PostgreSQL 실행 결과가 아니다
25줄F14-L25 WHERE amount_percent_rank <= 0.10 출고표 25번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 상태 partition 안에서 금액의 상대 순위를 0부터 계산한다.
입력
0, 10
결과·효과
관찰 상태 F14-025가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
26줄F14-L26 ORDER BY status, amount DESC, tx_id; 출고표 26번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 출력 또는 window 계산 순서를 안정적으로 정한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-026가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
정확히 10% 행 수를 보장하지 않는다
28줄F14-L28 -- 작은 표본 한계: 상태에 한 행만 있으면 percent_rank=0이라 그 한 행이 포함된다. 출고표 28번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 상태 partition 안에서 금액의 상대 순위를 0부터 계산한다.
입력
이전 줄의 상태와 PERCENT_RANK
결과·효과
관찰 상태 F14-028가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
workbook 제공 정답이 아니다
29줄F14-L29 -- 동률 반례: cutoff의 같은 amount는 함께 포함되어 한 상태에서 10%보다 많은 행이 나올 수 있다. 출고표 29번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
입력
10
결과·효과
관찰 상태 F14-029가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
정확히 10% 행 수를 보장하지 않는다
05

STEP 05 / 13

원본 코드 조각

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

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

F14-C01 · 원문 1–12줄1–12줄
1–12줄 원본
-- W24-SQL-Q40 학습용 예시이며 workbook 제공 정답이 아니다.
-- 입력 grain: business_tx 한 행 = 거래 한 건. 출력 grain: 상태별 상위 10% 후보 거래 한 행.
-- PERCENT_RANK는 같은 amount의 동률을 같은 순위로 보존하므로 결과가 정확히 10% 행 수가 아닐 수 있다.
WITH ranked AS (
  SELECT
    tx_id,
    status,
    amount,
    occurred_at,
    PERCENT_RANK() OVER (
      PARTITION BY status
      ORDER BY amount DESC
F14-C02 · 원문 13–24줄13–24줄
13–24줄 원본
    ) AS amount_percent_rank,
    COUNT(*) OVER (PARTITION BY status) AS status_rows
  FROM business_tx
)
SELECT
  tx_id,
  status,
  amount,
  occurred_at,
  amount_percent_rank,
  status_rows
FROM ranked
F14-C03 · 원문 25–29줄25–29줄
25–29줄 원본
WHERE amount_percent_rank <= 0.10
ORDER BY status, amount DESC, tx_id;

-- 작은 표본 한계: 상태에 한 행만 있으면 percent_rank=0이라 그 한 행이 포함된다.
-- 동률 반례: cutoff의 같은 amount는 함께 포함되어 한 상태에서 10%보다 많은 행이 나올 수 있다.
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

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

전체 번역 28 / 28

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

원본한국어 번역
1-- W24-SQL-Q40 학습용 예시이며 workbook 제공 정답이 아니다.실행 의미: W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
2-- 입력 grain: business_tx 한 행 = 거래 한 건. 출력 grain: 상태별 상위 10% 후보 거래 한 행.실행 의미: W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
3-- PERCENT_RANK는 같은 amount의 동률을 같은 순위로 보존하므로 결과가 정확히 10% 행 수가 아닐 수 있다.실행 의미: 상태 partition 안에서 금액의 상대 순위를 0부터 계산한다.
4WITH ranked AS (실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
5 SELECT실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
6 tx_id,실행 의미: W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
7 status,실행 의미: W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
8 amount,실행 의미: W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
9 occurred_at,실행 의미: W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
10 PERCENT_RANK() OVER (실행 의미: 상태 partition 안에서 금액의 상대 순위를 0부터 계산한다.
11 PARTITION BY status실행 의미: 각 status를 서로 독립된 window 집합으로 나눈다.
12 ORDER BY amount DESC실행 의미: 출력 또는 window 계산 순서를 안정적으로 정한다.
13 ) AS amount_percent_rank,실행 의미: 상태 partition 안에서 금액의 상대 순위를 0부터 계산한다.
14 COUNT(*) OVER (PARTITION BY status) AS status_rows실행 의미: 각 status를 서로 독립된 window 집합으로 나눈다.
15 FROM business_tx실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
16)실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
17SELECT실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
18 tx_id,실행 의미: W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
19 status,실행 의미: W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
20 amount,실행 의미: W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
21 occurred_at,실행 의미: W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
22 amount_percent_rank,실행 의미: 상태 partition 안에서 금액의 상대 순위를 0부터 계산한다.
23 status_rows실행 의미: W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
24FROM ranked실행 의미: SQL 집합의 입력·변환·필터 단계를 선언한다.
25WHERE amount_percent_rank <= 0.10실행 의미: 상태 partition 안에서 금액의 상대 순위를 0부터 계산한다.
26ORDER BY status, amount DESC, tx_id;실행 의미: 출력 또는 window 계산 순서를 안정적으로 정한다.
28-- 작은 표본 한계: 상태에 한 행만 있으면 percent_rank=0이라 그 한 행이 포함된다.실행 의미: 상태 partition 안에서 금액의 상대 순위를 0부터 계산한다.
29-- 동률 반례: cutoff의 같은 amount는 함께 포함되어 한 상태에서 10%보다 많은 행이 나올 수 있다.실행 의미: W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다.
07

STEP 07 / 13

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

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

한 줄로 읽기

W24-SQL-Q40 — 상태별 상위 10% 고액 거래는 status별 PERCENT_RANK를 계산해 고액 상위 후보를 고르고 작은 표본과 cutoff 동률이 결과 cardinality에 미치는 영향을 드러낸다.

문법 해부

  • .sql 문법에서 선언·조건·pipeline·block 경계를 먼저 나눈다.
  • expected 값과 actual 결과를 같은 이름처럼 보여도 서로 다른 source로 읽는다.
  • native exit·row count·hash·사람 판정을 서로 대체하지 않는다.

실행 순서

  1. 입력 경로·fixture·환경변수·expected 계약을 고정한다.
  2. source가 실행하는 native process·HTTP·SQL 또는 형식 검사를 따라간다.
  3. actual 값과 exact marker를 대조하고 실패면 성공 발행 전에 중단한다.
  4. finally cleanup과 비범위를 evidence에 남긴다.

W24 조각별 정밀 해설

F14-C01 · 원문 1–12줄
문법 해부
.sql 문법으로 1–12줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
PERCENT_RANK, PARTITION BY status, <=0.10를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
workbook 제공 정답이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
workbook 제공 정답이 아니다; 정확히 10% 행 수를 보장하지 않는다; 실제 PostgreSQL 실행 결과가 아니다
다음 연결
다음 조각 또는 F14 evidence 판정으로 상태를 넘긴다.
F14-C02 · 원문 13–24줄
문법 해부
.sql 문법으로 13–24줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
PERCENT_RANK, PARTITION BY status, <=0.10를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
workbook 제공 정답이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
workbook 제공 정답이 아니다; 정확히 10% 행 수를 보장하지 않는다; 실제 PostgreSQL 실행 결과가 아니다
다음 연결
다음 조각 또는 F14 evidence 판정으로 상태를 넘긴다.
F14-C03 · 원문 25–29줄
문법 해부
.sql 문법으로 25–29줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
PERCENT_RANK, PARTITION BY status, <=0.10를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
workbook 제공 정답이 아니다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
workbook 제공 정답이 아니다; 정확히 10% 행 수를 보장하지 않는다; 실제 PostgreSQL 실행 결과가 아니다
다음 연결
다음 조각 또는 F14 evidence 판정으로 상태를 넘긴다.
실행 순서 — W24-SQL-Q40 — 상태별 상위 10% 고액 거래히토리 → 니지카 → 료 → 키타
  1. 히토리

    PARTITION BY status가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 status별 PERCENT_RANK를 계산해 고액 상위 후보를 고르고 작은 표본과 cutoff 동률이 결과 cardinality에 미치는 영향을 드러낸다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘정확히 10% 행 수를 보장하지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 PARTITION BY status와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

08

STEP 08 / 13

실제 값 따라가기

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

순서들어온 값코드가 하는 일나온 값·상태경계
입력PERCENT_RANKsource 계약에 대입F14 실행/설명 시작 상태workbook 제공 정답이 아니다
검증PARTITION BY statusexpected와 actual 또는 형식 대조통과 또는 첫 mismatch정확히 10% 행 수를 보장하지 않는다
증거tiesmarker·hash·row를 같은 run에 연결범위가 적힌 evidence 후보실제 PostgreSQL 실행 결과가 아니다
실제 값 — W24-SQL-Q40 — 상태별 상위 10% 고액 거래히토리 → 니지카 → 료 → 키타
  1. 히토리

    <=0.10가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 status별 PERCENT_RANK를 계산해 고액 상위 후보를 고르고 작은 표본과 cutoff 동률이 결과 cardinality에 미치는 영향을 드러낸다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘실제 PostgreSQL 실행 결과가 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 <=0.10와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

09

STEP 09 / 13

Gradle·PowerShell·HTTP·PostgreSQL 내부에서 벌어지는 일

Gradle·JUnit XML·PowerShell·HTTP·PostgreSQL·Docker에서 실제로 일어나는 일과 증명 범위를 구분합니다.

source/contract

W24-SQL-Q40.sql bytes와 expected 값을 읽는다.

파일 존재만으로 runtime 성공은 아니다.
execution/evidence

native exit·HTTP status·JUnit XML·DB row·hash 중 이 파일이 소유한 값을 만든다.

workbook 제공 정답이 아니다
release/human

관련 evidence와 사람 의미 검토를 release 후보에 연결한다.

실제 PostgreSQL 실행 결과가 아니다
첫 실패 경계 — W24-SQL-Q40 — 상태별 상위 10% 고액 거래히토리 → 니지카 → 료 → 키타
  1. 히토리

    small sample가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 status별 PERCENT_RANK를 계산해 고액 상위 후보를 고르고 작은 표본과 cutoff 동률이 결과 cardinality에 미치는 영향을 드러낸다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘workbook 제공 정답이 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 small sample와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

10

STEP 10 / 13

흔한 착각과 틀린 예

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

❌ PERCENT_RANK 문자열이 source에 있으니 실제 실행도 Green이다.

왜 틀리나 source literal과 runtime 관찰값은 다른 증거다.

바르게 읽기 native exit·actual XML/HTTP/DB evidence를 별도로 확인한다.

반례 script가 실행 전 경로 오류로 멈춰도 literal은 그대로 남는다.

❌ 파일 SHA-256이 있으면 내용의 의미와 사실성도 검증됐다.

왜 틀리나 hash는 동일 bytes만 말한다.

바르게 읽기 schema·수치·질문·근거는 별도 자동 또는 사람 판정을 거친다.

반례 빈 review 질문을 가진 CSV도 안정된 hash를 가진다.

❌ LOCAL_ARTIFACT_VALIDATED는 release Green과 같다.

왜 틀리나 generic validator는 파일 shape만 확인한다.

바르게 읽기 HUMAN_SEMANTIC_REVIEW_REQUIRED를 유지한다.

반례 잘못된 track 점수표도 byte 수 조건은 통과할 수 있다.

❌ 이 파일이 W24 전체 lifecycle을 모두 소유한다.

왜 틀리나 각 source는 Gate·demo·cleanup·사람 review 중 일부만 담당한다.

바르게 읽기 owner와 non-responsibility를 release manifest에서 분리한다.

반례 D4 source audit에는 runtime_claim=false가 명시된다.

❌ 이전 주 Green이나 오래된 log를 현재 commit 결과로 재사용한다.

왜 틀리나 source·commit·actual result가 같은 실행에 묶이지 않는다.

바르게 읽기 release 후보에서 새 evidence와 hash를 만든다.

반례 expected JSON이 바뀌면 예전 XML은 exact inventory를 증명하지 못한다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

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

증명 범위

workbook 제공 정답이 아니다

이 책임을 맡는 곳: runtime Gate
증명 범위

정확히 10% 행 수를 보장하지 않는다

이 책임을 맡는 곳: external/human review
증명 범위

실제 PostgreSQL 실행 결과가 아니다

이 책임을 맡는 곳: release manifest
증명 범위

workbook 제공 정답이 아니다

이 책임을 맡는 곳: 운영 환경
증명하지 않는 범위 — W24-SQL-Q40 — 상태별 상위 10% 고액 거래히토리 → 니지카 → 료 → 키타
  1. 히토리

    ties가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 status별 PERCENT_RANK를 계산해 고액 상위 후보를 고르고 작은 표본과 cutoff 동률이 결과 cardinality에 미치는 영향을 드러낸다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘정확히 10% 행 수를 보장하지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 ties와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

12

STEP 12 / 13

직접 다시 써보기

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

1단계 · 뜻부터 복원

  • status별 PERCENT_RANK를 계산해 고액 상위 후보를 고르고 작은 표본과 cutoff 동률이 결과 cardinality에 미치는 영향을 드러낸다.
  • 핵심 값은 PERCENT_RANK, PARTITION BY status, <=0.10, small sample, ties다.

2단계 · 코드 조각 재조립

  1. 1. W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다
  2. 2. W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다
  3. 3. 상태 partition 안에서 금액의 상대 순위를 0부터 계산한다
  4. 4. SQL 집합의 입력·변환·필터 단계를 선언한다
  5. 5. SQL 집합의 입력·변환·필터 단계를 선언한다
  6. 6. W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다
  7. 7. W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다
  8. 8. W24-SQL-Q40.sql의 다음 검증 또는 설명 단계를 구성한다

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

illustrative/sql/W24-SQL-Q40.sql을 새 파일에 다시 쓰고 expected·actual·실패·cleanup·비범위를 주석으로 표시한다.

자가 점검
  • 비어 있지 않은 모든 source 줄을 한 번씩 읽었나?
  • source shape와 runtime Green을 분리했나?
  • 사람 검토·외부 상태를 자동 성공으로 꾸미지 않았나?
  • 첫 실패와 cleanup 책임을 설명할 수 있나?
13

STEP 13 / 13

전체 원본 source

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

학습용 예시 전체 확인하기 · 정본 답안 아님
학습용 예시 · Q39/Q40 prompt 기반 SQL · 정본 답안 아님 · workbook 제공 정답 아님illustrative/sql/W24-SQL-Q40.sqlSHA-256 dcbf68b7e46dd19a9a7e24df302c9632257ae8ad2b7fa949e8194b8132ebd9b5
W24-SQL-Q40 — 상태별 상위 10% 고액 거래 전체
-- W24-SQL-Q40 학습용 예시이며 workbook 제공 정답이 아니다.
-- 입력 grain: business_tx 한 행 = 거래 한 건. 출력 grain: 상태별 상위 10% 후보 거래 한 행.
-- PERCENT_RANK는 같은 amount의 동률을 같은 순위로 보존하므로 결과가 정확히 10% 행 수가 아닐 수 있다.
WITH ranked AS (
  SELECT
    tx_id,
    status,
    amount,
    occurred_at,
    PERCENT_RANK() OVER (
      PARTITION BY status
      ORDER BY amount DESC
    ) AS amount_percent_rank,
    COUNT(*) OVER (PARTITION BY status) AS status_rows
  FROM business_tx
)
SELECT
  tx_id,
  status,
  amount,
  occurred_at,
  amount_percent_rank,
  status_rows
FROM ranked
WHERE amount_percent_rank <= 0.10
ORDER BY status, amount DESC, tx_id;

-- 작은 표본 한계: 상태에 한 행만 있으면 percent_rank=0이라 그 한 행이 포함된다.
-- 동률 반례: cutoff의 같은 amount는 함께 포함되어 한 상태에서 10%보다 많은 행이 나올 수 있다.
15

W24 D6 track selection — 가중치 100과 정확히 한 track

illustrative/markdown/W24-D6-track-selection.md

학습용 예시 · PDF template/validator · 정본 답안 아님 · 학습용 예시 · 정본 답안 아님 · W24-F15
34줄 연결34줄 번역4 chunks
01

STEP 01 / 13

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

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

오늘의 한 문장

job fit·관심·자료·팀 기회·완주 위험을 40·20·15·15·10으로 비교하고 근거·합계·단일 선택을 사람 검토에 남긴다.

  1. weights=100은 어느 source와 실제 결과에서 확인해야 할까?
  2. 첫 실패를 만드는 조건과 fail-closed 지점은 어디일까?
  3. 왜 ‘실제 점수·URL·서명이 비어 있다’를 별도 경계로 남겨야 할까?
이 파일에서 끝까지 다시 쓰는 값weights=100securitiescardevidence URLsingle selection
왜 필요한가 — W24 D6 track selection — 가중치 100과 정확히 한 track히토리 → 니지카 → 료 → 키타
  1. 히토리

    weights=100가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 job fit·관심·자료·팀 기회·완주 위험을 40·20·15·15·10으로 비교하고 근거·합계·단일 선택을 사람 검토에 남긴다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘실제 점수·URL·서명이 비어 있다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 weights=100와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

02

STEP 02 / 13

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

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

새 기능을 멈춘 팀이 코드·test·문서·demo를 같은 release 후보에 묶어 하나씩 검수한다.

검수 도장이 붙은 공통 거래 코어 출고 상자

이 파일은 job fit·관심·자료·팀 기회·완주 위험을 40·20·15·15·10으로 비교하고 근거·합계·단일 선택을 사람 검토에 남긴다. 눈으로 읽을 때는 각 줄을 검수표 한 칸처럼 보고, 입력과 다음 상태를 놓치지 않는다.

마지막 도장은 source shape와 실제 runtime·사람 검토를 구분한 뒤에만 찍는다. 특히 실제 점수·URL·서명이 비어 있다

딱 여기까지만 비유는 실행 순서를 돕지만 실제 Gradle·Docker·DB·사람 review를 대신하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

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

값 1: weights=100

이 파일에서 계속 확인할 고정 단서가 weights=100다.

코드 연결
F15 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
실제 점수·URL·서명이 비어 있다

값 2: securities

이 파일에서 계속 확인할 고정 단서가 securities다.

코드 연결
F15 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
generic hash 검사는 선택 완료가 아니다

값 3: card

이 파일에서 계속 확인할 고정 단서가 card다.

코드 연결
F15 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
두 track 동시 선택을 허용하지 않는다

값 4: evidence URL

이 파일에서 계속 확인할 고정 단서가 evidence URL다.

코드 연결
F15 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
실제 점수·URL·서명이 비어 있다

값 5: single selection

이 파일에서 계속 확인할 고정 단서가 single selection다.

코드 연결
F15 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
generic hash 검사는 선택 완료가 아니다
04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

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

단어 몇 개만 뽑은 표가 아닙니다.학습용 예시 · PDF template/validator · 정본 답안 아님에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.34 / 34 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F15-L01 # W24 D6 track selection 학습 골격 출고표 1번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
이전 줄의 상태와 weights=100
결과·효과
관찰 상태 F15-001가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 점수·URL·서명이 비어 있다
3줄F15-L03 > PDF p810–811의 TEMPLATE와 generic validator를 한 파일에 모았다. 실제 점수·근거 URL·서명·최종 선택은 비어 있다. 출고표 3번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 weights=100
결과·효과
관찰 상태 F15-003가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 track 동시 선택을 허용하지 않는다
5줄F15-L05 ## Selection CSV template 출고표 5번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
이전 줄의 상태와 weights=100
결과·효과
관찰 상태 F15-005가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
generic hash 검사는 선택 완료가 아니다
7줄F15-L07 criterion,weight,securities,card,evidence 출고표 7번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 weights=100
결과·효과
관찰 상태 F15-007가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 점수·URL·서명이 비어 있다
8줄F15-L08 job_fit,40,,, 출고표 8번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
입력
40
결과·효과
관찰 상태 F15-008가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
generic hash 검사는 선택 완료가 아니다
9줄F15-L09 interest,20,,, 출고표 9번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
입력
20
결과·효과
관찰 상태 F15-009가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 track 동시 선택을 허용하지 않는다
10줄F15-L10 source_quality,15,,, 출고표 10번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
입력
15
결과·효과
관찰 상태 F15-010가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 점수·URL·서명이 비어 있다
11줄F15-L11 team_opportunity,15,,, 출고표 11번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
입력
15
결과·효과
관찰 상태 F15-011가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
generic hash 검사는 선택 완료가 아니다
12줄F15-L12 completion_risk,10,,, 출고표 12번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
입력
10
결과·효과
관찰 상태 F15-012가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 track 동시 선택을 허용하지 않는다
14줄F15-L14 ## 파일·hash 보조 검사 출고표 14번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
이전 줄의 상태와 weights=100
결과·효과
관찰 상태 F15-014가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
generic hash 검사는 선택 완료가 아니다
16줄F15-L16 $Artifact = Join-Path $LearnerRoot 'evidence\w24\track-selection.csv' 출고표 16번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Artifact, $LearnerRoot, 'evidence\w24\track-selection.csv'
결과·효과
관찰 상태 F15-016가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 점수·URL·서명이 비어 있다
17줄F15-L17 if (!(Test-Path -LiteralPath $Artifact -PathType Leaf)) { 출고표 17번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 필수 파일이나 경로가 실제로 있는지 확인한다.
입력
$Artifact
결과·효과
관찰 상태 F15-017가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
generic hash 검사는 선택 완료가 아니다
18줄F15-L18 throw "learner artifact missing: $Artifact" 출고표 18번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
"learner artifact missing: $Artifact"
결과·효과
관찰 상태 F15-018가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 track 동시 선택을 허용하지 않는다
19줄F15-L19 } 출고표 19번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 weights=100
결과·효과
관찰 상태 F15-019가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 점수·URL·서명이 비어 있다
20줄F15-L20 $Item = Get-Item -LiteralPath $Artifact 출고표 20번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Item, $Artifact
결과·효과
관찰 상태 F15-020가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
generic hash 검사는 선택 완료가 아니다
21줄F15-L21 if ($Item.Length -lt 40) { 출고표 21번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$Item, 40
결과·효과
관찰 상태 F15-021가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 track 동시 선택을 허용하지 않는다
22줄F15-L22 throw "artifact is too small to support the claim: bytes=$($Item.Length)" 출고표 22번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
$Item
결과·효과
관찰 상태 F15-022가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 점수·URL·서명이 비어 있다
23줄F15-L23 } 출고표 23번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 weights=100
결과·효과
관찰 상태 F15-023가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
generic hash 검사는 선택 완료가 아니다
24줄F15-L24 $Text = Get-Content -LiteralPath $Artifact -Raw 출고표 24번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$Text, $Artifact
결과·효과
관찰 상태 F15-024가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 track 동시 선택을 허용하지 않는다
25줄F15-L25 if ($Text -match '(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b') { 출고표 25번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
입력
$Text, '(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b'
결과·효과
관찰 상태 F15-025가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 점수·URL·서명이 비어 있다
26줄F15-L26 throw 'unresolved placeholder in learner artifact' 출고표 26번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
이전 줄의 상태와 weights=100
결과·효과
관찰 상태 F15-026가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
generic hash 검사는 선택 완료가 아니다
27줄F15-L27 } 출고표 27번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 weights=100
결과·효과
관찰 상태 F15-027가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 track 동시 선택을 허용하지 않는다
28줄F15-L28 $NonBlank = @($Text -split '[\r\n]+' | Where-Object { $_.Trim().Length -gt 0 }) 출고표 28번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건을 만족하는 row만 필터링한다.
입력
$NonBlank, $Text, '[\r\n]+'
결과·효과
관찰 상태 F15-028가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 점수·URL·서명이 비어 있다
29줄F15-L29 if ($NonBlank.Count -lt 3) { 출고표 29번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
$NonBlank, 3
결과·효과
관찰 상태 F15-029가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
generic hash 검사는 선택 완료가 아니다
30줄F15-L30 throw "artifact needs at least three nonblank evidence lines: $($NonBlank.Count)" 출고표 30번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
$NonBlank
결과·효과
관찰 상태 F15-030가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 track 동시 선택을 허용하지 않는다
31줄F15-L31 } 출고표 31번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 weights=100
결과·효과
관찰 상태 F15-031가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 점수·URL·서명이 비어 있다
32줄F15-L32 $Hash = (Get-FileHash -LiteralPath $Artifact -Algorithm SHA256).Hash.ToLowerInvariant() 출고표 32번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 현재 bytes를 64자리 digest로 evidence에 결박한다.
입력
$Hash, $Artifact
결과·효과
관찰 상태 F15-032가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
generic hash 검사는 선택 완료가 아니다
33줄F15-L33 "LOCAL_ARTIFACT_VALIDATED W24D6 bytes=$($Item.Length) sha256=$Hash" 출고표 33번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 파일 bytes·기본 형식·hash만 통과한 보조 marker를 낸다.
입력
$Item, $Hash
결과·효과
관찰 상태 F15-033가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 track 동시 선택을 허용하지 않는다
35줄F15-L35 ## 반드시 남는 사람 판정 출고표 35번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
입력
이전 줄의 상태와 weights=100
결과·효과
관찰 상태 F15-035가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
generic hash 검사는 선택 완료가 아니다
37줄F15-L37 - weight는 40+20+15+15+10=100이어야 한다. 출고표 37번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
입력
40, 20, 15
결과·효과
관찰 상태 F15-037가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 점수·URL·서명이 비어 있다
38줄F15-L38 - 각 점수의 실제 근거 URL과 확인일을 사람이 대조한다. 출고표 38번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 weights=100
결과·효과
관찰 상태 F15-038가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
generic hash 검사는 선택 완료가 아니다
39줄F15-L39 - 가중 합계와 사전 정의 tie-breaker를 다시 계산한다. 출고표 39번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 weights=100
결과·효과
관찰 상태 F15-039가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
두 track 동시 선택을 허용하지 않는다
40줄F15-L40 - 증권 또는 카드 정확히 하나만 선택하고 서명한다. 출고표 40번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
입력
이전 줄의 상태와 weights=100
결과·효과
관찰 상태 F15-040가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 점수·URL·서명이 비어 있다
41줄F15-L41 - LOCAL_ARTIFACT_VALIDATED 뒤에도 HUMAN_SEMANTIC_REVIEW_REQUIRED다. 출고표 41번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 파일 bytes·기본 형식·hash만 통과한 보조 marker를 낸다.
입력
이전 줄의 상태와 weights=100
결과·효과
관찰 상태 F15-041가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
generic hash 검사는 선택 완료가 아니다
05

STEP 05 / 13

원본 코드 조각

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

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

F15-C01 · 원문 1–12줄1–12줄
1–12줄 원본
# W24 D6 track selection 학습 골격

> PDF p810–811의 TEMPLATE와 generic validator를 한 파일에 모았다. 실제 점수·근거 URL·서명·최종 선택은 비어 있다.

## Selection CSV template

criterion,weight,securities,card,evidence
job_fit,40,,,
interest,20,,,
source_quality,15,,,
team_opportunity,15,,,
completion_risk,10,,,
F15-C02 · 원문 13–24줄13–24줄
13–24줄 원본

## 파일·hash 보조 검사

    $Artifact = Join-Path $LearnerRoot 'evidence\w24\track-selection.csv'
    if (!(Test-Path -LiteralPath $Artifact -PathType Leaf)) {
      throw "learner artifact missing: $Artifact"
    }
    $Item = Get-Item -LiteralPath $Artifact
    if ($Item.Length -lt 40) {
      throw "artifact is too small to support the claim: bytes=$($Item.Length)"
    }
    $Text = Get-Content -LiteralPath $Artifact -Raw
F15-C03 · 원문 25–36줄25–36줄
25–36줄 원본
    if ($Text -match '(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b') {
      throw 'unresolved placeholder in learner artifact'
    }
    $NonBlank = @($Text -split '[\r\n]+' | Where-Object { $_.Trim().Length -gt 0 })
    if ($NonBlank.Count -lt 3) {
      throw "artifact needs at least three nonblank evidence lines: $($NonBlank.Count)"
    }
    $Hash = (Get-FileHash -LiteralPath $Artifact -Algorithm SHA256).Hash.ToLowerInvariant()
    "LOCAL_ARTIFACT_VALIDATED W24D6 bytes=$($Item.Length) sha256=$Hash"

## 반드시 남는 사람 판정
F15-C04 · 원문 37–41줄37–41줄
37–41줄 원본
- weight는 40+20+15+15+10=100이어야 한다.
- 각 점수의 실제 근거 URL과 확인일을 사람이 대조한다.
- 가중 합계와 사전 정의 tie-breaker를 다시 계산한다.
- 증권 또는 카드 정확히 하나만 선택하고 서명한다.
- LOCAL_ARTIFACT_VALIDATED 뒤에도 HUMAN_SEMANTIC_REVIEW_REQUIRED다.
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

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

전체 번역 34 / 34

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

원본한국어 번역
1# W24 D6 track selection 학습 골격문서 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
3> PDF p810–811의 TEMPLATE와 generic validator를 한 파일에 모았다. 실제 점수·근거 URL·서명·최종 선택은 비어 있다.문서 의미: W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
5## Selection CSV template문서 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
7criterion,weight,securities,card,evidence문서 의미: W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
8job_fit,40,,,문서 의미: W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
9interest,20,,,문서 의미: W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
10source_quality,15,,,문서 의미: W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
11team_opportunity,15,,,문서 의미: W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
12completion_risk,10,,,문서 의미: W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
14## 파일·hash 보조 검사문서 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
16 $Artifact = Join-Path $LearnerRoot 'evidence\w24\track-selection.csv'문서 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
17 if (!(Test-Path -LiteralPath $Artifact -PathType Leaf)) {문서 의미: 필수 파일이나 경로가 실제로 있는지 확인한다.
18 throw "learner artifact missing: $Artifact"문서 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
19 }문서 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
20 $Item = Get-Item -LiteralPath $Artifact문서 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
21 if ($Item.Length -lt 40) {문서 의미: 조건·반복·함수의 실행 block을 연다.
22 throw "artifact is too small to support the claim: bytes=$($Item.Length)"문서 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
23 }문서 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
24 $Text = Get-Content -LiteralPath $Artifact -Raw문서 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
25 if ($Text -match '(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b') {문서 의미: Markdown 표 또는 PowerShell pipeline에서 값을 열이나 다음 명령으로 연결한다.
26 throw 'unresolved placeholder in learner artifact'문서 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
27 }문서 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
28 $NonBlank = @($Text -split '[\r\n]+' | Where-Object { $_.Trim().Length -gt 0 })문서 의미: 조건을 만족하는 row만 필터링한다.
29 if ($NonBlank.Count -lt 3) {문서 의미: 조건·반복·함수의 실행 block을 연다.
30 throw "artifact needs at least three nonblank evidence lines: $($NonBlank.Count)"문서 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
31 }문서 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
32 $Hash = (Get-FileHash -LiteralPath $Artifact -Algorithm SHA256).Hash.ToLowerInvariant()문서 의미: 현재 bytes를 64자리 digest로 evidence에 결박한다.
33 "LOCAL_ARTIFACT_VALIDATED W24D6 bytes=$($Item.Length) sha256=$Hash"문서 의미: 파일 bytes·기본 형식·hash만 통과한 보조 marker를 낸다.
35## 반드시 남는 사람 판정문서 의미: 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다.
37- weight는 40+20+15+15+10=100이어야 한다.문서 의미: W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
38- 각 점수의 실제 근거 URL과 확인일을 사람이 대조한다.문서 의미: W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
39- 가중 합계와 사전 정의 tie-breaker를 다시 계산한다.문서 의미: W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
40- 증권 또는 카드 정확히 하나만 선택하고 서명한다.문서 의미: W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다.
41- LOCAL_ARTIFACT_VALIDATED 뒤에도 HUMAN_SEMANTIC_REVIEW_REQUIRED다.문서 의미: 파일 bytes·기본 형식·hash만 통과한 보조 marker를 낸다.
07

STEP 07 / 13

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

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

한 줄로 읽기

W24 D6 track selection — 가중치 100과 정확히 한 track는 job fit·관심·자료·팀 기회·완주 위험을 40·20·15·15·10으로 비교하고 근거·합계·단일 선택을 사람 검토에 남긴다.

문법 해부

  • .md 문법에서 선언·조건·pipeline·block 경계를 먼저 나눈다.
  • expected 값과 actual 결과를 같은 이름처럼 보여도 서로 다른 source로 읽는다.
  • native exit·row count·hash·사람 판정을 서로 대체하지 않는다.

실행 순서

  1. 입력 경로·fixture·환경변수·expected 계약을 고정한다.
  2. source가 실행하는 native process·HTTP·SQL 또는 형식 검사를 따라간다.
  3. actual 값과 exact marker를 대조하고 실패면 성공 발행 전에 중단한다.
  4. finally cleanup과 비범위를 evidence에 남긴다.

W24 조각별 정밀 해설

F15-C01 · 원문 1–12줄
문법 해부
.md 문법으로 1–12줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
weights=100, securities, card를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
실제 점수·URL·서명이 비어 있다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
실제 점수·URL·서명이 비어 있다; generic hash 검사는 선택 완료가 아니다; 두 track 동시 선택을 허용하지 않는다
다음 연결
다음 조각 또는 F15 evidence 판정으로 상태를 넘긴다.
F15-C02 · 원문 13–24줄
문법 해부
.md 문법으로 13–24줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
weights=100, securities, card를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
실제 점수·URL·서명이 비어 있다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
실제 점수·URL·서명이 비어 있다; generic hash 검사는 선택 완료가 아니다; 두 track 동시 선택을 허용하지 않는다
다음 연결
다음 조각 또는 F15 evidence 판정으로 상태를 넘긴다.
F15-C03 · 원문 25–36줄
문법 해부
.md 문법으로 25–36줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
weights=100, securities, card를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
실제 점수·URL·서명이 비어 있다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
실제 점수·URL·서명이 비어 있다; generic hash 검사는 선택 완료가 아니다; 두 track 동시 선택을 허용하지 않는다
다음 연결
다음 조각 또는 F15 evidence 판정으로 상태를 넘긴다.
F15-C04 · 원문 37–41줄
문법 해부
.md 문법으로 37–41줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
weights=100, securities, card를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
실제 점수·URL·서명이 비어 있다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
실제 점수·URL·서명이 비어 있다; generic hash 검사는 선택 완료가 아니다; 두 track 동시 선택을 허용하지 않는다
다음 연결
다음 조각 또는 F15 evidence 판정으로 상태를 넘긴다.
실행 순서 — W24 D6 track selection — 가중치 100과 정확히 한 track히토리 → 니지카 → 료 → 키타
  1. 히토리

    securities가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 job fit·관심·자료·팀 기회·완주 위험을 40·20·15·15·10으로 비교하고 근거·합계·단일 선택을 사람 검토에 남긴다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘generic hash 검사는 선택 완료가 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 securities와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

08

STEP 08 / 13

실제 값 따라가기

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

순서들어온 값코드가 하는 일나온 값·상태경계
입력weights=100source 계약에 대입F15 실행/설명 시작 상태실제 점수·URL·서명이 비어 있다
검증securitiesexpected와 actual 또는 형식 대조통과 또는 첫 mismatchgeneric hash 검사는 선택 완료가 아니다
증거single selectionmarker·hash·row를 같은 run에 연결범위가 적힌 evidence 후보두 track 동시 선택을 허용하지 않는다
실제 값 — W24 D6 track selection — 가중치 100과 정확히 한 track히토리 → 니지카 → 료 → 키타
  1. 히토리

    card가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 job fit·관심·자료·팀 기회·완주 위험을 40·20·15·15·10으로 비교하고 근거·합계·단일 선택을 사람 검토에 남긴다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘두 track 동시 선택을 허용하지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 card와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

09

STEP 09 / 13

Gradle·PowerShell·HTTP·PostgreSQL 내부에서 벌어지는 일

Gradle·JUnit XML·PowerShell·HTTP·PostgreSQL·Docker에서 실제로 일어나는 일과 증명 범위를 구분합니다.

source/contract

W24-D6-track-selection.md bytes와 expected 값을 읽는다.

파일 존재만으로 runtime 성공은 아니다.
execution/evidence

native exit·HTTP status·JUnit XML·DB row·hash 중 이 파일이 소유한 값을 만든다.

실제 점수·URL·서명이 비어 있다
release/human

관련 evidence와 사람 의미 검토를 release 후보에 연결한다.

두 track 동시 선택을 허용하지 않는다
첫 실패 경계 — W24 D6 track selection — 가중치 100과 정확히 한 track히토리 → 니지카 → 료 → 키타
  1. 히토리

    evidence URL가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 job fit·관심·자료·팀 기회·완주 위험을 40·20·15·15·10으로 비교하고 근거·합계·단일 선택을 사람 검토에 남긴다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘실제 점수·URL·서명이 비어 있다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 evidence URL와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

10

STEP 10 / 13

흔한 착각과 틀린 예

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

❌ weights=100 문자열이 source에 있으니 실제 실행도 Green이다.

왜 틀리나 source literal과 runtime 관찰값은 다른 증거다.

바르게 읽기 native exit·actual XML/HTTP/DB evidence를 별도로 확인한다.

반례 script가 실행 전 경로 오류로 멈춰도 literal은 그대로 남는다.

❌ 파일 SHA-256이 있으면 내용의 의미와 사실성도 검증됐다.

왜 틀리나 hash는 동일 bytes만 말한다.

바르게 읽기 schema·수치·질문·근거는 별도 자동 또는 사람 판정을 거친다.

반례 빈 review 질문을 가진 CSV도 안정된 hash를 가진다.

❌ LOCAL_ARTIFACT_VALIDATED는 release Green과 같다.

왜 틀리나 generic validator는 파일 shape만 확인한다.

바르게 읽기 HUMAN_SEMANTIC_REVIEW_REQUIRED를 유지한다.

반례 잘못된 track 점수표도 byte 수 조건은 통과할 수 있다.

❌ 이 파일이 W24 전체 lifecycle을 모두 소유한다.

왜 틀리나 각 source는 Gate·demo·cleanup·사람 review 중 일부만 담당한다.

바르게 읽기 owner와 non-responsibility를 release manifest에서 분리한다.

반례 D4 source audit에는 runtime_claim=false가 명시된다.

❌ 이전 주 Green이나 오래된 log를 현재 commit 결과로 재사용한다.

왜 틀리나 source·commit·actual result가 같은 실행에 묶이지 않는다.

바르게 읽기 release 후보에서 새 evidence와 hash를 만든다.

반례 expected JSON이 바뀌면 예전 XML은 exact inventory를 증명하지 못한다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

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

증명 범위

실제 점수·URL·서명이 비어 있다

이 책임을 맡는 곳: runtime Gate
증명 범위

generic hash 검사는 선택 완료가 아니다

이 책임을 맡는 곳: external/human review
증명 범위

두 track 동시 선택을 허용하지 않는다

이 책임을 맡는 곳: release manifest
증명 범위

실제 점수·URL·서명이 비어 있다

이 책임을 맡는 곳: 운영 환경
증명하지 않는 범위 — W24 D6 track selection — 가중치 100과 정확히 한 track히토리 → 니지카 → 료 → 키타
  1. 히토리

    single selection가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 job fit·관심·자료·팀 기회·완주 위험을 40·20·15·15·10으로 비교하고 근거·합계·단일 선택을 사람 검토에 남긴다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘generic hash 검사는 선택 완료가 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 single selection와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

12

STEP 12 / 13

직접 다시 써보기

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

1단계 · 뜻부터 복원

  • job fit·관심·자료·팀 기회·완주 위험을 40·20·15·15·10으로 비교하고 근거·합계·단일 선택을 사람 검토에 남긴다.
  • 핵심 값은 weights=100, securities, card, evidence URL, single selection다.

2단계 · 코드 조각 재조립

  1. 1. 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다
  2. 3. W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다
  3. 5. 이 줄은 실행 코드가 아니라 가정·출처·한계를 밝히는 주석이다
  4. 7. W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다
  5. 8. W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다
  6. 9. W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다
  7. 10. W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다
  8. 11. W24-D6-track-selection.md의 다음 검증 또는 설명 단계를 구성한다

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

illustrative/markdown/W24-D6-track-selection.md을 새 파일에 다시 쓰고 expected·actual·실패·cleanup·비범위를 주석으로 표시한다.

자가 점검
  • 비어 있지 않은 모든 source 줄을 한 번씩 읽었나?
  • source shape와 runtime Green을 분리했나?
  • 사람 검토·외부 상태를 자동 성공으로 꾸미지 않았나?
  • 첫 실패와 cleanup 책임을 설명할 수 있나?
13

STEP 13 / 13

전체 원본 source

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

학습용 예시 전체 확인하기 · 정본 답안 아님
학습용 예시 · PDF template/validator · 정본 답안 아님illustrative/markdown/W24-D6-track-selection.mdSHA-256 07c42803558975425a81307c5e2d6242fa20988767b9d011bd5113c6ad3b221d
W24 D6 track selection — 가중치 100과 정확히 한 track 전체
# W24 D6 track selection 학습 골격

> PDF p810–811의 TEMPLATE와 generic validator를 한 파일에 모았다. 실제 점수·근거 URL·서명·최종 선택은 비어 있다.

## Selection CSV template

criterion,weight,securities,card,evidence
job_fit,40,,,
interest,20,,,
source_quality,15,,,
team_opportunity,15,,,
completion_risk,10,,,

## 파일·hash 보조 검사

    $Artifact = Join-Path $LearnerRoot 'evidence\w24\track-selection.csv'
    if (!(Test-Path -LiteralPath $Artifact -PathType Leaf)) {
      throw "learner artifact missing: $Artifact"
    }
    $Item = Get-Item -LiteralPath $Artifact
    if ($Item.Length -lt 40) {
      throw "artifact is too small to support the claim: bytes=$($Item.Length)"
    }
    $Text = Get-Content -LiteralPath $Artifact -Raw
    if ($Text -match '(?i)\b(TODO|TBD|FILL_ME|PLACEHOLDER)\b') {
      throw 'unresolved placeholder in learner artifact'
    }
    $NonBlank = @($Text -split '[\r\n]+' | Where-Object { $_.Trim().Length -gt 0 })
    if ($NonBlank.Count -lt 3) {
      throw "artifact needs at least three nonblank evidence lines: $($NonBlank.Count)"
    }
    $Hash = (Get-FileHash -LiteralPath $Artifact -Algorithm SHA256).Hash.ToLowerInvariant()
    "LOCAL_ARTIFACT_VALIDATED W24D6 bytes=$($Item.Length) sha256=$Hash"

## 반드시 남는 사람 판정

- weight는 40+20+15+15+10=100이어야 한다.
- 각 점수의 실제 근거 URL과 확인일을 사람이 대조한다.
- 가중 합계와 사전 정의 tie-breaker를 다시 계산한다.
- 증권 또는 카드 정확히 하나만 선택하고 서명한다.
- LOCAL_ARTIFACT_VALIDATED 뒤에도 HUMAN_SEMANTIC_REVIEW_REQUIRED다.
16

run-w24-release.ps1 — exact Gate와 lifecycle을 묶는 release owner

scripts/run-w24-release.ps1

PDF 전문 정본 · packaged PowerShell source · 정본 · W24-F16
15줄 연결15줄 번역2 chunks
01

STEP 01 / 13

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

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

오늘의 한 문장

clean test와 coreV1Gate actual XML 37/66을 다시 계산한 뒤 lifecycle runner를 호출하고 release marker를 발행한다.

  1. classes=37은 어느 source와 실제 결과에서 확인해야 할까?
  2. 첫 실패를 만드는 조건과 fail-closed 지점은 어디일까?
  3. 왜 ‘tag 생성 자체는 이 script에 없다’를 별도 경계로 남겨야 할까?
이 파일에서 끝까지 다시 쓰는 값classes=37selectors=43tests=66core_gate=GREENdemo=GREENcleanup=1
왜 필요한가 — run-w24-release.ps1 — exact Gate와 lifecycle을 묶는 release owner히토리 → 니지카 → 료 → 키타
  1. 히토리

    classes=37가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 clean test와 coreV1Gate actual XML 37/66을 다시 계산한 뒤 lifecycle runner를 호출하고 release marker를 발행한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘tag 생성 자체는 이 script에 없다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 classes=37와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

02

STEP 02 / 13

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

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

새 기능을 멈춘 팀이 코드·test·문서·demo를 같은 release 후보에 묶어 하나씩 검수한다.

검수 도장이 붙은 공통 거래 코어 출고 상자

이 파일은 clean test와 coreV1Gate actual XML 37/66을 다시 계산한 뒤 lifecycle runner를 호출하고 release marker를 발행한다. 눈으로 읽을 때는 각 줄을 검수표 한 칸처럼 보고, 입력과 다음 상태를 놓치지 않는다.

마지막 도장은 source shape와 실제 runtime·사람 검토를 구분한 뒤에만 찍는다. 특히 tag 생성 자체는 이 script에 없다

딱 여기까지만 비유는 실행 순서를 돕지만 실제 Gradle·Docker·DB·사람 review를 대신하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

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

값 1: classes=37

이 파일에서 계속 확인할 고정 단서가 classes=37다.

코드 연결
F16 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
tag 생성 자체는 이 script에 없다

값 2: selectors=43

이 파일에서 계속 확인할 고정 단서가 selectors=43다.

코드 연결
F16 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
Git clean·track 한 개는 별도 사람 Gate다

값 3: tests=66

이 파일에서 계속 확인할 고정 단서가 tests=66다.

코드 연결
F16 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
실행하지 않은 HTML에서 Green을 주장하지 않는다

값 4: core_gate=GREEN

이 파일에서 계속 확인할 고정 단서가 core_gate=GREEN다.

코드 연결
F16 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
tag 생성 자체는 이 script에 없다

값 5: demo=GREEN

이 파일에서 계속 확인할 고정 단서가 demo=GREEN다.

코드 연결
F16 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
Git clean·track 한 개는 별도 사람 Gate다
04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

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

단어 몇 개만 뽑은 표가 아닙니다.PDF 전문 정본 · packaged PowerShell source에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.15 / 15 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F16-L01 param([Parameter(Mandatory=$true)][string]$ProjectRoot,[Parameter(Mandatory=$true)][string]$EvidenceDir,[string]$ComposeProject='w24-learner-release',[int]$Port=28080,[int]$DbPort=62440) 출고표 1번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 PowerShell script가 받을 입력 계약을 연다.
입력
$true, $ProjectRoot, $true
결과·효과
관찰 상태 F16-001가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
tag 생성 자체는 이 script에 없다
2줄F16-L02 $ErrorActionPreference='Stop';$learner=(Resolve-Path -LiteralPath $ProjectRoot).Path;$e=[IO.Path]::GetFullPath($EvidenceDir);New-Item -ItemType Directory -Force $e|Out-Null 출고표 2번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다.
입력
$ErrorActionPreference, 'Stop', $learner
결과·효과
관찰 상태 F16-002가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
Git clean·track 한 개는 별도 사람 Gate다
3줄F16-L03 Push-Location $learner 출고표 3번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 run-w24-release.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$learner
결과·효과
관찰 상태 F16-003가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실행하지 않은 HTML에서 Green을 주장하지 않는다
4줄F16-L04 try{ 출고표 4번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
이전 줄의 상태와 classes=37
결과·효과
관찰 상태 F16-004가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
tag 생성 자체는 이 script에 없다
5줄F16-L05 & .\gradlew.bat clean test coreV1Gate --no-daemon 출고표 5번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 learner project의 Gradle wrapper로 지정 task를 실행한다.
입력
이전 줄의 상태와 classes=37
결과·효과
관찰 상태 F16-005가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
Git clean·track 한 개는 별도 사람 Gate다
6줄F16-L06 if($LASTEXITCODE-ne 0){throw "W24 coreV1Gate exit=$LASTEXITCODE"} 출고표 6번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 native process 종료 코드를 검사해 실패를 놓치지 않는다.
입력
$LASTEXITCODE, 0, "W24 coreV1Gate exit=$LASTEXITCODE"
결과·효과
관찰 상태 F16-006가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실행하지 않은 HTML에서 Green을 주장하지 않는다
7줄F16-L07 $contract=Get-Content -Raw -LiteralPath (Join-Path (Split-Path -Parent $PSScriptRoot) 'learning_stages/w24/overlay/core-v1-expected.json')|ConvertFrom-Json;$expected=@($contract.classes.psobject.Properties.Name) 출고표 7번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 class 이름과 기대 test 수를 exact inventory로 고정한다.
입력
$contract, $PSScriptRoot, $expected
결과·효과
관찰 상태 F16-007가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
tag 생성 자체는 이 script에 없다
8줄F16-L08 $rows=@(Get-ChildItem build/test-results/coreV1Gate -Filter 'TEST-*.xml'|ForEach-Object{[xml]$x=Get-Content -Raw $_.FullName;[pscustomobject]@{class=[string]$x.testsuite.name;tests=[int]$x.testsuite.tests;failures=[int]$x.testsuite.failures;errors=[int]$x.testsuite.errors;skipped=[int]$x.testsuite.skipped}}) 출고표 8번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 JUnit XML 결과 파일만 exact inventory 입력으로 모은다.
입력
$rows, 'TEST-*.xml', $x
결과·효과
관찰 상태 F16-008가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
Git clean·track 한 개는 별도 사람 Gate다
9줄F16-L09 $actual=@($rows.class|Sort-Object -Unique);if(Compare-Object ($expected|Sort-Object) $actual){throw "W24 exact class inventory mismatch expected=$expected actual=$actual"} 출고표 9번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 expected와 actual 집합에 누락·예상 밖 항목이 있는지 비교한다.
입력
$actual, $rows, $expected
결과·효과
관찰 상태 F16-009가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실행하지 않은 HTML에서 Green을 주장하지 않는다
10줄F16-L10 if($rows.Count-ne 37-or@($rows|Where-Object{$_.tests-ne[int]$contract.classes.psobject.Properties[$_.class].Value-or$_.failures-ne 0-or$_.errors-ne 0-or$_.skipped-ne 0}).Count-ne 0){throw "W24 per-suite XML exact mismatch classes=$($rows.Count)"};$total=($rows|Measure-Object tests -Sum).Sum;if($total-ne 66){throw "W24 exact test total mismatch=$total"} 출고표 10번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 class 이름과 기대 test 수를 exact inventory로 고정한다.
입력
$rows, 37, $rows
결과·효과
관찰 상태 F16-010가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
tag 생성 자체는 이 script에 없다
11줄F16-L11 $rows|ConvertTo-Json|Set-Content -Encoding utf8 (Join-Path $e 'core-v1-gate.json') 출고표 11번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 검증된 object를 JSON evidence text로 직렬화한다.
입력
$rows, $e, 'core-v1-gate.json'
결과·효과
관찰 상태 F16-011가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
Git clean·track 한 개는 별도 사람 Gate다
12줄F16-L12 }finally{Pop-Location} 출고표 12번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 중간 실패가 있어도 반드시 실행할 cleanup 경계를 연다.
입력
이전 줄의 상태와 classes=37
결과·효과
관찰 상태 F16-012가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실행하지 않은 HTML에서 Green을 주장하지 않는다
13줄F16-L13 & powershell.exe -NoProfile -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot 'run-w24-lifecycle.ps1') -ProjectRoot $learner -EvidenceDir $e -ComposeProject $ComposeProject -Port $Port -DbPort $DbPort 출고표 13번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 run-w24-release.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$PSScriptRoot, 'run-w24-lifecycle.ps1', $learner
결과·효과
관찰 상태 F16-013가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
tag 생성 자체는 이 script에 없다
14줄F16-L14 if($LASTEXITCODE-ne 0){throw "W24 lifecycle exit=$LASTEXITCODE"} 출고표 14번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 native process 종료 코드를 검사해 실패를 놓치지 않는다.
입력
$LASTEXITCODE, 0, "W24 lifecycle exit=$LASTEXITCODE"
결과·효과
관찰 상태 F16-014가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
Git clean·track 한 개는 별도 사람 Gate다
15줄F16-L15 "W24_RELEASE_GREEN classes=37 selectors=43 tests=66 core_gate=GREEN demo=GREEN cleanup=1 native_exit=0" 출고표 15번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 selector 총수를 JSON 계약에 고정한다.
입력
37, 43, 66
결과·효과
관찰 상태 F16-015가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실행하지 않은 HTML에서 Green을 주장하지 않는다
05

STEP 05 / 13

원본 코드 조각

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

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

F16-C01 · 원문 1–12줄1–12줄
1–12줄 원본
param([Parameter(Mandatory=$true)][string]$ProjectRoot,[Parameter(Mandatory=$true)][string]$EvidenceDir,[string]$ComposeProject='w24-learner-release',[int]$Port=28080,[int]$DbPort=62440)
$ErrorActionPreference='Stop';$learner=(Resolve-Path -LiteralPath $ProjectRoot).Path;$e=[IO.Path]::GetFullPath($EvidenceDir);New-Item -ItemType Directory -Force $e|Out-Null
Push-Location $learner
try{
 & .\gradlew.bat clean test coreV1Gate --no-daemon
 if($LASTEXITCODE-ne 0){throw "W24 coreV1Gate exit=$LASTEXITCODE"}
 $contract=Get-Content -Raw -LiteralPath (Join-Path (Split-Path -Parent $PSScriptRoot) 'learning_stages/w24/overlay/core-v1-expected.json')|ConvertFrom-Json;$expected=@($contract.classes.psobject.Properties.Name)
 $rows=@(Get-ChildItem build/test-results/coreV1Gate -Filter 'TEST-*.xml'|ForEach-Object{[xml]$x=Get-Content -Raw $_.FullName;[pscustomobject]@{class=[string]$x.testsuite.name;tests=[int]$x.testsuite.tests;failures=[int]$x.testsuite.failures;errors=[int]$x.testsuite.errors;skipped=[int]$x.testsuite.skipped}})
 $actual=@($rows.class|Sort-Object -Unique);if(Compare-Object ($expected|Sort-Object) $actual){throw "W24 exact class inventory mismatch expected=$expected actual=$actual"}
 if($rows.Count-ne 37-or@($rows|Where-Object{$_.tests-ne[int]$contract.classes.psobject.Properties[$_.class].Value-or$_.failures-ne 0-or$_.errors-ne 0-or$_.skipped-ne 0}).Count-ne 0){throw "W24 per-suite XML exact mismatch classes=$($rows.Count)"};$total=($rows|Measure-Object tests -Sum).Sum;if($total-ne 66){throw "W24 exact test total mismatch=$total"}
 $rows|ConvertTo-Json|Set-Content -Encoding utf8 (Join-Path $e 'core-v1-gate.json')
}finally{Pop-Location}
F16-C02 · 원문 13–15줄13–15줄
13–15줄 원본
& powershell.exe -NoProfile -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot 'run-w24-lifecycle.ps1') -ProjectRoot $learner -EvidenceDir $e -ComposeProject $ComposeProject -Port $Port -DbPort $DbPort
if($LASTEXITCODE-ne 0){throw "W24 lifecycle exit=$LASTEXITCODE"}
"W24_RELEASE_GREEN classes=37 selectors=43 tests=66 core_gate=GREEN demo=GREEN cleanup=1 native_exit=0"
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

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

전체 번역 15 / 15

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

원본한국어 번역
1param([Parameter(Mandatory=$true)][string]$ProjectRoot,[Parameter(Mandatory=$true)][string]$EvidenceDir,[string]$ComposeProject='w24-learner-release',[int]$Port=28080,[int]$DbPort=62440)실행 의미: PowerShell script가 받을 입력 계약을 연다.
2$ErrorActionPreference='Stop';$learner=(Resolve-Path -LiteralPath $ProjectRoot).Path;$e=[IO.Path]::GetFullPath($EvidenceDir);New-Item -ItemType Directory -Force $e|Out-Null실행 의미: PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다.
3Push-Location $learner실행 의미: run-w24-release.ps1의 다음 검증 또는 설명 단계를 구성한다.
4try{실행 의미: 조건·반복·함수의 실행 block을 연다.
5 & .\gradlew.bat clean test coreV1Gate --no-daemon실행 의미: learner project의 Gradle wrapper로 지정 task를 실행한다.
6 if($LASTEXITCODE-ne 0){throw "W24 coreV1Gate exit=$LASTEXITCODE"}실행 의미: native process 종료 코드를 검사해 실패를 놓치지 않는다.
7 $contract=Get-Content -Raw -LiteralPath (Join-Path (Split-Path -Parent $PSScriptRoot) 'learning_stages/w24/overlay/core-v1-expected.json')|ConvertFrom-Json;$expected=@($contract.classes.psobject.Properties.Name)실행 의미: class 이름과 기대 test 수를 exact inventory로 고정한다.
8 $rows=@(Get-ChildItem build/test-results/coreV1Gate -Filter 'TEST-*.xml'|ForEach-Object{[xml]$x=Get-Content -Raw $_.FullName;[pscustomobject]@{class=[string]$x.testsuite.name;tests=[int]$x.testsuite.tests;failures=[int]$x.testsuite.failures;errors=[int]$x.testsuite.errors;skipped=[int]$x.testsuite.skipped}})실행 의미: JUnit XML 결과 파일만 exact inventory 입력으로 모은다.
9 $actual=@($rows.class|Sort-Object -Unique);if(Compare-Object ($expected|Sort-Object) $actual){throw "W24 exact class inventory mismatch expected=$expected actual=$actual"}실행 의미: expected와 actual 집합에 누락·예상 밖 항목이 있는지 비교한다.
10 if($rows.Count-ne 37-or@($rows|Where-Object{$_.tests-ne[int]$contract.classes.psobject.Properties[$_.class].Value-or$_.failures-ne 0-or$_.errors-ne 0-or$_.skipped-ne 0}).Count-ne 0){throw "W24 per-suite XML exact mismatch classes=$($rows.Count)"};$total=($rows|Measure-Object tests -Sum).Sum;if($total-ne 66){throw "W24 exact test total mismatch=$total"}실행 의미: class 이름과 기대 test 수를 exact inventory로 고정한다.
11 $rows|ConvertTo-Json|Set-Content -Encoding utf8 (Join-Path $e 'core-v1-gate.json')실행 의미: 검증된 object를 JSON evidence text로 직렬화한다.
12}finally{Pop-Location}실행 의미: 중간 실패가 있어도 반드시 실행할 cleanup 경계를 연다.
13& powershell.exe -NoProfile -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot 'run-w24-lifecycle.ps1') -ProjectRoot $learner -EvidenceDir $e -ComposeProject $ComposeProject -Port $Port -DbPort $DbPort실행 의미: run-w24-release.ps1의 다음 검증 또는 설명 단계를 구성한다.
14if($LASTEXITCODE-ne 0){throw "W24 lifecycle exit=$LASTEXITCODE"}실행 의미: native process 종료 코드를 검사해 실패를 놓치지 않는다.
15"W24_RELEASE_GREEN classes=37 selectors=43 tests=66 core_gate=GREEN demo=GREEN cleanup=1 native_exit=0"실행 의미: selector 총수를 JSON 계약에 고정한다.
07

STEP 07 / 13

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

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

한 줄로 읽기

run-w24-release.ps1 — exact Gate와 lifecycle을 묶는 release owner는 clean test와 coreV1Gate actual XML 37/66을 다시 계산한 뒤 lifecycle runner를 호출하고 release marker를 발행한다.

문법 해부

  • .ps1 문법에서 선언·조건·pipeline·block 경계를 먼저 나눈다.
  • expected 값과 actual 결과를 같은 이름처럼 보여도 서로 다른 source로 읽는다.
  • native exit·row count·hash·사람 판정을 서로 대체하지 않는다.

실행 순서

  1. 입력 경로·fixture·환경변수·expected 계약을 고정한다.
  2. source가 실행하는 native process·HTTP·SQL 또는 형식 검사를 따라간다.
  3. actual 값과 exact marker를 대조하고 실패면 성공 발행 전에 중단한다.
  4. finally cleanup과 비범위를 evidence에 남긴다.

W24 조각별 정밀 해설

F16-C01 · 원문 1–12줄
문법 해부
.ps1 문법으로 1–12줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
classes=37, selectors=43, tests=66를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
tag 생성 자체는 이 script에 없다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
tag 생성 자체는 이 script에 없다; Git clean·track 한 개는 별도 사람 Gate다; 실행하지 않은 HTML에서 Green을 주장하지 않는다
다음 연결
다음 조각 또는 F16 evidence 판정으로 상태를 넘긴다.
F16-C02 · 원문 13–15줄
문법 해부
.ps1 문법으로 13–15줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
classes=37, selectors=43, tests=66를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
tag 생성 자체는 이 script에 없다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
tag 생성 자체는 이 script에 없다; Git clean·track 한 개는 별도 사람 Gate다; 실행하지 않은 HTML에서 Green을 주장하지 않는다
다음 연결
다음 조각 또는 F16 evidence 판정으로 상태를 넘긴다.
실행 순서 — run-w24-release.ps1 — exact Gate와 lifecycle을 묶는 release owner히토리 → 니지카 → 료 → 키타
  1. 히토리

    selectors=43가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 clean test와 coreV1Gate actual XML 37/66을 다시 계산한 뒤 lifecycle runner를 호출하고 release marker를 발행한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘Git clean·track 한 개는 별도 사람 Gate다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 selectors=43와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

08

STEP 08 / 13

실제 값 따라가기

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

순서들어온 값코드가 하는 일나온 값·상태경계
입력classes=37source 계약에 대입F16 실행/설명 시작 상태tag 생성 자체는 이 script에 없다
검증selectors=43expected와 actual 또는 형식 대조통과 또는 첫 mismatchGit clean·track 한 개는 별도 사람 Gate다
증거cleanup=1marker·hash·row를 같은 run에 연결범위가 적힌 evidence 후보실행하지 않은 HTML에서 Green을 주장하지 않는다
실제 값 — run-w24-release.ps1 — exact Gate와 lifecycle을 묶는 release owner히토리 → 니지카 → 료 → 키타
  1. 히토리

    tests=66가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 clean test와 coreV1Gate actual XML 37/66을 다시 계산한 뒤 lifecycle runner를 호출하고 release marker를 발행한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘실행하지 않은 HTML에서 Green을 주장하지 않는다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 tests=66와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

09

STEP 09 / 13

Gradle·PowerShell·HTTP·PostgreSQL 내부에서 벌어지는 일

Gradle·JUnit XML·PowerShell·HTTP·PostgreSQL·Docker에서 실제로 일어나는 일과 증명 범위를 구분합니다.

source/contract

run-w24-release.ps1 bytes와 expected 값을 읽는다.

파일 존재만으로 runtime 성공은 아니다.
execution/evidence

native exit·HTTP status·JUnit XML·DB row·hash 중 이 파일이 소유한 값을 만든다.

tag 생성 자체는 이 script에 없다
release/human

관련 evidence와 사람 의미 검토를 release 후보에 연결한다.

실행하지 않은 HTML에서 Green을 주장하지 않는다
첫 실패 경계 — run-w24-release.ps1 — exact Gate와 lifecycle을 묶는 release owner히토리 → 니지카 → 료 → 키타
  1. 히토리

    core_gate=GREEN가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 clean test와 coreV1Gate actual XML 37/66을 다시 계산한 뒤 lifecycle runner를 호출하고 release marker를 발행한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘tag 생성 자체는 이 script에 없다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 core_gate=GREEN와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

10

STEP 10 / 13

흔한 착각과 틀린 예

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

❌ classes=37 문자열이 source에 있으니 실제 실행도 Green이다.

왜 틀리나 source literal과 runtime 관찰값은 다른 증거다.

바르게 읽기 native exit·actual XML/HTTP/DB evidence를 별도로 확인한다.

반례 script가 실행 전 경로 오류로 멈춰도 literal은 그대로 남는다.

❌ 파일 SHA-256이 있으면 내용의 의미와 사실성도 검증됐다.

왜 틀리나 hash는 동일 bytes만 말한다.

바르게 읽기 schema·수치·질문·근거는 별도 자동 또는 사람 판정을 거친다.

반례 빈 review 질문을 가진 CSV도 안정된 hash를 가진다.

❌ LOCAL_ARTIFACT_VALIDATED는 release Green과 같다.

왜 틀리나 generic validator는 파일 shape만 확인한다.

바르게 읽기 HUMAN_SEMANTIC_REVIEW_REQUIRED를 유지한다.

반례 잘못된 track 점수표도 byte 수 조건은 통과할 수 있다.

❌ 이 파일이 W24 전체 lifecycle을 모두 소유한다.

왜 틀리나 각 source는 Gate·demo·cleanup·사람 review 중 일부만 담당한다.

바르게 읽기 owner와 non-responsibility를 release manifest에서 분리한다.

반례 D4 source audit에는 runtime_claim=false가 명시된다.

❌ 이전 주 Green이나 오래된 log를 현재 commit 결과로 재사용한다.

왜 틀리나 source·commit·actual result가 같은 실행에 묶이지 않는다.

바르게 읽기 release 후보에서 새 evidence와 hash를 만든다.

반례 expected JSON이 바뀌면 예전 XML은 exact inventory를 증명하지 못한다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

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

증명 범위

tag 생성 자체는 이 script에 없다

이 책임을 맡는 곳: runtime Gate
증명 범위

Git clean·track 한 개는 별도 사람 Gate다

이 책임을 맡는 곳: external/human review
증명 범위

실행하지 않은 HTML에서 Green을 주장하지 않는다

이 책임을 맡는 곳: release manifest
증명 범위

tag 생성 자체는 이 script에 없다

이 책임을 맡는 곳: 운영 환경
증명하지 않는 범위 — run-w24-release.ps1 — exact Gate와 lifecycle을 묶는 release owner히토리 → 니지카 → 료 → 키타
  1. 히토리

    demo=GREEN가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 clean test와 coreV1Gate actual XML 37/66을 다시 계산한 뒤 lifecycle runner를 호출하고 release marker를 발행한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘Git clean·track 한 개는 별도 사람 Gate다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 demo=GREEN와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

12

STEP 12 / 13

직접 다시 써보기

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

1단계 · 뜻부터 복원

  • clean test와 coreV1Gate actual XML 37/66을 다시 계산한 뒤 lifecycle runner를 호출하고 release marker를 발행한다.
  • 핵심 값은 classes=37, selectors=43, tests=66, core_gate=GREEN, demo=GREEN, cleanup=1다.

2단계 · 코드 조각 재조립

  1. 1. PowerShell script가 받을 입력 계약을 연다
  2. 2. PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다
  3. 3. run-w24-release.ps1의 다음 검증 또는 설명 단계를 구성한다
  4. 4. 조건·반복·함수의 실행 block을 연다
  5. 5. learner project의 Gradle wrapper로 지정 task를 실행한다
  6. 6. native process 종료 코드를 검사해 실패를 놓치지 않는다
  7. 7. class 이름과 기대 test 수를 exact inventory로 고정한다
  8. 8. JUnit XML 결과 파일만 exact inventory 입력으로 모은다

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

scripts/run-w24-release.ps1을 새 파일에 다시 쓰고 expected·actual·실패·cleanup·비범위를 주석으로 표시한다.

자가 점검
  • 비어 있지 않은 모든 source 줄을 한 번씩 읽었나?
  • source shape와 runtime Green을 분리했나?
  • 사람 검토·외부 상태를 자동 성공으로 꾸미지 않았나?
  • 첫 실패와 cleanup 책임을 설명할 수 있나?
13

STEP 13 / 13

전체 원본 source

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

원문 정본 전체 source 확인하기
PDF 전문 정본 · packaged PowerShell sourcescripts/run-w24-release.ps1SHA-256 6191a5c37f5b336203eecd9712f988b07eb9d6d936d27e3b07649ac36b9a3dcb
run-w24-release.ps1 — exact Gate와 lifecycle을 묶는 release owner 전체
param([Parameter(Mandatory=$true)][string]$ProjectRoot,[Parameter(Mandatory=$true)][string]$EvidenceDir,[string]$ComposeProject='w24-learner-release',[int]$Port=28080,[int]$DbPort=62440)
$ErrorActionPreference='Stop';$learner=(Resolve-Path -LiteralPath $ProjectRoot).Path;$e=[IO.Path]::GetFullPath($EvidenceDir);New-Item -ItemType Directory -Force $e|Out-Null
Push-Location $learner
try{
 & .\gradlew.bat clean test coreV1Gate --no-daemon
 if($LASTEXITCODE-ne 0){throw "W24 coreV1Gate exit=$LASTEXITCODE"}
 $contract=Get-Content -Raw -LiteralPath (Join-Path (Split-Path -Parent $PSScriptRoot) 'learning_stages/w24/overlay/core-v1-expected.json')|ConvertFrom-Json;$expected=@($contract.classes.psobject.Properties.Name)
 $rows=@(Get-ChildItem build/test-results/coreV1Gate -Filter 'TEST-*.xml'|ForEach-Object{[xml]$x=Get-Content -Raw $_.FullName;[pscustomobject]@{class=[string]$x.testsuite.name;tests=[int]$x.testsuite.tests;failures=[int]$x.testsuite.failures;errors=[int]$x.testsuite.errors;skipped=[int]$x.testsuite.skipped}})
 $actual=@($rows.class|Sort-Object -Unique);if(Compare-Object ($expected|Sort-Object) $actual){throw "W24 exact class inventory mismatch expected=$expected actual=$actual"}
 if($rows.Count-ne 37-or@($rows|Where-Object{$_.tests-ne[int]$contract.classes.psobject.Properties[$_.class].Value-or$_.failures-ne 0-or$_.errors-ne 0-or$_.skipped-ne 0}).Count-ne 0){throw "W24 per-suite XML exact mismatch classes=$($rows.Count)"};$total=($rows|Measure-Object tests -Sum).Sum;if($total-ne 66){throw "W24 exact test total mismatch=$total"}
 $rows|ConvertTo-Json|Set-Content -Encoding utf8 (Join-Path $e 'core-v1-gate.json')
}finally{Pop-Location}
& powershell.exe -NoProfile -ExecutionPolicy Bypass -File (Join-Path $PSScriptRoot 'run-w24-lifecycle.ps1') -ProjectRoot $learner -EvidenceDir $e -ComposeProject $ComposeProject -Port $Port -DbPort $DbPort
if($LASTEXITCODE-ne 0){throw "W24 lifecycle exit=$LASTEXITCODE"}
"W24_RELEASE_GREEN classes=37 selectors=43 tests=66 core_gate=GREEN demo=GREEN cleanup=1 native_exit=0"
17

run-w24-lifecycle.ps1 — DB·host JVM·demo·cleanup 책임

scripts/run-w24-lifecycle.ps1

PDF 전문 정본 · packaged PowerShell source · 정본 · W24-F17
25줄 연결25줄 번역3 chunks
01

STEP 01 / 13

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

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

오늘의 한 문장

disposable DB Compose와 host JVM을 띄워 readiness와 demo를 확인하고 성공·실패 모두에서 process·container·volume·secret 환경변수를 정리한다.

  1. port=28080은 어느 source와 실제 결과에서 확인해야 할까?
  2. 첫 실패를 만드는 조건과 fail-closed 지점은 어디일까?
  3. 왜 ‘Docker·port·자격증명이 필요하다’를 별도 경계로 남겨야 할까?
이 파일에서 끝까지 다시 쓰는 값port=28080dbPort=62440health=UPcleanup=1container_absentvolume_absent
왜 필요한가 — run-w24-lifecycle.ps1 — DB·host JVM·demo·cleanup 책임히토리 → 니지카 → 료 → 키타
  1. 히토리

    port=28080가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 disposable DB Compose와 host JVM을 띄워 readiness와 demo를 확인하고 성공·실패 모두에서 process·container·volume·secret 환경변수를 정리한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘Docker·port·자격증명이 필요하다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 port=28080와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

02

STEP 02 / 13

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

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

새 기능을 멈춘 팀이 코드·test·문서·demo를 같은 release 후보에 묶어 하나씩 검수한다.

검수 도장이 붙은 공통 거래 코어 출고 상자

이 파일은 disposable DB Compose와 host JVM을 띄워 readiness와 demo를 확인하고 성공·실패 모두에서 process·container·volume·secret 환경변수를 정리한다. 눈으로 읽을 때는 각 줄을 검수표 한 칸처럼 보고, 입력과 다음 상태를 놓치지 않는다.

마지막 도장은 source shape와 실제 runtime·사람 검토를 구분한 뒤에만 찍는다. 특히 Docker·port·자격증명이 필요하다

딱 여기까지만 비유는 실행 순서를 돕지만 실제 Gradle·Docker·DB·사람 review를 대신하지 않는다.

03

STEP 03 / 13

초등학생도 이해하는 설명

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

값 1: port=28080

이 파일에서 계속 확인할 고정 단서가 port=28080다.

코드 연결
F17 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
Docker·port·자격증명이 필요하다

값 2: dbPort=62440

이 파일에서 계속 확인할 고정 단서가 dbPort=62440다.

코드 연결
F17 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
강제 실패 경로도 cleanup 책임을 유지한다

값 3: health=UP

이 파일에서 계속 확인할 고정 단서가 health=UP다.

코드 연결
F17 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
실제 운영 환경 검증이 아니다

값 4: cleanup=1

이 파일에서 계속 확인할 고정 단서가 cleanup=1다.

코드 연결
F17 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
Docker·port·자격증명이 필요하다

값 5: container_absent

이 파일에서 계속 확인할 고정 단서가 container_absent다.

코드 연결
F17 전체 source와 evidence marker에서 같은 값을 찾는다.
비유
검수표에 미리 인쇄된 숫자나 상태 칸
비유의 끝
강제 실패 경로도 cleanup 책임을 유지한다
04

STEP 04 / 13

비유 ↔ 코드 전체 연결표

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

단어 몇 개만 뽑은 표가 아닙니다.PDF 전문 정본 · packaged PowerShell source에서 비어 있지 않은 모든 줄을 원본 줄 번호 그대로 연결했습니다.25 / 25 연결
정확한 원본 줄STARRY 비유실제 뜻·입력·결과·한계
1줄F17-L01 param([Parameter(Mandatory=$true)][string]$ProjectRoot,[Parameter(Mandatory=$true)][string]$EvidenceDir,[string]$ComposeProject='w24-learner-demo',[int]$Port=28080,[int]$DbPort=62440,[switch]$ForceFailureAfterCompose) 출고표 1번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 PowerShell script가 받을 입력 계약을 연다.
입력
$true, $ProjectRoot, $true
결과·효과
관찰 상태 F17-001가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
Docker·port·자격증명이 필요하다
2줄F17-L02 $ErrorActionPreference='Stop';$referenceRoot=Split-Path -Parent $PSScriptRoot;$learner=(Resolve-Path -LiteralPath $ProjectRoot).Path;$e=[IO.Path]::GetFullPath($EvidenceDir) 출고표 2번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다.
입력
$ErrorActionPreference, 'Stop', $referenceRoot
결과·효과
관찰 상태 F17-002가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
강제 실패 경로도 cleanup 책임을 유지한다
3줄F17-L03 if(!(Test-Path -LiteralPath (Join-Path $learner 'gradlew.bat') -PathType Leaf)){throw 'W24 learner gradlew.bat missing'} 출고표 3번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 learner project의 Gradle wrapper로 지정 task를 실행한다.
입력
$learner, 'gradlew.bat', 'W24 learner gradlew.bat missing'
결과·효과
관찰 상태 F17-003가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 운영 환경 검증이 아니다
4줄F17-L04 New-Item -ItemType Directory -Force $e|Out-Null;$proc=$null;$appPid=$null;$cleanupResponsible=$true;$body=$null;$caught=$null;$compose=Join-Path $referenceRoot 'compose.yaml';if(!(Test-Path -LiteralPath $compose)){throw 'W24 packaged DB-only compose.yaml missing'} 출고표 4번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 container·volume·process가 남지 않았는지 lifecycle evidence에 기록한다.
입력
$e, $proc, $null
결과·효과
관찰 상태 F17-004가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
Docker·port·자격증명이 필요하다
5줄F17-L05 $env:FCL_DB_PASSWORD='w24-disposable-password';$env:FCL_DB_PORT="$DbPort";$env:SPRING_DATASOURCE_URL="jdbc:postgresql://localhost:$DbPort/financial_core";$env:SPRING_DATASOURCE_USERNAME='app';$env:SPRING_DATASOURCE_PASSWORD=$env:FCL_DB_PASSWORD;$env:SERVER_PORT="$Port";$env:FCL_DEMO_USER='customer-1';$env:FCL_DEMO_PASSWORD='password' 출고표 5번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$env, 'w24-disposable-password', $env
결과·효과
관찰 상태 F17-005가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
강제 실패 경로도 cleanup 책임을 유지한다
6줄F17-L06 Push-Location $learner 출고표 6번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 run-w24-lifecycle.ps1의 다음 검증 또는 설명 단계를 구성한다.
입력
$learner
결과·효과
관찰 상태 F17-006가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 운영 환경 검증이 아니다
7줄F17-L07 try{ 출고표 7번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 조건·반복·함수의 실행 block을 연다.
입력
이전 줄의 상태와 port=28080
결과·효과
관찰 상태 F17-007가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
Docker·port·자격증명이 필요하다
8줄F17-L08 & docker compose -f $compose -p $ComposeProject up -d --wait db;if($LASTEXITCODE-ne 0){throw "W24 compose up exit=$LASTEXITCODE"};if($ForceFailureAfterCompose){throw 'W24 forced partial-startup failure'} 출고표 8번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 native process 종료 코드를 검사해 실패를 놓치지 않는다.
입력
$compose, $ComposeProject, $LASTEXITCODE
결과·효과
관찰 상태 F17-008가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
강제 실패 경로도 cleanup 책임을 유지한다
9줄F17-L09 $container=(& docker compose -f $compose -p $ComposeProject ps -q db).Trim();if($LASTEXITCODE-ne 0-or[string]::IsNullOrWhiteSpace($container)){throw 'W24 DB container resolution failed'} 출고표 9번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 native process 종료 코드를 검사해 실패를 놓치지 않는다.
입력
$container, $compose, $ComposeProject
결과·효과
관찰 상태 F17-009가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 운영 환경 검증이 아니다
10줄F17-L10 $stdout=Join-Path $e 'host.stdout.log';$stderr=Join-Path $e 'host.stderr.log';$proc=Start-Process -FilePath (Join-Path $learner 'gradlew.bat') -ArgumentList @('bootRun','--no-daemon') -WorkingDirectory $learner -PassThru -WindowStyle Hidden -RedirectStandardOutput $stdout -RedirectStandardError $stderr 출고표 10번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 learner project의 Gradle wrapper로 지정 task를 실행한다.
입력
$stdout, $e, 'host.stdout.log'
결과·효과
관찰 상태 F17-010가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
Docker·port·자격증명이 필요하다
11줄F17-L11 $health=$null;for($i=0;$i-lt 90;$i++){if($proc.HasExited){throw "W24 host app exited=$($proc.ExitCode)"};try{$health=Invoke-RestMethod "http://localhost:$Port/actuator/health" -TimeoutSec 2;if($health.status-eq'UP'){break}}catch{};Start-Sleep 1};if(!$health-or$health.status-ne'UP'){throw 'W24 readiness never UP'} 출고표 11번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 HTTP API를 호출해 status와 JSON response를 받는다.
입력
$health, $null, $i
결과·효과
관찰 상태 F17-011가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
강제 실패 경로도 cleanup 책임을 유지한다
12줄F17-L12 $listen=Get-NetTCPConnection -State Listen -LocalPort $Port -ErrorAction SilentlyContinue;if(!$listen){throw 'W24 listener missing'};$appPid=[int]$listen[0].OwningProcess 출고표 12번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
$listen, $Port, $listen
결과·효과
관찰 상태 F17-012가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 운영 환경 검증이 아니다
13줄F17-L13 & powershell.exe -NoProfile -ExecutionPolicy Bypass -File (Join-Path $referenceRoot 'scripts/run-w24-demo.ps1') -EvidencePath (Join-Path $e 'demo-run.txt') -BaseUrl "http://localhost:$Port" -Container $container;if($LASTEXITCODE-ne 0){throw "W24 demo exit=$LASTEXITCODE"} 출고표 13번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 native process 종료 코드를 검사해 실패를 놓치지 않는다.
입력
$referenceRoot, 'scripts/run-w24-demo.ps1', $e
결과·효과
관찰 상태 F17-013가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
Docker·port·자격증명이 필요하다
14줄F17-L14 $body=[ordered]@{compose_project=$ComposeProject;runtime='host JVM';port=$Port;health='UP';demo='GREEN';native_exit=0} 출고표 14번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
입력
$body, $ComposeProject, 'host JVM'
결과·효과
관찰 상태 F17-014가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
강제 실패 경로도 cleanup 책임을 유지한다
15줄F17-L15 }catch{$caught=$_}finally{ 출고표 15번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 중간 실패가 있어도 반드시 실행할 cleanup 경계를 연다.
입력
$caught, $_
결과·효과
관찰 상태 F17-015가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 운영 환경 검증이 아니다
16줄F17-L16 if($appPid){Stop-Process -Id $appPid -Force -ErrorAction SilentlyContinue};if($proc-and!$proc.HasExited){Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue} 출고표 16번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 성공·실패 뒤 남은 host JVM을 정리한다.
입력
$appPid, $appPid, $proc
결과·효과
관찰 상태 F17-016가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
Docker·port·자격증명이 필요하다
17줄F17-L17 & docker compose -f $compose -p $ComposeProject down -v|Out-Null;$downExit=$LASTEXITCODE 출고표 17번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 native process 종료 코드를 검사해 실패를 놓치지 않는다.
입력
$compose, $ComposeProject, $downExit
결과·효과
관찰 상태 F17-017가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
강제 실패 경로도 cleanup 책임을 유지한다
18줄F17-L18 $containers=@(& docker compose -f $compose -p $ComposeProject ps -q);$containerAbsent=($LASTEXITCODE-eq 0-and$containers.Count-eq 0) 출고표 18번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 native process 종료 코드를 검사해 실패를 놓치지 않는다.
입력
$containers, $compose, $ComposeProject
결과·효과
관찰 상태 F17-018가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 운영 환경 검증이 아니다
19줄F17-L19 $volumeName="${ComposeProject}_financial-core-db";$volumes=@(& docker volume ls -q --filter "name=^${volumeName}$");$volumeAbsent=($LASTEXITCODE-eq 0-and$volumes.Count-eq 0) 출고표 19번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 native process 종료 코드를 검사해 실패를 놓치지 않는다.
입력
$volumeName, "${ComposeProject}_financial-core-db", $volumes
결과·효과
관찰 상태 F17-019가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
Docker·port·자격증명이 필요하다
20줄F17-L20 Pop-Location;Remove-Item Env:FCL_DB_PASSWORD,Env:FCL_DB_PORT,Env:SPRING_DATASOURCE_URL,Env:SPRING_DATASOURCE_USERNAME,Env:SPRING_DATASOURCE_PASSWORD,Env:SERVER_PORT,Env:FCL_DEMO_USER,Env:FCL_DEMO_PASSWORD -ErrorAction SilentlyContinue 출고표 20번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 runtime에만 둔 DB·demo secret 환경변수를 정리한다.
입력
이전 줄의 상태와 port=28080
결과·효과
관찰 상태 F17-020가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
강제 실패 경로도 cleanup 책임을 유지한다
21줄F17-L21 } 출고표 21번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 앞에서 연 block 또는 호출 범위를 닫는다.
입력
이전 줄의 상태와 port=28080
결과·효과
관찰 상태 F17-021가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 운영 환경 검증이 아니다
22줄F17-L22 if($downExit-ne 0-or-not$containerAbsent-or-not$volumeAbsent){throw "W24 cleanup verification failed down=$downExit container_absent=$containerAbsent volume_absent=$volumeAbsent"} 출고표 22번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 container·volume·process가 남지 않았는지 lifecycle evidence에 기록한다.
입력
$downExit, 0, $containerAbsent
결과·효과
관찰 상태 F17-022가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
Docker·port·자격증명이 필요하다
23줄F17-L23 if($caught){throw $caught} 출고표 23번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
입력
$caught, $caught
결과·효과
관찰 상태 F17-023가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
강제 실패 경로도 cleanup 책임을 유지한다
24줄F17-L24 $body.cleanup=1;$body.down_native_exit=$downExit;$body.container_absent=$containerAbsent;$body.volume_absent=$volumeAbsent;$tmp=Join-Path $e 'lifecycle.json.tmp';$final=Join-Path $e 'lifecycle.json';$body|ConvertTo-Json|Set-Content -Encoding utf8 $tmp;Move-Item -LiteralPath $tmp -Destination $final -Force 출고표 24번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 검증된 object를 JSON evidence text로 직렬화한다.
입력
$body, 1, $body
결과·효과
관찰 상태 F17-024가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
실제 운영 환경 검증이 아니다
25줄F17-L25 "W24_LIFECYCLE_GREEN project=$ComposeProject port=$Port health=UP demo=GREEN cleanup=1 native_exit=0" 출고표 25번 칸을 읽어 다음 검사 칸으로 넘기는 장면 이 줄은 container·volume·process가 남지 않았는지 lifecycle evidence에 기록한다.
입력
$ComposeProject, $Port, 1
결과·효과
관찰 상태 F17-025가 만들어져 뒤 단계의 독립 판정 입력이 된다.
비유의 한계
Docker·port·자격증명이 필요하다
05

STEP 05 / 13

원본 코드 조각

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

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

F17-C01 · 원문 1–12줄1–12줄
1–12줄 원본
param([Parameter(Mandatory=$true)][string]$ProjectRoot,[Parameter(Mandatory=$true)][string]$EvidenceDir,[string]$ComposeProject='w24-learner-demo',[int]$Port=28080,[int]$DbPort=62440,[switch]$ForceFailureAfterCompose)
$ErrorActionPreference='Stop';$referenceRoot=Split-Path -Parent $PSScriptRoot;$learner=(Resolve-Path -LiteralPath $ProjectRoot).Path;$e=[IO.Path]::GetFullPath($EvidenceDir)
if(!(Test-Path -LiteralPath (Join-Path $learner 'gradlew.bat') -PathType Leaf)){throw 'W24 learner gradlew.bat missing'}
New-Item -ItemType Directory -Force $e|Out-Null;$proc=$null;$appPid=$null;$cleanupResponsible=$true;$body=$null;$caught=$null;$compose=Join-Path $referenceRoot 'compose.yaml';if(!(Test-Path -LiteralPath $compose)){throw 'W24 packaged DB-only compose.yaml missing'}
$env:FCL_DB_PASSWORD='w24-disposable-password';$env:FCL_DB_PORT="$DbPort";$env:SPRING_DATASOURCE_URL="jdbc:postgresql://localhost:$DbPort/financial_core";$env:SPRING_DATASOURCE_USERNAME='app';$env:SPRING_DATASOURCE_PASSWORD=$env:FCL_DB_PASSWORD;$env:SERVER_PORT="$Port";$env:FCL_DEMO_USER='customer-1';$env:FCL_DEMO_PASSWORD='password'
Push-Location $learner
try{
 & docker compose -f $compose -p $ComposeProject up -d --wait db;if($LASTEXITCODE-ne 0){throw "W24 compose up exit=$LASTEXITCODE"};if($ForceFailureAfterCompose){throw 'W24 forced partial-startup failure'}
 $container=(& docker compose -f $compose -p $ComposeProject ps -q db).Trim();if($LASTEXITCODE-ne 0-or[string]::IsNullOrWhiteSpace($container)){throw 'W24 DB container resolution failed'}
 $stdout=Join-Path $e 'host.stdout.log';$stderr=Join-Path $e 'host.stderr.log';$proc=Start-Process -FilePath (Join-Path $learner 'gradlew.bat') -ArgumentList @('bootRun','--no-daemon') -WorkingDirectory $learner -PassThru -WindowStyle Hidden -RedirectStandardOutput $stdout -RedirectStandardError $stderr
 $health=$null;for($i=0;$i-lt 90;$i++){if($proc.HasExited){throw "W24 host app exited=$($proc.ExitCode)"};try{$health=Invoke-RestMethod "http://localhost:$Port/actuator/health" -TimeoutSec 2;if($health.status-eq'UP'){break}}catch{};Start-Sleep 1};if(!$health-or$health.status-ne'UP'){throw 'W24 readiness never UP'}
 $listen=Get-NetTCPConnection -State Listen -LocalPort $Port -ErrorAction SilentlyContinue;if(!$listen){throw 'W24 listener missing'};$appPid=[int]$listen[0].OwningProcess
F17-C02 · 원문 13–24줄13–24줄
13–24줄 원본
 & powershell.exe -NoProfile -ExecutionPolicy Bypass -File (Join-Path $referenceRoot 'scripts/run-w24-demo.ps1') -EvidencePath (Join-Path $e 'demo-run.txt') -BaseUrl "http://localhost:$Port" -Container $container;if($LASTEXITCODE-ne 0){throw "W24 demo exit=$LASTEXITCODE"}
 $body=[ordered]@{compose_project=$ComposeProject;runtime='host JVM';port=$Port;health='UP';demo='GREEN';native_exit=0}
}catch{$caught=$_}finally{
 if($appPid){Stop-Process -Id $appPid -Force -ErrorAction SilentlyContinue};if($proc-and!$proc.HasExited){Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue}
 & docker compose -f $compose -p $ComposeProject down -v|Out-Null;$downExit=$LASTEXITCODE
 $containers=@(& docker compose -f $compose -p $ComposeProject ps -q);$containerAbsent=($LASTEXITCODE-eq 0-and$containers.Count-eq 0)
 $volumeName="${ComposeProject}_financial-core-db";$volumes=@(& docker volume ls -q --filter "name=^${volumeName}$");$volumeAbsent=($LASTEXITCODE-eq 0-and$volumes.Count-eq 0)
 Pop-Location;Remove-Item Env:FCL_DB_PASSWORD,Env:FCL_DB_PORT,Env:SPRING_DATASOURCE_URL,Env:SPRING_DATASOURCE_USERNAME,Env:SPRING_DATASOURCE_PASSWORD,Env:SERVER_PORT,Env:FCL_DEMO_USER,Env:FCL_DEMO_PASSWORD -ErrorAction SilentlyContinue
}
if($downExit-ne 0-or-not$containerAbsent-or-not$volumeAbsent){throw "W24 cleanup verification failed down=$downExit container_absent=$containerAbsent volume_absent=$volumeAbsent"}
if($caught){throw $caught}
$body.cleanup=1;$body.down_native_exit=$downExit;$body.container_absent=$containerAbsent;$body.volume_absent=$volumeAbsent;$tmp=Join-Path $e 'lifecycle.json.tmp';$final=Join-Path $e 'lifecycle.json';$body|ConvertTo-Json|Set-Content -Encoding utf8 $tmp;Move-Item -LiteralPath $tmp -Destination $final -Force
F17-C03 · 원문 25–25줄25–25줄
25–25줄 원본
"W24_LIFECYCLE_GREEN project=$ComposeProject port=$Port health=UP demo=GREEN cleanup=1 native_exit=0"
06

STEP 06 / 13

코드 한 줄씩 한국어로 번역

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

전체 번역 25 / 25

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

원본한국어 번역
1param([Parameter(Mandatory=$true)][string]$ProjectRoot,[Parameter(Mandatory=$true)][string]$EvidenceDir,[string]$ComposeProject='w24-learner-demo',[int]$Port=28080,[int]$DbPort=62440,[switch]$ForceFailureAfterCompose)실행 의미: PowerShell script가 받을 입력 계약을 연다.
2$ErrorActionPreference='Stop';$referenceRoot=Split-Path -Parent $PSScriptRoot;$learner=(Resolve-Path -LiteralPath $ProjectRoot).Path;$e=[IO.Path]::GetFullPath($EvidenceDir)실행 의미: PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다.
3if(!(Test-Path -LiteralPath (Join-Path $learner 'gradlew.bat') -PathType Leaf)){throw 'W24 learner gradlew.bat missing'}실행 의미: learner project의 Gradle wrapper로 지정 task를 실행한다.
4New-Item -ItemType Directory -Force $e|Out-Null;$proc=$null;$appPid=$null;$cleanupResponsible=$true;$body=$null;$caught=$null;$compose=Join-Path $referenceRoot 'compose.yaml';if(!(Test-Path -LiteralPath $compose)){throw 'W24 packaged DB-only compose.yaml missing'}실행 의미: container·volume·process가 남지 않았는지 lifecycle evidence에 기록한다.
5$env:FCL_DB_PASSWORD='w24-disposable-password';$env:FCL_DB_PORT="$DbPort";$env:SPRING_DATASOURCE_URL="jdbc:postgresql://localhost:$DbPort/financial_core";$env:SPRING_DATASOURCE_USERNAME='app';$env:SPRING_DATASOURCE_PASSWORD=$env:FCL_DB_PASSWORD;$env:SERVER_PORT="$Port";$env:FCL_DEMO_USER='customer-1';$env:FCL_DEMO_PASSWORD='password'실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
6Push-Location $learner실행 의미: run-w24-lifecycle.ps1의 다음 검증 또는 설명 단계를 구성한다.
7try{실행 의미: 조건·반복·함수의 실행 block을 연다.
8 & docker compose -f $compose -p $ComposeProject up -d --wait db;if($LASTEXITCODE-ne 0){throw "W24 compose up exit=$LASTEXITCODE"};if($ForceFailureAfterCompose){throw 'W24 forced partial-startup failure'}실행 의미: native process 종료 코드를 검사해 실패를 놓치지 않는다.
9 $container=(& docker compose -f $compose -p $ComposeProject ps -q db).Trim();if($LASTEXITCODE-ne 0-or[string]::IsNullOrWhiteSpace($container)){throw 'W24 DB container resolution failed'}실행 의미: native process 종료 코드를 검사해 실패를 놓치지 않는다.
10 $stdout=Join-Path $e 'host.stdout.log';$stderr=Join-Path $e 'host.stderr.log';$proc=Start-Process -FilePath (Join-Path $learner 'gradlew.bat') -ArgumentList @('bootRun','--no-daemon') -WorkingDirectory $learner -PassThru -WindowStyle Hidden -RedirectStandardOutput $stdout -RedirectStandardError $stderr실행 의미: learner project의 Gradle wrapper로 지정 task를 실행한다.
11 $health=$null;for($i=0;$i-lt 90;$i++){if($proc.HasExited){throw "W24 host app exited=$($proc.ExitCode)"};try{$health=Invoke-RestMethod "http://localhost:$Port/actuator/health" -TimeoutSec 2;if($health.status-eq'UP'){break}}catch{};Start-Sleep 1};if(!$health-or$health.status-ne'UP'){throw 'W24 readiness never UP'}실행 의미: HTTP API를 호출해 status와 JSON response를 받는다.
12 $listen=Get-NetTCPConnection -State Listen -LocalPort $Port -ErrorAction SilentlyContinue;if(!$listen){throw 'W24 listener missing'};$appPid=[int]$listen[0].OwningProcess실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
13 & powershell.exe -NoProfile -ExecutionPolicy Bypass -File (Join-Path $referenceRoot 'scripts/run-w24-demo.ps1') -EvidencePath (Join-Path $e 'demo-run.txt') -BaseUrl "http://localhost:$Port" -Container $container;if($LASTEXITCODE-ne 0){throw "W24 demo exit=$LASTEXITCODE"}실행 의미: native process 종료 코드를 검사해 실패를 놓치지 않는다.
14 $body=[ordered]@{compose_project=$ComposeProject;runtime='host JVM';port=$Port;health='UP';demo='GREEN';native_exit=0}실행 의미: 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다.
15}catch{$caught=$_}finally{실행 의미: 중간 실패가 있어도 반드시 실행할 cleanup 경계를 연다.
16 if($appPid){Stop-Process -Id $appPid -Force -ErrorAction SilentlyContinue};if($proc-and!$proc.HasExited){Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue}실행 의미: 성공·실패 뒤 남은 host JVM을 정리한다.
17 & docker compose -f $compose -p $ComposeProject down -v|Out-Null;$downExit=$LASTEXITCODE실행 의미: native process 종료 코드를 검사해 실패를 놓치지 않는다.
18 $containers=@(& docker compose -f $compose -p $ComposeProject ps -q);$containerAbsent=($LASTEXITCODE-eq 0-and$containers.Count-eq 0)실행 의미: native process 종료 코드를 검사해 실패를 놓치지 않는다.
19 $volumeName="${ComposeProject}_financial-core-db";$volumes=@(& docker volume ls -q --filter "name=^${volumeName}$");$volumeAbsent=($LASTEXITCODE-eq 0-and$volumes.Count-eq 0)실행 의미: native process 종료 코드를 검사해 실패를 놓치지 않는다.
20 Pop-Location;Remove-Item Env:FCL_DB_PASSWORD,Env:FCL_DB_PORT,Env:SPRING_DATASOURCE_URL,Env:SPRING_DATASOURCE_USERNAME,Env:SPRING_DATASOURCE_PASSWORD,Env:SERVER_PORT,Env:FCL_DEMO_USER,Env:FCL_DEMO_PASSWORD -ErrorAction SilentlyContinue실행 의미: runtime에만 둔 DB·demo secret 환경변수를 정리한다.
21}실행 의미: 앞에서 연 block 또는 호출 범위를 닫는다.
22if($downExit-ne 0-or-not$containerAbsent-or-not$volumeAbsent){throw "W24 cleanup verification failed down=$downExit container_absent=$containerAbsent volume_absent=$volumeAbsent"}실행 의미: container·volume·process가 남지 않았는지 lifecycle evidence에 기록한다.
23if($caught){throw $caught}실행 의미: 계약 위반을 발견하면 성공 marker 전에 실행을 중단한다.
24$body.cleanup=1;$body.down_native_exit=$downExit;$body.container_absent=$containerAbsent;$body.volume_absent=$volumeAbsent;$tmp=Join-Path $e 'lifecycle.json.tmp';$final=Join-Path $e 'lifecycle.json';$body|ConvertTo-Json|Set-Content -Encoding utf8 $tmp;Move-Item -LiteralPath $tmp -Destination $final -Force실행 의미: 검증된 object를 JSON evidence text로 직렬화한다.
25"W24_LIFECYCLE_GREEN project=$ComposeProject port=$Port health=UP demo=GREEN cleanup=1 native_exit=0"실행 의미: container·volume·process가 남지 않았는지 lifecycle evidence에 기록한다.
07

STEP 07 / 13

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

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

한 줄로 읽기

run-w24-lifecycle.ps1 — DB·host JVM·demo·cleanup 책임는 disposable DB Compose와 host JVM을 띄워 readiness와 demo를 확인하고 성공·실패 모두에서 process·container·volume·secret 환경변수를 정리한다.

문법 해부

  • .ps1 문법에서 선언·조건·pipeline·block 경계를 먼저 나눈다.
  • expected 값과 actual 결과를 같은 이름처럼 보여도 서로 다른 source로 읽는다.
  • native exit·row count·hash·사람 판정을 서로 대체하지 않는다.

실행 순서

  1. 입력 경로·fixture·환경변수·expected 계약을 고정한다.
  2. source가 실행하는 native process·HTTP·SQL 또는 형식 검사를 따라간다.
  3. actual 값과 exact marker를 대조하고 실패면 성공 발행 전에 중단한다.
  4. finally cleanup과 비범위를 evidence에 남긴다.

W24 조각별 정밀 해설

F17-C01 · 원문 1–12줄
문법 해부
.ps1 문법으로 1–12줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
port=28080, dbPort=62440, health=UP를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
Docker·port·자격증명이 필요하다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
Docker·port·자격증명이 필요하다; 강제 실패 경로도 cleanup 책임을 유지한다; 실제 운영 환경 검증이 아니다
다음 연결
다음 조각 또는 F17 evidence 판정으로 상태를 넘긴다.
F17-C02 · 원문 13–24줄
문법 해부
.ps1 문법으로 13–24줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
port=28080, dbPort=62440, health=UP를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
Docker·port·자격증명이 필요하다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
Docker·port·자격증명이 필요하다; 강제 실패 경로도 cleanup 책임을 유지한다; 실제 운영 환경 검증이 아니다
다음 연결
다음 조각 또는 F17 evidence 판정으로 상태를 넘긴다.
F17-C03 · 원문 25–25줄
문법 해부
.ps1 문법으로 25–25줄의 선언·조건·pipeline·block을 나눈다.
실제 값 추적
port=28080, dbPort=62440, health=UP를 입력으로 두고 이 조각 뒤의 actual 상태를 추적한다.
정상 예
expected와 actual이 일치하고 owner evidence가 같은 run/hash에 연결되는 경우다.
틀린 예·반례
Docker·port·자격증명이 필요하다인데도 더 큰 Green을 주장하는 경우다.
착각 방지
파일 존재·문자열·hash·exit0 하나를 의미 Green 전체와 같다고 보지 않는다.
하지 않는 일
Docker·port·자격증명이 필요하다; 강제 실패 경로도 cleanup 책임을 유지한다; 실제 운영 환경 검증이 아니다
다음 연결
다음 조각 또는 F17 evidence 판정으로 상태를 넘긴다.
실행 순서 — run-w24-lifecycle.ps1 — DB·host JVM·demo·cleanup 책임히토리 → 니지카 → 료 → 키타
  1. 히토리

    dbPort=62440가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 disposable DB Compose와 host JVM을 띄워 readiness와 demo를 확인하고 성공·실패 모두에서 process·container·volume·secret 환경변수를 정리한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘강제 실패 경로도 cleanup 책임을 유지한다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 dbPort=62440와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

08

STEP 08 / 13

실제 값 따라가기

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

순서들어온 값코드가 하는 일나온 값·상태경계
입력port=28080source 계약에 대입F17 실행/설명 시작 상태Docker·port·자격증명이 필요하다
검증dbPort=62440expected와 actual 또는 형식 대조통과 또는 첫 mismatch강제 실패 경로도 cleanup 책임을 유지한다
증거volume_absentmarker·hash·row를 같은 run에 연결범위가 적힌 evidence 후보실제 운영 환경 검증이 아니다
실제 값 — run-w24-lifecycle.ps1 — DB·host JVM·demo·cleanup 책임히토리 → 니지카 → 료 → 키타
  1. 히토리

    health=UP가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 disposable DB Compose와 host JVM을 띄워 readiness와 demo를 확인하고 성공·실패 모두에서 process·container·volume·secret 환경변수를 정리한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘실제 운영 환경 검증이 아니다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 health=UP와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

09

STEP 09 / 13

Gradle·PowerShell·HTTP·PostgreSQL 내부에서 벌어지는 일

Gradle·JUnit XML·PowerShell·HTTP·PostgreSQL·Docker에서 실제로 일어나는 일과 증명 범위를 구분합니다.

source/contract

run-w24-lifecycle.ps1 bytes와 expected 값을 읽는다.

파일 존재만으로 runtime 성공은 아니다.
execution/evidence

native exit·HTTP status·JUnit XML·DB row·hash 중 이 파일이 소유한 값을 만든다.

Docker·port·자격증명이 필요하다
release/human

관련 evidence와 사람 의미 검토를 release 후보에 연결한다.

실제 운영 환경 검증이 아니다
첫 실패 경계 — run-w24-lifecycle.ps1 — DB·host JVM·demo·cleanup 책임히토리 → 니지카 → 료 → 키타
  1. 히토리

    cleanup=1가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 disposable DB Compose와 host JVM을 띄워 readiness와 demo를 확인하고 성공·실패 모두에서 process·container·volume·secret 환경변수를 정리한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘Docker·port·자격증명이 필요하다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 cleanup=1와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

10

STEP 10 / 13

흔한 착각과 틀린 예

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

❌ port=28080 문자열이 source에 있으니 실제 실행도 Green이다.

왜 틀리나 source literal과 runtime 관찰값은 다른 증거다.

바르게 읽기 native exit·actual XML/HTTP/DB evidence를 별도로 확인한다.

반례 script가 실행 전 경로 오류로 멈춰도 literal은 그대로 남는다.

❌ 파일 SHA-256이 있으면 내용의 의미와 사실성도 검증됐다.

왜 틀리나 hash는 동일 bytes만 말한다.

바르게 읽기 schema·수치·질문·근거는 별도 자동 또는 사람 판정을 거친다.

반례 빈 review 질문을 가진 CSV도 안정된 hash를 가진다.

❌ LOCAL_ARTIFACT_VALIDATED는 release Green과 같다.

왜 틀리나 generic validator는 파일 shape만 확인한다.

바르게 읽기 HUMAN_SEMANTIC_REVIEW_REQUIRED를 유지한다.

반례 잘못된 track 점수표도 byte 수 조건은 통과할 수 있다.

❌ 이 파일이 W24 전체 lifecycle을 모두 소유한다.

왜 틀리나 각 source는 Gate·demo·cleanup·사람 review 중 일부만 담당한다.

바르게 읽기 owner와 non-responsibility를 release manifest에서 분리한다.

반례 D4 source audit에는 runtime_claim=false가 명시된다.

❌ 이전 주 Green이나 오래된 log를 현재 commit 결과로 재사용한다.

왜 틀리나 source·commit·actual result가 같은 실행에 묶이지 않는다.

바르게 읽기 release 후보에서 새 evidence와 hash를 만든다.

반례 expected JSON이 바뀌면 예전 XML은 exact inventory를 증명하지 못한다.

11

STEP 11 / 13

이 코드가 보장하지 않는 것

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

증명 범위

Docker·port·자격증명이 필요하다

이 책임을 맡는 곳: runtime Gate
증명 범위

강제 실패 경로도 cleanup 책임을 유지한다

이 책임을 맡는 곳: external/human review
증명 범위

실제 운영 환경 검증이 아니다

이 책임을 맡는 곳: release manifest
증명 범위

Docker·port·자격증명이 필요하다

이 책임을 맡는 곳: 운영 환경
증명하지 않는 범위 — run-w24-lifecycle.ps1 — DB·host JVM·demo·cleanup 책임히토리 → 니지카 → 료 → 키타
  1. 히토리

    container_absent가 보이면 바로 완료라고 생각해도 돼? 어떤 입력과 상태를 먼저 확인해야 해?

  2. 니지카

    순서는 source를 읽고 입력을 고정한 뒤 disposable DB Compose와 host JVM을 띄워 readiness와 demo를 확인하고 성공·실패 모두에서 process·container·volume·secret 환경변수를 정리한다. 마지막에 실제 marker와 evidence를 대조하는 거야.

  3. 여기서 멈출 경계는 ‘강제 실패 경로도 cleanup 책임을 유지한다’야. 파일 존재나 문자열 하나를 더 큰 성공으로 확대하면 안 돼.

  4. 키타

    판정은 container_absent와 실제 exit·row·hash를 같은 실행에 묶는 것. 이 HTML은 코드를 설명하지만 runtime Green을 만들지는 않아.

12

STEP 12 / 13

직접 다시 써보기

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

1단계 · 뜻부터 복원

  • disposable DB Compose와 host JVM을 띄워 readiness와 demo를 확인하고 성공·실패 모두에서 process·container·volume·secret 환경변수를 정리한다.
  • 핵심 값은 port=28080, dbPort=62440, health=UP, cleanup=1, container_absent, volume_absent다.

2단계 · 코드 조각 재조립

  1. 1. PowerShell script가 받을 입력 계약을 연다
  2. 2. PowerShell 오류를 계속 진행하지 않고 중단시키는 기본 정책을 둔다
  3. 3. learner project의 Gradle wrapper로 지정 task를 실행한다
  4. 4. container·volume·process가 남지 않았는지 lifecycle evidence에 기록한다
  5. 5. 오른쪽 계산 결과를 이름 붙인 PowerShell 변수에 저장한다
  6. 6. run-w24-lifecycle.ps1의 다음 검증 또는 설명 단계를 구성한다
  7. 7. 조건·반복·함수의 실행 block을 연다
  8. 8. native process 종료 코드를 검사해 실패를 놓치지 않는다

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

scripts/run-w24-lifecycle.ps1을 새 파일에 다시 쓰고 expected·actual·실패·cleanup·비범위를 주석으로 표시한다.

자가 점검
  • 비어 있지 않은 모든 source 줄을 한 번씩 읽었나?
  • source shape와 runtime Green을 분리했나?
  • 사람 검토·외부 상태를 자동 성공으로 꾸미지 않았나?
  • 첫 실패와 cleanup 책임을 설명할 수 있나?
13

STEP 13 / 13

전체 원본 source

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

원문 정본 전체 source 확인하기
PDF 전문 정본 · packaged PowerShell sourcescripts/run-w24-lifecycle.ps1SHA-256 f22fa51f1a5e4b9dceb836c81a520f82ae6e500108de1e027d6d47d2e18d1983
run-w24-lifecycle.ps1 — DB·host JVM·demo·cleanup 책임 전체
param([Parameter(Mandatory=$true)][string]$ProjectRoot,[Parameter(Mandatory=$true)][string]$EvidenceDir,[string]$ComposeProject='w24-learner-demo',[int]$Port=28080,[int]$DbPort=62440,[switch]$ForceFailureAfterCompose)
$ErrorActionPreference='Stop';$referenceRoot=Split-Path -Parent $PSScriptRoot;$learner=(Resolve-Path -LiteralPath $ProjectRoot).Path;$e=[IO.Path]::GetFullPath($EvidenceDir)
if(!(Test-Path -LiteralPath (Join-Path $learner 'gradlew.bat') -PathType Leaf)){throw 'W24 learner gradlew.bat missing'}
New-Item -ItemType Directory -Force $e|Out-Null;$proc=$null;$appPid=$null;$cleanupResponsible=$true;$body=$null;$caught=$null;$compose=Join-Path $referenceRoot 'compose.yaml';if(!(Test-Path -LiteralPath $compose)){throw 'W24 packaged DB-only compose.yaml missing'}
$env:FCL_DB_PASSWORD='w24-disposable-password';$env:FCL_DB_PORT="$DbPort";$env:SPRING_DATASOURCE_URL="jdbc:postgresql://localhost:$DbPort/financial_core";$env:SPRING_DATASOURCE_USERNAME='app';$env:SPRING_DATASOURCE_PASSWORD=$env:FCL_DB_PASSWORD;$env:SERVER_PORT="$Port";$env:FCL_DEMO_USER='customer-1';$env:FCL_DEMO_PASSWORD='password'
Push-Location $learner
try{
 & docker compose -f $compose -p $ComposeProject up -d --wait db;if($LASTEXITCODE-ne 0){throw "W24 compose up exit=$LASTEXITCODE"};if($ForceFailureAfterCompose){throw 'W24 forced partial-startup failure'}
 $container=(& docker compose -f $compose -p $ComposeProject ps -q db).Trim();if($LASTEXITCODE-ne 0-or[string]::IsNullOrWhiteSpace($container)){throw 'W24 DB container resolution failed'}
 $stdout=Join-Path $e 'host.stdout.log';$stderr=Join-Path $e 'host.stderr.log';$proc=Start-Process -FilePath (Join-Path $learner 'gradlew.bat') -ArgumentList @('bootRun','--no-daemon') -WorkingDirectory $learner -PassThru -WindowStyle Hidden -RedirectStandardOutput $stdout -RedirectStandardError $stderr
 $health=$null;for($i=0;$i-lt 90;$i++){if($proc.HasExited){throw "W24 host app exited=$($proc.ExitCode)"};try{$health=Invoke-RestMethod "http://localhost:$Port/actuator/health" -TimeoutSec 2;if($health.status-eq'UP'){break}}catch{};Start-Sleep 1};if(!$health-or$health.status-ne'UP'){throw 'W24 readiness never UP'}
 $listen=Get-NetTCPConnection -State Listen -LocalPort $Port -ErrorAction SilentlyContinue;if(!$listen){throw 'W24 listener missing'};$appPid=[int]$listen[0].OwningProcess
 & powershell.exe -NoProfile -ExecutionPolicy Bypass -File (Join-Path $referenceRoot 'scripts/run-w24-demo.ps1') -EvidencePath (Join-Path $e 'demo-run.txt') -BaseUrl "http://localhost:$Port" -Container $container;if($LASTEXITCODE-ne 0){throw "W24 demo exit=$LASTEXITCODE"}
 $body=[ordered]@{compose_project=$ComposeProject;runtime='host JVM';port=$Port;health='UP';demo='GREEN';native_exit=0}
}catch{$caught=$_}finally{
 if($appPid){Stop-Process -Id $appPid -Force -ErrorAction SilentlyContinue};if($proc-and!$proc.HasExited){Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue}
 & docker compose -f $compose -p $ComposeProject down -v|Out-Null;$downExit=$LASTEXITCODE
 $containers=@(& docker compose -f $compose -p $ComposeProject ps -q);$containerAbsent=($LASTEXITCODE-eq 0-and$containers.Count-eq 0)
 $volumeName="${ComposeProject}_financial-core-db";$volumes=@(& docker volume ls -q --filter "name=^${volumeName}$");$volumeAbsent=($LASTEXITCODE-eq 0-and$volumes.Count-eq 0)
 Pop-Location;Remove-Item Env:FCL_DB_PASSWORD,Env:FCL_DB_PORT,Env:SPRING_DATASOURCE_URL,Env:SPRING_DATASOURCE_USERNAME,Env:SPRING_DATASOURCE_PASSWORD,Env:SERVER_PORT,Env:FCL_DEMO_USER,Env:FCL_DEMO_PASSWORD -ErrorAction SilentlyContinue
}
if($downExit-ne 0-or-not$containerAbsent-or-not$volumeAbsent){throw "W24 cleanup verification failed down=$downExit container_absent=$containerAbsent volume_absent=$volumeAbsent"}
if($caught){throw $caught}
$body.cleanup=1;$body.down_native_exit=$downExit;$body.container_absent=$containerAbsent;$body.volume_absent=$volumeAbsent;$tmp=Join-Path $e 'lifecycle.json.tmp';$final=Join-Path $e 'lifecycle.json';$body|ConvertTo-Json|Set-Content -Encoding utf8 $tmp;Move-Item -LiteralPath $tmp -Destination $final -Force
"W24_LIFECYCLE_GREEN project=$ComposeProject port=$Port health=UP demo=GREEN cleanup=1 native_exit=0"