20 KiB
S2_00 request 준비 계획 v1 — 필수 조건을 유지한 단순화
작성일: 2026-09-30. 상태: 분석·계획 작성 완료 / 구현 미착수. 원본: s2-00-request-preparation.md. 원본은 보존한다.
1. Occam's Razor 분석
기존 계획은 안전성에 필요한 항목과 선택적인 구현을 함께 필수화하여, 가장 단순한 계획이라고 보기는 어렵다. 같은 요구를 충족하면서 새 프로토콜·검증 중복·변경 범위를 줄일 수 있다. 다만 backend 기능이 미확정이므로 '절대적으로 가장 효율적'이라고 단정하지 않고, 확인된 코드와 사용자 제약 아래의 권고안을 제시한다. 여기서 효율성은 우선 구현·검증·유지보수 비용이며, 실행시간 개선 수치는 측정하지 않았다.
1.1 제약을 지키는 단순화와 구조 변경의 구분
| 대안 | 장점·비용 | 판단 |
|---|---|---|
| 원본의 독립 2-task + 준비 receipt 전달 | 별도 receipt schema·실행 envelope·후행 전달·task별 검증 필요 | 요청 identity 확인은 타당하지만 구체 수단을 줄일 수 있음 |
| 2-task + 동일한 불변 host 인자 공급 | 두 task가 같은 값으로 request를 재구성; 별도 준비 receipt 전달 불필요. 2-task 빌드 변경은 여전히 필요 | v1 채택: 기존 '선행 task 신설' 요구 유지 |
| 기존 단일 task 맨 앞의 준비 함수 | task 간 전달·실패 gate·2-task builder 변경을 제거할 수 있어 구조적으로 더 단순 | 독립 선행 task 요구를 완화하는 대안. v1에 몰래 적용하지 않음 |
| 외부 host에서 request 생성 | YAML 구조 변경이 작음 | 'YAML 맨 앞의 선행 task' 요구와 다르므로 기본안 제외 |
v1은 요청 목적을 바꾸지 않고 독립 선행 task를 유지한다. 단일 task 내부 함수 방식은 추가 구조를 가장 크게 줄이지만, 기존에 명시한 두-task 조건과 구별해야 한다.
1.2 줄일 수 있는 항목과 유지할 항목
| 원본 계획 | v1 결정 | 이유·적용 조건 |
|---|---|---|
| 신규 prepare receipt schema와 host→ingress receipt 전달 | 제거. host가 확정한 동일 네 인자를 두 task에 제공하고 ingress가 expected bytes를 재구성 | 별도 파생 자료를 전달하지 않아도 요청 일치 검증 가능. host 인자는 실행 중 불변이어야 함 |
| 새로운 execution envelope·lock token을 task마다 검증 | 별도 형식 신설 안 함. 기존 인증된 실행 context와 host 직렬화 사용 | 기존 기능의 실제 지원 여부부터 확인. 없는 기능을 있다고 가정하지 않음 |
| 검증한 bytes를 write/read-back한 뒤 동일 bytes를 다시 parse/schema 검사 | 반복 검사 제거 | 처음 검증한 canonical bytes와 read-back bytes의 완전 일치가 확인되면 같은 내용을 다시 검증할 필요 없음 |
| 선행 단계에서 schema/release closure 별도 hydration | 기본안에서 제외 | 이미 존재하는 폐쇄형 request validator와 schema의 일치를 offline test로 확인. ingress의 기존 release 검증은 유지 |
| 신규 분산 lock·lease·fencing 체계 가능성까지 초기 구현에 포함 | 기존 host 직렬화 재사용 우선, 별도 체계는 실제 미지원일 때만 재설계 | 잠금 안전성은 필수이나 새 잠금 서비스를 만드는 것이 필수는 아님 |
| 동일 attempt 재사용 최적화 | 초기 제외. 소유권 획득 후 전체 준비 작업 재실행 | 작은 JSON의 재쓰기보다 별도 재사용 분기의 관리 비용이 클 수 있음. 기존 결과 idempotency는 유지 |
| schema·manifest 전체 개정 | 실제 구조·hash 참조가 바뀌는 항목만 갱신 | 파일을 더 적게 수정하려고 필요한 hash/권한 갱신을 생략하지 않음 |
| 정확히 2 task·순서 및 두 code hash 검증 | 유지 | 현 builder가 1 task를 강제하므로 피할 수 없는 변경 |
| 저장 실패 시 차단·request 2회 읽기·host 직렬화 | 유지 | 요구된 실행 안전성. bytes 비교는 상호 배제를 대신하지 않음 |
특히 runtime의 write_binary_verified()에는 이미 write 후 read-back bytes 비교가 있다. 같은 일을 하는 새 IO 계층을 만들 필요가 없다. _inline_validate_request()도 이미 정확히 6필드·ID·경로 검증을 수행한다. 근거는 아래 Evidence Ledger에 기록한다.
Objective
IN → Task_S2_00_prepare_request → Task_S2_00_deterministic_ingress → OUT을 구현하되, 새 준비 receipt 전달 프로토콜 없이 동일한 외부 인자와 기존 검증·IO 기능으로 request 생성 및 소비를 연결한다.
Deliverables
- 기존 authoring을 정본으로 하는 2-task YAML·파생 배포본 및 필요한 code mirror/빌드 receipt 변경.
- 최소 준비 함수, ingress의 expected request bytes 대조, 외부 인자·직렬화·success-only 계약.
- 실제 변경된 binding·schema·manifest/hash, 관련 시험 및 분석·IO 문서 개정.
Scope and Non-Scope
request의 6필드·고정 경로와 기존 ingress의 C00–C15·출력 계약을 유지한다. 신규 receipt 파일·범용 workflow framework·독립 lock 서비스·release 전체 재설계는 기본 범위에 넣지 않는다. 기존 DEV release 제한과 core 결함 수정은 별개다. 이 문서는 구현 계획이며 실행 자산을 변경하지 않는다.
Known Inputs
M = Case_02_Comparison_Research/YAML_Prompts/2. Stage_2/, R = M/Default_Agent/Stage_2_Clean/, W = 인증된 localdocs workspace.
현재 authoring은 M/Stage_2_S2_00_v.2.yml, 배포본은 R/agent_scripts/Stage_2_S2_00.yml이다. 빌더는 1 task·1 code pointer를 전제로 하고, S2_00 binding은 결과 root만 쓰기 허용한다. request writer를 추가하려면 이 두 계약 변경은 불가피하다. backend의 실제 인자 전달·직렬화 구현은 UNVERIFIED다.
Material Assumptions
- host가 권한을 확인한 네 인자를 실행 시작 때 확정하고 두 task에 동일하게 공급할 수 있어야 한다. YAML 문법·환경변수 이름·run_code parameter를 임의로 발명하지 않는다.
- 같은
(user, workspace)의 S2_00 실행은 host가 전역 직렬화한다. 단일 worker의 로컬 mutex만으로 다중 worker 안전성을 주장하지 않는다. - task 간 메모리 공유는 가정하지 않는다. request bytes는 각 task가 동일한 규칙으로 재구성한다.
- 동일한 bytes의 request가 남아 있다는 사실만으로 prepare 성공을 대신하지 않는다. 현재 host 실행에서 prepare 성공 판정이 먼저 있어야 한다.
Questions That Could Change the Outcome
구현 전에 세 가지만 먼저 확인한다: ① 동일 불변 인자를 두 task에 공급하는 실제 방식, ② exit code와 task 결과에 따른 success-only 후행 실행, ③ 취소·worker 장애·진행 중 I/O까지 포함한 workspace 직렬화. 세 조건이 지원되면 아래 최소안을 진행한다. 미지원이면 필요한 backend 보강을 명시하며, receipt나 lock 파일을 추가하는 것으로 문제가 해결되었다고 간주하지 않는다. 기존 지원만으로 가능하다는 현재의 실증 근거는 없다.
Workstreams and Dependencies
1단계 — 외부 입력과 host 경계 확정
외부에서 공급하는 값은 다음 네 문자열이다.
| 필드 | 검증 |
|---|---|
request_id |
[A-Za-z0-9][A-Za-z0-9._-]{0,127} |
attempt_id |
위와 동일; host 재시도 정책으로 결정 |
stage1_run_root_ref |
W 아래 승인된 Stage 1 사건 root의 NFC canonical 상대경로 |
stage1_deployment_root_ref |
W 아래 승인된 Stage 1 배포 root의 NFC canonical 상대경로 |
준비 task가 schema_version=stage2_s2_00_execution_request.v1, workflow_id=S2_00을 추가하여 정확히 6필드를 만든다. 누락·추가 외부 키와 잘못된 타입을 거절한다. 기존 path validator로 absolute path·..·역슬래시·NUL·비정규 경로를 거절하고, 접근 권한과 Stage 1 run 선택은 host가 결속한다. shell/Python source에 원문 인자를 직접 삽입하지 않는다.
host는 준비 task 시작 전 실행 소유권을 획득하여 S2_00 전체 종료 및 미완료 I/O 종료까지 유지한다. 이는 hydration 완료까지의 최소 보호 요구를 충족한다. 중간 해제 callback은 추가하지 않는다. 모든 writer·retry가 같은 통제에 참여해야 하며, 종료 여부가 불명확한 경우 다음 실행을 보류한다. TTL 만료만으로 takeover하지 않는다. host에 이 보장이 없으면 live-ready로 판정하지 않는다.
2단계 — 최소 준비 함수와 ingress 비교 구현
아래는 의미를 설명하는 pseudocode이며 현재 실행 가능한 API가 아니다.
# 양쪽 task에 host가 동일하게 공급한 네 값
expected = build_request(immutable_host_args) # 두 상수 추가, 정확한 외부 키 확인
expected_raw = canonical_json_bytes(expected)
_inline_validate_request(expected_raw)
# prepare task: 인증된 localdocs 세션 및 host 실행 소유권 아래 수행
localdocs.write_binary_verified(INLINE_REQUEST_PATH, expected_raw)
# 세션 종료까지 성공한 후 task 성공을 반환한다.
# ingress task: 현재 실행의 host_args로 expected_raw를 독립 재구성
actual_raw = localdocs.read_binary(INLINE_REQUEST_PATH) # 기존 첫 읽기에 통합
if actual_raw != expected_raw:
raise IngressError("RUN_REQUEST_INPUT_MISMATCH", "request differs from host input")
# 이후 기존 strict validation 및 2회 읽기/hydration을 계속한다.
build_request는 네 값에 두 상수를 추가하는 작은 함수로 제한한다. 별도의 범용 serializer나 validator framework를 만들지 않는다.- prepare는 기존 validator·canonical serializer·MCP IO helper의 동작을 재사용한다. 두 독립 inline payload에 필요한 helper는 authoring/build 시 포함한다. 외부
.pyruntime import나 ingress 전체 실행 코드를 복제해 실행하는 방식은 피한다. 중복 포함된 helper의 일치는 좁은 parity 검사로 확인하며 새 공통 모듈 배포 체계까지 만들지 않는다. write_binary_verified가 bytes 일치를 확인하므로 추가 read-back/parse를 중복 수행하지 않는다. task 성공 결과에는 backend가 요구하는 최소ok/error만 사용하며 새 버전 receipt schema·추가 파일은 만들지 않는다.- ingress의 expected bytes 검사는 기존 첫 request 읽기에 결합한다. 이미 첫 읽기가 expected와 같고 두 번째가 첫 번째와 같은지 검사하므로 두 번째에서 동일한 expected hash를 다시 계산할 필요는 없다.
- 이 대조는 request ID만이 아니라 여섯 필드 전체를 확인한다. 서로 다른 요청으로 두 pass 모두 교체되더라도 거절한다. 다만 상호 배제는 여전히 host 책임이다.
- 실패 시 준비 작업 전체를 다시 실행한다. 남아 있는 파일을 신뢰해 ingress만 우회 실행하지 않는다. 정리 목적으로 request를 무조건 삭제하지 않는다.
3단계 — 두 task의 실행 순서와 실패 차단
host: 동일 workspace 실행 소유권 확보, 네 인자 확정
→ IN
→ prepare: 검증 → 저장/read-back → 세션 종료 → 성공
→ host: 현재 실행의 prepare 성공일 때만 ingress 시작
→ ingress: expected bytes 일치 → 기존 2회 읽기/hydration → 기존 core/발행
→ OUT 또는 실패 정리
→ host: task와 미완료 I/O 종료 확인 후 소유권 해제
YAML의 nexts/wait_until은 위 순서를 정확히 기술한다. transport 응답 성공만으로 업무 성공을 판정하지 않는다. exit code 및 backend가 해석하는 task 결과에서 실패·잘못된 결과·timeout이면 ingress를 호출하지 않는다. 후행에 준비 receipt를 전달할 필요는 없지만, host의 task 성공 판정 자체는 생략할 수 없다. 직접 ingress 호출은 host admission으로 차단한다.
4단계 — 실제 영향 범위만 빌드·배포 갱신
| 항목 | 최소 변경 |
|---|---|
M/Stage_2_S2_00_v.2.yml |
prepare task와 지정 DAG, ingress expected bytes 검사 추가 |
R/offline_build/build_s2_00_inline_projection.py/.txt |
정확히 두 task를 ID로 추출·검증. 0번 task가 ingress라는 가정 제거. 공통 코드 검사와 task별 필수 검사 분리 |
R/agent_scripts/Stage_2_S2_00.yml, runtime mirror, R/manifest/s2_00_inline_code_receipt.json |
기존 파생 절차로 재생성. 두 code pointer/hash를 결속. 별도 runtime 준비 receipt와 혼동하지 않음 |
| prepare code mirror | 기존 mirror 정책을 유지하는 데 필요한 runtime/s2_00_prepare_request.py/.txt만 파생 생성. 새로운 독립 서비스는 아님 |
| workflow 및 executor binding | 외부 네 인자, success-only, 직렬화 책임과 prepare의 정확한 request 쓰기 경로 추가. ingress의 결과 root 쓰기 범위 유지 |
| 관련 schema | 2-task binding/빌드 receipt 표현이 바뀌어 기존 schema와 충돌하는 부분만 수정. 기존 execution_request의 6필드 schema는 유지 |
| module/release·code pin·Agent/workflow hash | 실제 변경 자산 및 이를 참조하는 hash만 재결속. 순환 결속을 새로 만들지 않고 기존 detached 절차 유지 |
| 기존 분석서·IO 문서 | 구현 완료 후 실제 두-task 구조, 인자 및 request 저장 시점을 반영 |
스키마를 안 바꾼다는 이유로 필요한 code hash를 누락하거나, 단순화를 이유로 기존 검증기를 무력화하지 않는다. 두 task 구성이 요구되는 한 builder·mirror·권한·hash 비용은 남는다. 별도의 준비 receipt schema와 전달 소비자만 제거하는 것이다. 빌드 재실행 시 동일 bytes인지 확인한다.
5단계 — 필요한 시험과 완료 판정
아래 Validation Plan을 실행하여 기준선에 있던 실패와 이번 변경의 회귀를 구분한다. host 지원 여부가 불확실하면 offline 구현·시험과 실제 운영 적격성을 별도로 보고한다. DEV guard를 해제해서 성공 결과를 만들지 않는다.
Source and Tool Plan
원본 계획, 현재 authoring/runtime/builder/binding을 우선 근거로 삼는다. 외부 제품 권고나 일반론이 아닌 로컬 코드의 중복·의존성을 분석한다. 구현 시 backend 코드·문서로 세 선행 조건을 확인하고 기존 테스트 runner 및 빌드 --check를 사용한다. 실제 backend 통합 시험은 격리된 fixture 환경에서 수행한다.
Validation Plan
| 시험 묶음 | 통과 기준 |
|---|---|
| 정상·잘못된 외부 입력 | 정상은 정확한 6필드 canonical bytes; 누락/추가/ID/path/type 오류는 저장 전 거절. 기존 request schema와 validator 수용 범위 일치 |
| 저장·read-back·종료 실패 | 후행 ingress 호출 0회. ok:false·비정상 exit·잘못된 성공 결과도 차단 |
| request 교체·잘못된 host 입력 결속 | 첫 읽기의 전체 bytes 대조 및 기존 두 pass 비교로 거절. stale request·다른 attempt·다른 roots 포함 |
| 경쟁·취소·재시도 | 같은 workspace의 두 worker는 직렬 실행; 이전 writer/I/O가 남은 동안 다음 실행 금지. 다른 workspace는 독립 실행 |
| 2-task 빌드·회귀 | 지정 두 task/순서만 허용, code/mirror/receipt/hash 일치, 반복 빌드 동일. 기존 정상 11+E/diagnostic 5파일 fixture 계약 유지 |
| backend 통합 | 동일 불변 인자 공급, success-only 실행, 전역 직렬화·권한 강제가 실제 작동 |
별도 준비 receipt, TTL/fencing 프로토콜, 재사용 최적화를 만들지 않으므로 이들의 전용 시험도 만들지 않는다. 단, worker 장애 이후 교차 쓰기가 없다는 기능 시험은 필수로 남는다. 신규 기능의 fixture 회귀와 실제 MCP/backend 실행 증거를 구분한다.
Approval Boundaries
이번 요청 범위는 분석과 v1 계획 파일 작성이다. 원본 계획과 실행 자산을 보존한다. 이 문서 작성만으로 구현·배포·live 검증을 수행한 것으로 표현하지 않는다.
Progress
- 원본 계획과 현재 validator·IO·builder·binding 대조
- 제약 유지안과 제약 완화 대안 구별
- 중복 프로토콜·검증·최적화 제거 및 v1 작성
- backend 세 조건 확인
- 준비 task·ingress·빌드/배포 계약 구현
- 회귀·경쟁·backend 통합 검증 및 문서 갱신
Decision Log
| 결정 | 근거·효과 |
|---|---|
| 독립 선행 task 유지 | 앞선 사용자 요구를 바꾸지 않음. 절대 최소 구조와 제약 내 최소안을 구분 |
| 동일 host 인자로 expected bytes 재구성 | 별도 준비 receipt·schema·전달을 제거하면서 전체 request 일치 검증 유지 |
| 기존 verified write/validator 재사용 | 현재 존재하는 동작을 새 계층으로 중복 구현하지 않음 |
| 전체 실행 직렬화 유지 | 중간 해제 신호보다 구현이 단순함. 동일 workspace 처리량 최적화는 이번 목표에서 제외 |
| 조건부 backend 확인 | 미확정 host 기능을 기정사실로 삼는 것이 가장 큰 숨은 복잡성이므로 먼저 검증 |
Evidence Ledger
행번호는 2026-09-30 확인본 기준이다. runtime mirror를 구현 대조 자료로 사용했으며 authoring의 정본 지위를 바꾸지 않는다.
| 분석 명제 | 현재 확인 근거 | 판정 |
|---|---|---|
| 중복 없는 writer/validator 재사용 가능 | R/runtime/s2_00_ingress.py의 write_binary_verified(5492행), _inline_validate_request(5505행) |
write/read-back 및 6필드 검증 존재 확인 |
| ingress 첫 읽기에 expected 대조 추가 가능 | 같은 runtime _inline_hydrate(5712행 이후) |
기존 첫 읽기 및 검증 순서 확인; 변경은 제안 |
| 2-task 빌드 변경은 생략 불가 | R/offline_build/build_s2_00_inline_projection.py: 326–378 |
단일 task·DAG 제약 확인 |
| 준비 receipt 제거의 전제 | 두 task가 동일한 인증된 불변 host 입력을 받는다는 새 계약 | 설계 제안; backend 실제 지원 UNVERIFIED |
| request 쓰기 권한 추가 필요 | R/deployment/stage2_code_executor_binding.yml: 47–66 |
기존 write root는 결과 폴더 |
Risks and Failure Modes
직렬화가 실제로 보장되지 않으면 receipt를 제거하든 유지하든 고정 request 경로의 안전한 실행은 완성되지 않는다. task별 입력이 서로 다르거나 조작될 수 있다면 expected bytes 방식의 전제가 무너진다. 이 경우 host 입력 결속을 먼저 수정해야 한다. 인증된 인자·권한·잠금은 JSON을 단순하게 만드는 것과 별개의 필수 조건이다.
실패한 변경의 롤백은 진행 중 실행과 I/O 종료 후 검증된 기존 authoring·배포본·mirror·binding/hash 묶음으로 복원한다. 사건 자료·발행 결과는 삭제하지 않는다. 기존 버전도 request 외부 공급이 필요하므로 롤백이 자동 정상화를 뜻하지 않는다.
Results and Residual Uncertainty
기존 계획은 단순화할 수 있다. v1은 두-task 요구를 유지하면서 신규 준비 receipt/전달 schema·독립 실행 envelope 설계·중복 read-back 검증·불필요한 사전 closure 읽기·재사용 최적화를 기본 범위에서 제거했다. 필수 인자 검증·저장 확인·후행 차단·동일 요청 소비·동시 실행 통제·hash 일치는 유지했다. 이는 코드 근거에 따른 설계 평가이며 성능 벤치마크 결과가 아니다. backend 세 조건의 실제 지원과 구현 완료 여부는 미확정·미착수다.