자료 확인이 끝나기 전에 홈페이지를 계속 다듬어야 할 때가 있다. 그때 대기 중인 자료를 잠시 숨겨 미리보기를 이어가는 일과, 대기를 없애 운영 준비가 끝났다고 처리하는 일은 다르다. 원래 제작 기록의 세 가지 상태 규칙을 참고해, 선언한 상태만 계산하는 새 Python 모듈을 만들었다.
입력은 ID와 상태의 목록, 그리고 preview 또는 release 모드다. 결과는 표시할 ID, 제공하지 않기로 선언한 ID, 확인 대기 ID와 이 상태 조건에서 빌드를 허용하는지다. 실제 파일을 찾거나 사실을 판단하는 AI가 들어 있지 않다. 코드와 설명, 합성 예제와 실행 검사를 한 묶음으로 내려받을 수 있게 했다.
입력 계약을 작게 두고 뜻은 그대로 남긴다
최상위 JSON에는 features와 mode 두 키만 둔다. 각 항목에는 id와 state만 넣으며 상태는 confirmed, absent, pending 중 하나다. 같은 ID가 두 번 나오면 어떤 선언을 채택할지 추측하지 않고 입력 오류로 돌려준다. 알 수 없는 상태나 여분의 필드도 그대로 통과시키지 않는다. 다른 자료 형식을 쓴다면 이 작은 계약으로 바꾸는 연결을 명시적으로 작성한다.
ID는 비어 있지 않은 문자열이고 최대 백이십 글자다. 항목은 최대 천 개, CLI 입력은 최대 1 MiB로 제한했다. 이것은 인터넷 요청을 받는 서버의 보안 구성이나 고객 데이터를 익명화하는 기능이 아니다. 입력 ID를 출력에도 남기므로 공개 예제에는 실제 고객 식별자를 넣지 않는다.
숨김 결과 안에서도 없음과 대기를 나눈다
confirmed 항목은 visible에, absent는 declared_absent에, pending은 pending에 남긴다. hidden에는 제공하지 않는 항목 다음에 대기 항목이 들어가며 각 그룹 안에서는 원래 순서를 보존한다. 화면에 숨긴다는 공통 결과가 있어도 대기 상태를 없음으로 바꾸지 않는다. 입력 목록 자체도 수정하지 않는다.
preview에서는 대기가 있어도 이 조건을 통과하고, release에서는 대기가 하나라도 있으면 can_build가 false다. 명시적으로 빈 목록을 넣으면 이 상태 조건은 통과한다. 그것이 빈 홈페이지나 전체 운영 준비를 승인한다는 뜻은 아니다. 다른 필수 자료와 설정 검사는 그대로 남겨야 한다.
소스 코드와 실제 실행 방법
아래 코드는 공유 ZIP의 feature_states.py와 같은 새 코드다. Python 표준 라이브러리만 사용하며 네트워크 호출, 파일 탐색, HTML 수정이나 발행 요청을 하지 않는다. 기능을 다른 프로그램에서 쓰려면 evaluate_features를 가져오고, CLI로 쓰려면 JSON을 표준 입력으로 전달한다. 원래 고객 템플릿의 프로그램을 배포한 것이 아니다.
압축을 푼 폴더에서 python feature_states.py < example-input.json으로 예제를 실행하고 python checks.py로 포함 검사를 실행한다. 종료 코드 0은 해당 모드의 상태 조건을 통과, 1은 운영 모드에서 대기가 남음, 2는 입력 계약 오류다. 실행을 자동화할 때는 출력 문장만 찾지 말고 종료 코드와 반환 상태를 함께 읽는다.
코드와 구현 살펴보기
새 독립 Python CLI · 선언한 상태만 계산
"""Pure declared-state gate. No discovery, rendering, storage or publication."""
import json,sys
MAX_FEATURES=1000
def evaluate_features(features,mode):
if mode not in ('preview','release'):raise ValueError('mode must be preview or release')
if not isinstance(features,list) or len(features)>MAX_FEATURES:raise ValueError('features must be a list of at most 1000 items')
visible=[];absent=[];pending=[];seen=set()
for row in features:
if not isinstance(row,dict) or set(row)!={'id','state'}:raise ValueError('each feature needs exactly id and state')
ident=row['id'];state=row['state']
if not isinstance(ident,str) or not ident.strip() or len(ident)>120 or ident in seen:raise ValueError('feature IDs must be unique nonempty strings of at most 120 characters')
if not isinstance(state,str) or state not in ('confirmed','absent','pending'):raise ValueError('unknown feature state')
seen.add(ident)
{'confirmed':visible,'absent':absent,'pending':pending}[state].append(ident)
return {'mode':mode,'visible':visible,'declared_absent':absent,'pending':pending,'hidden':absent+pending,'can_build':mode=='preview' or not pending,'scope':'declared states only; no asset/source/rights/operating-site validation'}
def unique_object(pairs):
result={}
for key,value in pairs:
if key in result:raise ValueError('duplicate JSON key')
result[key]=value
return result
def main():
try:
raw=sys.stdin.buffer.read(1024*1024+1)
if len(raw)>1024*1024:raise ValueError('input exceeds 1 MiB')
value=json.loads(raw,object_pairs_hook=unique_object)
if not isinstance(value,dict) or set(value)!={'features','mode'}:raise ValueError('root needs exactly features and mode')
result=evaluate_features(value['features'],value['mode'])
except (ValueError,TypeError,RecursionError,UnicodeError):
print(json.dumps({'error':'invalid feature-state contract'}));return 2
print(json.dumps(result,ensure_ascii=False));return 0 if result['can_build'] else 1
if __name__=='__main__':raise SystemExit(main())
중복 JSON 키를 조용히 덮어쓰지 않는다
JSON 객체 안에 같은 키를 두 번 적으면 마지막 값만 읽는 구현에서는 pending이 confirmed로 바뀐 것처럼 처리될 수 있다. 이 CLI는 입력을 읽을 때 중복 키를 발견하면 오류로 돌려준다. 최상위 features 중복과 개별 state 중복을 실제 프로세스로 확인했다. 선언의 충돌을 입력 단계에서 숨기지 않으려는 선택이다.
잘못된 구조, 너무 큰 입력과 깊게 중첩된 입력도 일반 입력 오류로 처리한다. 오류 출력에 원래 자료를 그대로 복사하지 않는다. 다만 정상 출력에 담긴 ID는 그대로 유지하므로, 이 장치를 개인정보 필터라고 설명해서는 안 된다. 프로그램이 검사하는 경계와 호출자가 지켜야 할 경계가 각각 있다.
원하는 사이트에 연결할 때 더 해야 할 일
실제 메뉴를 숨기고 페이지와 사이트맵을 맞추려면 별도 렌더러를 연결해야 한다. confirmed의 근거가 되는 파일과 사실, 권한과 최신성도 이 프로그램 밖에서 확인한다. absent는 표시할 자료에 대한 선언이며 현실의 시설이나 사업 관계가 없다는 증명이 아니다. 상태 조건이 통과했다고 다른 출시 검사를 생략하지 않는다.
이번 검사 스물네 개는 합성 상태 목록과 분리된 CLI 프로세스를 사용했다. 기존 고객 사이트, VR 실행이나 예약 접수, 이메일 수신을 검증한 결과는 아니다. 나는 재사용할 책임을 작게 잘라 확인 범위를 분명하게 두었다. 독자는 같은 계약을 자신의 메뉴 구조에 연결하고 그 연결 부분을 따로 검사할 수 있다.