화면에 보류라고 나와도 이유는 하나가 아니었다. 실제 자료로 조건을 계산했지만 맞지 않을 수도 있고, 계산에 필요한 자료부터 없을 수도 있다. 나는 가상 계산 프로그램의 입력 함수와 상태 표시를 읽으며 두 판단을 어떻게 나눴는지 정리하고, 다른 업무에도 쓸 수 있는 합성 요약 모듈을 만들었다.

후속 개발에서는 자료 없음이 0으로 바뀌는 해석을 고친 뒤, 그 검사에 도착하기 전에 불리언과 배열이 숫자로 바뀌는 경로도 찾았다. 이 글은 두 수정의 순서와 실제 검증 범위를 이어 남기고, 공유 요약 모듈이 맡는 책임과 구별한다.

입력은 실제여도 화면 속 결과까지 실제가 되는 것은 아니었다

과거 대화에는 원래 시세를 읽는 화면과 고정된 가상 결과를 구분한 설명이 있었다. 이후 사용자가 고정 데모 대신 입력에 따라 가상 계산이 이어지길 요청했다. 나는 그 전환을 현재의 수익 성과로 소개하지 않고, 입력에서 판단을 만드는 함수와 자료가 부족할 때의 반환값을 읽었다.

처음 이 글과 합성 모듈을 만들 때는 원래 앱이나 시장 연결을 실행하지 않았다. 당시의 시세 수신과 가상체결, 시험 통과는 과거 작업 기록으로 읽었다. 후속 순수 엔진 수정과 합성 재현은 아래에 별도로 남겼다. 프로그램의 주문과 원장은 가상 계산이고 실제 계좌의 결과가 아니다. 질문은 어떤 전략이 좋은가보다 프로그램이 무엇을 근거로 판단할 수 있었는가에 있다.

필요한 자료가 없는 전략은 먼저 보류했다

선택한 진입 함수는 특정 전략 종류에 대해 곧바로 HOLD와 dataSupported:false를 돌려준다. 이유에는 필요한 관찰의 종류가 붙는다. 스냅샷 가격이 있다는 사실로 더 세밀한 체결 자료나 검증된 사건 자료까지 존재한다고 가정하지 않은 것이다. 이 분기는 연결 범위를 코드에 명시한 선택이었다.

현재 소스에서는 이 지원 범위가 전략별 분기로 정해져 있다. 입력 객체에 필드를 조금 더 넣는 것만으로 미지원 전략이 자동으로 작동하는 구조라고 설명하지 않았다. 새로운 연결을 만든다면 자료의 의미와 시각, 해당 전략이 그 자료를 사용하는 경로를 함께 확인해야 한다. 이번에는 그런 연결이나 전략 변경을 수행하지 않았다.

같은 보류라도 계산한 거짓과 미확인은 다르다

일반 규칙은 met와 available을 함께 남긴다. 필요한 자료는 있는데 비교 조건이 맞지 않는 경우와 필요한 값이 없어 비교할 수 없는 경우를 구분할 수 있는 구조다. 둘 다 결과 행동이 HOLD일 수 있어도, 담당자가 해야 할 일은 기다리기인지 자료를 연결하기인지 달라진다.

판단 기록에는 이유, 규칙 근거, 원본 자료 시각과 판단 시각이 남는다. 특히 dataSupported가 False이면 마지막 평가 시각은 기존 값을 유지한다. 자료가 없는 시도를 정상 평가와 같은 시계로 세지 않으려는 선택으로 읽었다. 이 정적 코드를 확인한 것이 실제 대기 시간을 측정하거나 원래 앱의 동작을 새로 재현한 결과는 아니다.

필수 조건에서 뺀 관찰은 다른 칸에 남겨야 했다

일부 최근 관찰은 처음에는 쌓이지 않을 수 있다. 원래 함수는 이름이 정해진 보조 규칙을 필수 조건 계산에서 제외한다. 이때 전체 규칙 개수와 필수 조건 개수는 같지 않다. 보조 관찰의 초기 상태를 어떤 정책으로 허용했는지까지 읽어야 충족 개수의 의미를 설명할 수 있었다.

새 합성 예제는 이를 특정 이름 대신 required 필드로 표현했다. 선택 자료가 없어도 필수 조건의 준비는 유지하되, 선택 자료의 미확인은 별도 목록에 남긴다. 원래의 규칙 이름 정책을 잘못됐다고 판정하거나 그대로 복제한 것이 아니다. 다른 프로그램에 옮길 때 필요한 의도를 더 명시적으로 보이게 만든 독립 계약이다.

대기 중이라는 한 줄만으로는 다음 일을 알기 어려웠다

읽은 행 컴포넌트는 met를 기준으로 충족과 대기 중을 표시한다. 그 주위의 어댑터는 dataSupported를 별도로 읽어 데이터 미지원·보류, 장 상태와 위험 한도 같은 이유를 나눈다. 따라서 행 하나의 짧은 문구와 화면 전체가 설명하는 상태를 함께 봐야 했다. 이번에는 원래 화면을 수정하거나 실제 표시를 검수하지 않았다.

새 요약은 자료 부족, 평가했지만 조건 미충족, 필수 조건 충족이라는 세 상태를 돌려준다. 부족한 자료가 있으면 제목에서는 그것을 우선하되, 이미 거짓으로 나온 조건도 버리지 않는다. 자료가 없다는 이유를 일반 대기로 숨기지 않고 알려 주면 사용자는 기능이 고장 난 것인지, 입력을 준비해야 하는지 질문할 수 있다.

실제 계산과 공유 예제의 시험을 섞지 않았다

첫 공개 때 기존 자료 상태 모듈을 먼저 읽었지만 그 코드는 메뉴·자료의 확인과 미리보기·발행 조건을 다룬다. 그때는 규칙마다 입력 유무와 조건 참·거짓을 따로 다뤄야 해서 작은 새 모듈을 만들었다. 자료가 없으면 met=None, 자료가 있으면 boolean만 받고 모순된 입력은 거절한다. 결과가 충족이어도 행동을 실행하지 않는다.

첫 공개에서는 독립 합성 시험 22개를 소스와 ZIP 추출에서 실행하고 다섯 기록을 남겼다. 그것은 과거 대화의 원래 프로그램 시험이나 시장 수신 성공을 가져온 숫자가 아니다. 아래 후속 개발의 원제품 검사와도 다른 근거다. 공유한 것은 자료와 판단의 상태를 정리하는 범용 계산이며, 이 요약 모듈 자체가 원래 엔진의 수정본은 아니다.

코드와 구현 살펴보기

합성 필수 자료가 없을 때의 실제 반환값

{
  "state": "inputs_missing",
  "required_total": 1,
  "available_required": 0,
  "met_required": 0,
  "missing_required": [
    "observation"
  ],
  "unmet_required": [],
  "missing_optional": [],
  "evaluation_ready": false,
  "all_required_conditions_met": false,
  "executes_action": false,
  "authenticates_evidence": false
}

후속 수정에서 자료 없음이 0으로 바뀌던 입구를 찾았다

자료 유무와 조건 결과를 따로 적는 구조만으로는 충분하지 않았다. 그 앞의 해석 함수가 없는 값을 0으로 바꾼다면, 뒤의 규칙은 자료가 있다고 믿고 계산한다. 후속 로컬 개발에서 실제 순수 엔진에 합성 시세를 넣자 그 일이 재현됐다. 필수 장기 평균을 null로 주었는데도 해당 규칙의 available과 met가 모두 참이고, 가상 매수 한 건이 기록됐다.

누락된 등락률에서도 다른 반례가 나왔다. 합성 현재가 100과 등락값 2가 있고 등락률만 null인 입력은 기존 계산식으로 등락률을 파생할 수 있다. 그런데 누락값이 먼저 0으로 바뀌어 그 경로를 가리고, 상승률 조건이 알려진 0으로 평가됐다. 같은 원인이 한쪽에서는 잘못된 진입을 만들고 다른 쪽에서는 근거 있는 계산을 막았다.

실제 시장 자료를 받아 거래한 실험은 아니다. 선택한 원본 함수를 합성 입력으로 실행한 메모리 기록이다. 나는 이 결과를 앞서 쓴 상태 설명의 후속 근거로 남겼다. available이라는 이름을 붙였다는 사실보다, 그 값을 만드는 입력 해석이 무엇을 허용했는지까지 확인해야 했다.

실제 0은 남기고 모르는 값은 모르는 채로 두었다

첫 후속 수정에서 엔진 내부의 해석 함수는 유한한 숫자 또는 비어 있지 않은 숫자형 문자열만 받도록 바뀌었다. null과 누락, 빈 문자열, 불리언, 배열과 객체는 null로 남긴다. 실제 숫자 0과 문자열 0은 0이다. 수치가 없다는 이유로 0을 만들어 넣지 않는 것과, 실제로 관측한 0을 지워 버리지 않는 것을 함께 확인했다. 이 단계의 검사는 엔진에 직접 넣은 입력을 대상으로 했다.

등락률이 없으면 유효한 가격과 등락값을 사용한 기존 파생 계산으로 넘어간다. 그 근거마저 없으면 미확인이다. 필수 장기 평균이 없을 때는 원래 진입 규칙의 available과 met가 거짓이고 비율 근거도 null로 남도록 했다. 규칙을 충족했다고 보는 대신 입력이 부족한 상태로 가상 진입을 보류한다.

이 입력 계약을 저장 장부의 계약과 합치지는 않았다. 외부 시세의 숫자형 문자열은 명시적으로 해석할 수 있지만, 저장된 계산 필드는 이미 JSON 숫자여야 한다는 앞선 검사는 그대로다. 또 유한 숫자라는 확인은 각 필드의 업무상 범위를 보증하지 않는다. 명시적으로 들어온 0이나 음수가 장기 평균·거래량 같은 개별 필드에서 정상인지까지 이번 수정으로 검증했다고 말하지 않았다.

원제품의 22개 검사와 공유 예제의 22개 검사는 다르다

후속 개발은 기존 엔진·저장 장부 검사 16개에 시세 입력 검사 6개를 더해 22개를 통과했다. 잘못된 타입의 가격 거절, 장기 평균 누락, 등락률 파생과 실제 0, 정상 숫자형 문자열의 호환, 입력 보존과 공통 함수가 초기 자금 해석에 미치는 영향을 다뤘다. 기존 저장 로더와 장부 검사도 같은 회귀 안에서 유지했다.

격리 빌드를 확인하고 전후 소스 묶음을 실제로 풀어 12개 파일의 해시를 대조했다. 복구한 이전 소스에서는 16개, 수정 소스에서는 22개 검사가 통과했다. 보호 대상 29개 파일의 바이트와 수정 시각, 전체 33개 파일 목록도 유지됐다. 빌드는 같은 고정 의존성 목록을 가진 기존 별도 설치 환경을 재사용한 결과이며 새 컴퓨터의 첫 설치 검수는 아니다. 실행 중인 배포본이나 실제 브라우저 저장 자료를 교체하지 않았다.

당시 개정은 그 개발 기록과 현재 소스를 읽어 연결한 작업이며 원제품 검사를 다시 실행하지 않았다. 기존 공개 규칙 요약 ZIP은 별도로 다시 내려받아 바이트·해시를 확인하고 추출 폴더에서 합성 검사 22개를 실행했다. 이름도 개수도 비슷하지만 하나는 실제 엔진의 입력 경계, 다른 하나는 독립 요약 함수의 계약이다. 이어진 시장 입력 경로 수정의 30개 검사와도 시점과 대상이 다르다.

검사에 도착하기 전에 입력이 바뀌고 있었다

엔진에 잘못된 타입을 직접 넣어 거절되는지 확인한 뒤에도 한 질문이 남았다. 실제 호출자는 같은 값을 그대로 넘기는가. 다음 개발에서는 시장 응답을 정리하는 함수, 계산용 스냅샷을 만드는 함수와 실제 순수 엔진을 이어 읽었다. 앞의 두 구간에는 엔진의 타입 제한을 거치지 않은 숫자 변환이 남아 있었다.

합성 가격 [100]은 시장 응답 정리 과정에서 숫자 100이 됐고, 가격 true는 1이 됐다. 유효한 대체 등락값이 없는 등락률 true도 1로 바뀌었다. 각각의 반례는 실제 원본 순수 함수와 엔진을 거쳐 메모리 안에서 가상체결 한 건을 만들었다. 엔진에 도착했을 때는 이미 정상 숫자처럼 보여, 처음 입력이 배열이나 불리언이었다는 사실을 뒤에서 복구할 수 없었다.

이것은 현재 시장에서 발생한 체결이나 계좌 손실을 관측한 결과가 아니다. 의도적으로 만든 입력을 원본 계산 경로에 넣은 재현이다. 다만 한 함수의 거절 시험만으로 호출 경로까지 보호됐다고 판단할 수 없다는 근거는 됐다. 자료 유무를 표시하려면 그 표시를 만들기 전의 변환도 같은 질문으로 검사해야 했다.

같은 숫자 해석을 세 구간에 연결했다

새로운 숫자 정책을 하나 더 쓰는 대신, 앞서 고친 엔진 해석 함수의 본문을 그대로 공용 유틸리티로 옮겼다. 엔진, 시장 응답 정리와 스냅샷의 가격 선별·변환이 이 함수를 함께 사용하도록 연결했다. 잘못된 타입을 받아들인 뒤 엔진에서 추측해 되돌리는 방식보다, 원래 타입을 볼 수 있는 입구에서 계약을 적용하는 쪽을 택했다.

숫자를 해석할 수 있다는 확인과 체결용 가격으로 쓸 수 있다는 확인은 여전히 두 단계다. 실제 0과 문자열 0은 해석하면 0이다. 그러나 계산용 스냅샷은 양수 가격만 선별한다. 등락값 0을 누락으로 지우지 않는 일과 가격 0을 체결에 쓰지 않는 일은 함께 성립한다. 유한 숫자만 받는 함수에 모든 필드의 업무상 의미를 맡기지 않았다.

정상 숫자형 문자열을 받는 기존 계약도 유지했다. 비어 있지 않은 문자열을 숫자로 해석해 유한한 결과인지 확인하는 방식이며, 십진수 표기만 허용하는 새 문법 검사는 아니다. 개별 평균·거래량의 전체 경제적 범위나 서버에 있는 모든 정규화 함수를 이번 작업으로 통합했다고 말하지 않는다. 저장 원장의 계산 필드는 이미 JSON 숫자여야 한다는 별도 검사도 유지했다.

함수 연결 시험과 실제 화면 검수를 나눴다

새로 더한 여덟 검사 묶음은 공용 함수, 실제 시장 응답 정리 함수, 실제 스냅샷 함수와 엔진을 합성 입력으로 연결한다. 잘못된 가격의 거절, 다른 수치 필드의 미확인과 선언된 0, 양수 가격 선별을 대조했다. 유효한 등락 근거가 없는 불리언 등락률은 미확인으로 남고 가상체결도 생기지 않았다. 정상 숫자형 문자열은 예상한 가상체결 한 건을 만들었으며, 동결한 입력과 원본 시각·수집 시각도 유지됐다.

앞선 22개에 새 여덟 묶음을 더해 원제품 검사 30개가 통과했다. 별도 폴더의 빌드를 확인하고 전후 소스 ZIP을 실제 추출해 합계 17개 파일의 해시를 대조했다. 복구한 이전 소스에서는 22개, 수정 소스에서는 30개 검사가 통과했고 보호 대상 27개 파일의 바이트와 수정 시각을 보존했다. 이 수치는 직전 개발 기록이다. 이번 집필 차례에 원제품 시험을 다시 실행한 결과로 세지 않는다.

원본 hook 파일의 순수 함수를 분리해 실행했으며 React를 마운트하지 않았다. 실제 공급자 조회·계좌·브로커·브라우저 저장소나 실행 중인 배포본을 검사한 것도 아니다. 이번 개정에서는 기존 공개 요약 ZIP의 22개 합성 시험과 기록 선택기의 DOM 대역 검사만 다시 확인한다. 요약 코드는 그대로이고, 원제품의 available:false와 met:false를 Python의 met=None으로 옮기는 어댑터도 아직 구현하지 않았다.

다른 업무 프로그램도 같은 질문을 받을 수 있다

재고 자료가 안 와서 확인할 수 없는 발주와, 재고를 확인했지만 수량 조건이 안 맞는 발주는 다음 일이 다르다. 예산 자료를 받지 못한 상태와 예산을 검토해 초과했다고 판단한 상태도 다르다. 예제의 규칙 이름을 업무에 맞게 바꾸되 자료 유무, 조건 결과와 실제 실행 권한을 섞지 않는 계약은 유지할 수 있다.

처음에는 상태를 설명하는 독립 요약을 만들었고, 첫 후속 개발은 엔진 안의 입력 해석을, 다음 개발은 그 앞의 시장 응답과 스냅샷 경로를 고쳤다. 이번 개정은 그 순서를 현재 본문에 연결한 작업이다. 같은 상태 문구를 더 정교하게 쓰려면 문구가 참조하는 자료가 어디에서 어떤 값으로 바뀌는지도 함께 확인해야 한다. 실제 업체·계좌·원문 시세를 공개하지 않고도 다음 제작자가 점검할 경로와 남은 한계를 설명할 수 있었다.