263 lines
23 KiB
Markdown
263 lines
23 KiB
Markdown
# S2_00 request 생성·검증·저장 선행 task 신설 계획
|
||
|
||
## Objective
|
||
|
||
`Stage_2_S2_00.yml`의 맨 앞에 `Task_S2_00_prepare_request`를 신설하여 외부 실행 인자를 검증하고 `stage2_control/s2_00_request.json`을 저장·read-back한 뒤, 성공한 동일 실행만 기존 `Task_S2_00_deterministic_ingress`로 진행하도록 한다. workspace 단위 동시 실행 통제, 두 task 간 request identity 결속, 빌드·배포·hash 계약 갱신을 하나의 변경으로 다룬다.
|
||
|
||
작성일: 2026-09-30. 상태: **구현 전 계획**. 이 문서 작성 과정에서는 실행 YAML·runtime·배포 자산을 변경하지 않았다.
|
||
|
||
## Deliverables
|
||
|
||
| 산출물 | 내용 |
|
||
|---|---|
|
||
| 외부 실행 인자·host 계약 | 인자 전달 방식, workspace 권한·경로 결속, 직렬화, task 실패 차단, receipt 전달 |
|
||
| 2-task authoring 및 배포 YAML | prepare → ingress 순서와 success-only 실행 |
|
||
| prepare 구현 및 runtime mirror | 입력 검증, request 생성, write/read-back, 준비 receipt |
|
||
| ingress 보강 | host가 전달한 준비 receipt의 request hash·실행 identity와 실제 입력 대조 |
|
||
| workflow/schema/binding/builder 갱신 | task별 쓰기 권한, 2-task 추출·검증·receipt·mirror 계약 |
|
||
| 회귀·통합 검증 증거 | mock, 동시 실행, 실제 backend를 구분한 결과 |
|
||
| 분석·IO 문서 개정 | 새로운 선행 단계, 외부 인자 및 실패·잠금 수명 반영 |
|
||
|
||
## Scope and Non-Scope
|
||
|
||
- 범위: request 준비와 기존 ingress를 연결하는 구조 및 이를 배포 가능한 상태로 검증하는 데 필요한 계약 변경.
|
||
- 유지: request 파일의 기존 6필드, 고정 경로, 기존 C00/C05/C10/C15의 업무 책임, 정상/diagnostic 산출물 집합.
|
||
- 제외: Stage 1 사건 데이터 수정, S2_10 이후 업무 로직 변경, 기존 DEV release의 자동 production 승격, 기존 보존·projection 결함의 일괄 수정.
|
||
- 계획 작성이 구현 또는 live 배포 승인을 뜻하지 않는다. 실행 제한 해제는 request 생성 구현과 별개의 작업이다.
|
||
|
||
## Known Inputs
|
||
|
||
`M = Case_02_Comparison_Research/YAML_Prompts/2. Stage_2/`, `R = M/Default_Agent/Stage_2_Clean/`, `W = localdocs가 결속한 논리 workspace root`.
|
||
|
||
| 확인한 현 상태 | 근거 |
|
||
|---|---|
|
||
| 현재 IN → ingress → OUT, 단일 task | `R/agent_scripts/Stage_2_S2_00.yml`: 17–43, 6230–6248 |
|
||
| request는 읽기 입력이며 6필드 폐쇄형 검증 | 같은 YAML: 5548–5591, 5757 이후 |
|
||
| 입력 closure를 두 번 읽고 bytes 비교 후 temp hydration | 같은 YAML: 5825–5893 |
|
||
| 빌더가 정확히 1 task·1 run_code·고정 DAG를 강제 | `R/offline_build/build_s2_00_inline_projection.py`: 283–378 |
|
||
| authoring 정본은 `M/Stage_2_S2_00_v.2.yml`; 배포 YAML과 mirror는 파생본 | 같은 builder: 30–38, 680–755 |
|
||
| 단일 code pointer와 code hash·mirror를 receipt에 기록 | 같은 builder: 680–755 |
|
||
| 현재 S2_00 쓰기 root는 `stage2_runs/by-binding/<run_binding_digest>/` | `R/deployment/stage2_code_executor_binding.yml`: 47–66 |
|
||
| localdocs 계약상 허용 도구는 read_binary_doc/write_binary_file | 같은 binding: 47–66. CAS·분산 잠금 기능이 있다는 근거는 없음 |
|
||
| 외부 인자 주입 및 성공 receipt의 task 간 전달에 필요한 backend 구체 API | 현재 확인 범위에서 미확정. 구현 1단계에서 확인해야 함 |
|
||
|
||
사용자 지정 기존 분석 자료: [Stage_2_00_Analysis_v1.md](../YAML_Prompts/2.%20Stage_2/Stage_2_00_Analysis_v1.md), [Stage_2_00_IO_info.md](../YAML_Prompts/2.%20Stage_2/Stage_2_00_IO_info.md).
|
||
|
||
## Material Assumptions
|
||
|
||
1. request는 LLM이 추론하거나 폴더를 scan해서 만드는 값이 아니다. host가 확정한 네 값과 코드상 두 상수로 생성한다.
|
||
2. task 프로세스·임시 디렉터리·메모리는 서로 공유된다고 가정하지 않는다. backend가 인증된 실행 context와 선행 receipt를 후행 task에 전달해야 한다.
|
||
3. `wait_until`은 실행 순서를 기술하지만, 실패한 선행 task의 후속 실행까지 자동 차단한다는 보장은 별도로 검증한다.
|
||
4. 파일 읽기→없으면 lock 파일 쓰기는 원자적 잠금이 아니다. read-back·hash 비교도 상호 배제를 대신하지 않는다.
|
||
5. 권고 기본안은 **host가 같은 user/workspace의 전체 S2_00 실행을 직렬화**하는 것이다. 최소 요구 구간인 request 저장 전부터 hydration 완료까지보다 길게 잠금을 유지하여, 초기 구현에서 중간 해제 프로토콜을 추가하지 않는다.
|
||
|
||
## Questions That Could Change the Outcome
|
||
|
||
구현 착수 시 아래를 backend 문서·코드·시험으로 먼저 확인한다. 답을 추측해 YAML 문법이나 도구 기능을 만들지 않는다.
|
||
|
||
| 확인 사항 | 결정 기준·미지원 시 처리 |
|
||
|---|---|
|
||
| 외부 structured 인자 전달 방식 | 실제 지원하는 executor 입력 채널 사용. 고정된 템플릿 문법·미지원 run_code parameter를 임의 추가하지 않음 |
|
||
| 선행 stdout receipt를 후행 입력으로 전달하는 방식 | backend가 실행 identity에 결속해 전달해야 함. 동일 고정 파일에 별도 receipt를 쓴다는 방식만으로 신뢰 경계를 대신하지 않음 |
|
||
| task 성공 판정 | transport 성공뿐 아니라 exit code·receipt schema·ok·실행 ID 일치 확인 가능해야 함 |
|
||
| workspace 직렬화와 취소·worker 종료 보장 | 여러 backend worker에 걸친 전역 보장 필요. 한 프로세스의 mutex만 있으면 불충분 |
|
||
| 저장 권한 강제 | prepare에 정확한 request 경로만 쓰기 허용; ingress 결과 쓰기 권한과 분리 가능한지 확인 |
|
||
|
||
미지원 항목이 있으면 해당 backend 기능을 선행 구현 대상으로 기록한다. 로컬/mock 작업은 계속할 수 있으나 backend 증거 없이 live-ready로 표시하지 않는다.
|
||
|
||
## Workstreams and Dependencies
|
||
|
||
### 1. 기준선 및 변경 영향 확정
|
||
|
||
- 관련 authoring·배포 YAML, runtime mirror, workflow, schema, binding, builder·tests의 hash와 Git 변경 상태를 기록한다. 기존 사용자 변경은 보존한다.
|
||
- 문자열뿐 아니라 task ID·code pointer·code hash를 참조하는 소비자를 찾아 변경 목록을 닫는다.
|
||
- 기존 검사 결과를 기준선으로 기록하여 이번 변경의 회귀와 기존 실패를 구분한다.
|
||
- 위 backend 확인 사항을 검증하고 실제 인자·receipt 주입 방식 및 잠금 구현 위치를 확정한다.
|
||
|
||
완료 기준: 정확한 변경 파일 목록, backend 연동 계약, 기존 실패 목록이 기록되어야 한다.
|
||
|
||
### 2. 외부 인자 및 request 계약 확정
|
||
|
||
request 출력은 다음 6필드로 고정한다.
|
||
|
||
| 필드 | 공급자·형식 | 검증 |
|
||
|---|---|---|
|
||
| `schema_version` | prepare 코드 상수 | `stage2_s2_00_execution_request.v1` |
|
||
| `workflow_id` | prepare 코드 상수 | `S2_00` |
|
||
| `request_id` | host 문자열 | `[A-Za-z0-9][A-Za-z0-9._-]{0,127}` |
|
||
| `attempt_id` | host 문자열 | 위와 동일. 재시도 정책에 따라 새 시도 식별자 부여 |
|
||
| `stage1_run_root_ref` | host 문자열 | W 아래 승인된 Stage 1 사건 root에 결속한 canonical 상대경로 |
|
||
| `stage1_deployment_root_ref` | host 문자열 | W 아래 승인된 Stage 1 배포 root에 결속한 canonical 상대경로 |
|
||
|
||
- 누락·추가 필드, 빈 값, 잘못된 타입, absolute path, `..`, 역슬래시, NUL, 비정규 NFC 경로 등을 거절한다. 기존 `_inline_relative_path`와 검증 의미를 맞춘다.
|
||
- 문법적으로 올바른 경로라는 사실과 해당 실행이 접근할 권한이 있다는 사실을 구별한다. host가 승인한 user/workspace 및 Stage 1 완료 실행과 두 root를 결속한다.
|
||
- request 값은 다른 업무 run에서 남은 파일, 작업 디렉터리 추측, LLM 판단으로 채우지 않는다.
|
||
- user/workspace·host execution ID·lock ownership·준비 receipt는 별도의 실행 envelope에 담는다. 기존 request JSON에 7번째 필드를 추가하지 않는다.
|
||
- structured 전달을 우선한다. 코드 템플릿에 전달해야 하는 환경이라면 검증된 직렬화·안전한 encoding을 사용하고, 입력 문자열을 Python source에 직접 삽입하지 않는다.
|
||
|
||
완료 기준: 허용·거절 예제와 인자 전달 계약이 양쪽 task 및 backend 검증에서 일치한다.
|
||
|
||
### 3. host 직렬화 및 실패 수명 구현
|
||
|
||
잠금 key는 인증된 `(user, workspace, S2_00 request 고정 경로)`로 정한다. 서로 다른 request_id라도 동일 workspace의 고정 파일을 공유하면 같은 key를 사용한다.
|
||
|
||
```text
|
||
host admission → workspace 실행 소유권 획득
|
||
→ prepare 시작 → request 저장/read-back
|
||
→ 성공 receipt를 동일 실행 ingress에 전달
|
||
→ ingress request 1차/2차 읽기 → temp hydration
|
||
→ core 실행·원격 출력 발행 → 종료/취소 정리
|
||
→ 두 task와 미완료 I/O의 종료 확인 → 소유권 해제
|
||
```
|
||
|
||
- 기본안은 전체 S2_00 종료까지 직렬화한다. 따라서 최소 보호 구간인 hydration 완료까지는 확실히 포함된다.
|
||
- prepare에서 획득한 프로세스 로컬 lock을 task 종료 때 해제하는 구조는 금지한다. 소유권은 host 실행 전체에 귀속된다.
|
||
- 모든 request writer와 재시도 경로가 같은 통제에 참여해야 한다. 통제 밖 writer는 권한으로 차단한다.
|
||
- timeout·취소·host 재시작 시 오래된 worker와 진행 중 쓰기가 끝났는지 확인한 후 다음 실행을 허용한다. TTL 만료만으로 새 소유자를 실행하지 않는다.
|
||
- lease 방식이 불가피하다면 stale owner의 쓰기/읽기를 실제로 거절하는 fencing 또는 동등한 host 보장을 구현한다. JSON에 token만 넣는 것은 fencing이 아니다.
|
||
- 이후 성능 최적화로 hydration 직후 해제하려면 authenticated hydration-complete 신호, 이후 request 재읽기 없음, 원본 Stage 1 run의 불변성 등을 별도 입증한다. 초기 버전에는 적용하지 않는다.
|
||
|
||
완료 기준: 두 host worker의 경쟁·지연·취소 시험에서도 request 교차 소비가 없어야 한다.
|
||
|
||
### 4. 선행 task 구현
|
||
|
||
신규 task ID: `Task_S2_00_prepare_request`.
|
||
|
||
1. 인증된 host envelope, 실행 소유권, 네 외부 인자를 검증한다.
|
||
2. 고정 두 상수를 추가하여 6필드 request 객체를 만든다.
|
||
3. strict JSON/schema 및 경로·ID 검증을 수행한다. schema 자산을 읽는 경우 release/module manifest의 hash 결속된 정확한 closure를 사용한다.
|
||
4. 기존 canonical JSON 규칙(UTF-8, 정렬 key, 고정 구분자, NaN 금지, 종료 newline)으로 직렬화하고 raw SHA-256을 계산한다.
|
||
5. 소유권을 유지한 상태에서 `W/stage2_control/s2_00_request.json`에 binary write를 수행한다. 현재 계약에 없는 원격 rename·원자적 파일 교체 기능을 가정하지 않는다.
|
||
6. 같은 경로를 binary read-back하여 bytes가 동일한지 확인하고, 다시 parse/schema 검증한다.
|
||
7. 성공일 때만 stdout 준비 receipt를 반환한다. 권고 schema는 신규 `stage2_s2_00_prepare_request_receipt.v1`이며 `ok`, request path/hash/byte length, request_id/attempt_id, host execution binding을 포함한다. 이것은 **신규 설계**이며 기존 파일이라고 표현하지 않는다.
|
||
8. 오류·write 응답 유실·read-back 불일치·close 실패 등은 성공 receipt로 취급하지 않는다. ingress는 실행하지 않는다. 부분 파일이 남아 있어도 성공한 것으로 간주하지 않는다.
|
||
|
||
동일 시도 재실행은 같은 bytes 및 host identity가 확인되면 재사용 가능하다. 새 시도/다른 request로 교체할 때에는 이전 실행 종료 및 새 소유권이 먼저 확인되어야 한다. 성공 후 무조건 request를 삭제하는 정리 코드는 두지 않는다.
|
||
|
||
완료 기준: 실제 저장 bytes와 receipt hash가 일치하고, 모든 실패 경로가 후행 실행을 차단한다.
|
||
|
||
### 5. ingress 결속 및 DAG 변경
|
||
|
||
```text
|
||
IN
|
||
→ Task_S2_00_prepare_request
|
||
→ [host: exit=0 + 유효한 ok:true receipt + 동일 실행 binding 확인]
|
||
→ Task_S2_00_deterministic_ingress
|
||
→ OUT
|
||
```
|
||
|
||
- YAML `task_procedure`에 prepare의 `wait_until: [IN]`, ingress의 `wait_until: [Task_S2_00_prepare_request]`를 설정하고 nexts를 대응시킨다. stage prevs/nexts는 기존 독립 stage 구조를 유지한다.
|
||
- host의 success-only 조건은 YAML edge와 별도로 계약 및 시험에 포함한다. 실패한 prepare가 '완료'되었다는 이유로 ingress를 시작하지 않는다.
|
||
- ingress는 host가 제공한 준비 receipt가 없거나 잘못되면 시작을 거절한다. 최초 request bytes와 expected hash, request_id/attempt_id를 대조한다.
|
||
- 기존 두 read-pass의 동등성 검사를 유지한다. 두 번째 request bytes도 준비 receipt hash와 일치해야 한다. 동일하게 바뀐 다른 request를 두 번 읽어 통과하는 상황까지 차단한다.
|
||
- 신뢰할 수 없는 stale receipt·다른 workspace receipt·다른 attempt의 receipt를 거절한다.
|
||
- 기존 C00–C15, output barrier·route 계약은 유지한다. wrapper 실패와 core diagnostic 분기를 혼동하지 않는다.
|
||
|
||
완료 기준: prepare와 ingress가 같은 request를 사용했다는 검증 가능한 연결이 생긴다.
|
||
|
||
### 6. authoring·빌드·배포 계약 갱신
|
||
|
||
| 파일·영역 | 작업 |
|
||
|---|---|
|
||
| `M/Stage_2_S2_00_v.2.yml` | authoring 정본에서 2-task 구조·설명·version·inline source 갱신 |
|
||
| `R/agent_scripts/Stage_2_S2_00.yml` | 수정한 builder로 배포본 생성. 배포본만 수작업 수정하지 않음 |
|
||
| `R/offline_build/build_s2_00_inline_projection.py/.txt` | '정확히 1개' 검증을 **정확히 두 개의 지정 task와 지정 순서**로 변경; 추가 임의 task는 거절 |
|
||
| 같은 builder의 code 검사 | 공통 보안·endpoint·import 검사는 유지; ingress 전용 token과 prepare 전용 token을 분리 |
|
||
| `R/runtime/s2_00_ingress.py/.txt` | ingress task code의 파생 mirror로 유지 |
|
||
| 신규 `R/runtime/s2_00_prepare_request.py/.txt` | prepare code의 파생 mirror 제안. 두 task를 결합한 실행 파일로 만들지 않음 |
|
||
| `R/manifest/s2_00_inline_code_receipt.json` | task별 code pointer·hash·mirror, 전체 task semantics hash로 확장; schema version/소비자 동시 갱신 |
|
||
| `R/workflows/S2_00_stage1_ingress_normalize_and_bundle_compile.yml` | 선행 단계, 외부 인자, receipt·success gate·직렬화 계약 반영 |
|
||
| `R/deployment/stage2_code_executor_binding.yml` | task별 executor 및 권한: prepare는 request 고정 경로, ingress는 기존 결과 root. schema/release 읽기 경로도 task별 명시 |
|
||
| `R/schemas/ingress.schema.json` | 기존 6필드 execution_request 유지, 신규 prepare/envelope receipt 검증 정의 |
|
||
| `R/schemas/deployment.schema.json` 및 관련 schema | 두 task·task별 code binding·receipt 계약과 실제 소비자 호환성 반영 |
|
||
| `R/manifest/module_manifest.json`, `stage2_release.json`, release validator | 변경 자산의 등록·hash와 추가된 계약 검증 반영 |
|
||
| `M/Stage_2_00_Analysis_v1.md`, `Stage_2_00_IO_info.md` | 구현 완료 후 실제 구조·IO·검증 상태로 개정 |
|
||
|
||
`task index=0`에 ingress가 있다고 가정하는 코드를 모두 확인한다. task_name으로 추출하고 receipt에는 실제 YAML pointer도 남긴다. version 값은 관련 schema와 소비자 호환성을 확인해 함께 올린다.
|
||
|
||
### 7. hash 재결속 및 패키지 확정
|
||
|
||
- 변경 자산 → module/release → inline release pin → authoring projection/mirror/receipt → executor binding/detached admission의 실제 참조 그래프를 먼저 만든다.
|
||
- 현재 builder는 projection 이후 binding 재결속을 전제로 한다. 기존 detached 설계를 유지하고, parent release에 자신을 포함한 code hash를 되먹이는 순환 의존을 새로 만들지 않는다.
|
||
- 참조 그래프의 위상 순서대로 재생성한다. 순환이 발견되면 hash를 반복 덮어쓰는 대신 detached boundary를 설계·검증한다.
|
||
- 현재 `expected_release_sha256`, task별 code hash, Agent raw hash, workflow/schema/module hash와 receipt pointer를 함께 대조한다.
|
||
- 재생성 뒤 빌더 `--check`, release validator, mirror parity를 실행한다. 두 번째 빌드에서 bytes 차이가 없어야 한다.
|
||
- 테스트용 release와 실제 배포 release를 분리한다. DEV guard를 삭제하거나 production 표기를 붙여 검사를 통과시키지 않는다.
|
||
|
||
완료 기준: 참조된 변경 자산의 hash가 모두 일치하고, 반복 빌드가 추가 변경을 만들지 않는다.
|
||
|
||
## Source and Tool Plan
|
||
|
||
로컬 authoring·builder·runtime·tests를 우선 읽는다. backend 관련 문서·코드는 필요한 범위에서 확인하고 지원 여부를 증거로 남긴다. 신규 의존성 설치나 서비스 호출은 이 계획 작성에 포함하지 않는다. 구현 시 기존 도구·검증 runner를 확인해 사용하고, 라이브 시험은 별도 격리 workspace와 비실사건 fixture로 수행한다.
|
||
|
||
## Validation Plan
|
||
|
||
| 시험 | 통과 기준 |
|
||
|---|---|
|
||
| 유효한 인자 | request 정확히 6필드, canonical bytes/hash/read-back 일치 |
|
||
| 누락·추가·타입·ID·경로 오류 | 저장 전 거절, ingress 호출 0회 |
|
||
| 권한 밖 경로·다른 workspace | host 결속 검증 실패, 업무 입력 읽기 불가 |
|
||
| 저장 실패·응답 유실·read-back mismatch | 성공 receipt 없음, ingress 호출 0회 |
|
||
| 선행 task exit 0이나 ok:false/깨진 receipt | host가 후행 task를 실행하지 않음 |
|
||
| 준비 후 request 변조 | 첫 읽기 expected hash 검증 또는 두 pass 비교에서 거절 |
|
||
| 두 pass 모두 동일한 타 요청으로 교체 | 준비 receipt hash/identity 검증에서 거절 |
|
||
| 같은 workspace 두 요청·두 worker | 단일 소유자만 진입, 다른 요청 bytes를 소비하지 않음 |
|
||
| 다른 workspace 병렬 실행 | 불필요한 전역 직렬화 없이 독립 진행 |
|
||
| cancel·timeout·host crash·오래된 worker 재개 | 이전 쓰기 가능성이 사라지기 전 새 owner 쓰기 금지; stale owner 차단 |
|
||
| 동일 시도 retry / 새 attempt | 정의한 재사용/교체 정책 준수, 기존 output idempotency 계약 유지 |
|
||
| task shape / builder | 지정 두 task와 순서만 허용; task 누락·추가·우회 edge 거절 |
|
||
| 두 code mirror·receipt pointer·hash | authoring에서 추출한 bytes와 정확히 일치 |
|
||
| 기존 core 정상·diagnostic 회귀 | fixture 기준 11+E/5 출력 및 barrier 계약 보존 |
|
||
| 실제 backend 통합 | 인자 주입·receipt 전달·failure gate·workspace 격리를 실제 환경에서 확인 |
|
||
|
||
mock 통과는 실제 host 잠금·권한 강제 증거가 아니다. `STATIC_PASS`, `OFFLINE_TEST_PASS`, `BACKEND_INTEGRATION_PASS`, `LIVE_ADMISSION_PENDING`을 구분해 보고한다. 현재 DEV release로 정상 core 성공을 주장하지 않는다.
|
||
|
||
## Approval Boundaries
|
||
|
||
현재 요청은 작업 계획 작성이다. 이 단계에서는 계획 문서만 생성한다. 이후 구현 요청 시 범위 내 로컬 수정·시험을 수행하고, 실제 서비스 배포·외부 쓰기·live activation은 그때의 승인 범위를 확인한다. backend 기능 미지원은 기술적 미완료 조건으로 기록하며 이를 단순 승인 문제로 대체하지 않는다.
|
||
|
||
## Progress
|
||
|
||
- [x] 현재 단일 task·request read·builder 제약 확인
|
||
- [x] 현재 write root와 localdocs 도구 계약 확인
|
||
- [x] 작업 순서·의존성·동시 실행·검증 계획 작성
|
||
- [ ] backend 전달·직렬화 기능 확인 및 연동 방식 확정
|
||
- [ ] schema·prepare·ingress·DAG 구현
|
||
- [ ] builder·binding·hash 재결속
|
||
- [ ] offline·동시 실행·backend 통합 검증
|
||
- [ ] 분석·IO 문서 갱신 및 배포 적격성 판정
|
||
|
||
## Decision Log
|
||
|
||
| 날짜 | 결정 | 근거 | 결과 |
|
||
|---|---|---|---|
|
||
| 2026-09-30 | request의 기존 6필드 유지 | 현재 strict validator와 사용자 요구 | 실행 보조 정보는 host envelope로 분리 |
|
||
| 2026-09-30 | 첫 버전은 전체 S2_00 host 직렬화 | 두 독립 task 사이 lock 수명 및 고정 request 경로 | hydration 완료 전 해제 위험과 중간 callback 의존 감소 |
|
||
| 2026-09-30 | 준비 receipt hash를 ingress에 전달 | 두 read-pass 비교만으로 다른 요청 교체를 모두 검출할 수 없음 | 소비할 request를 선행 실행에 결속 |
|
||
| 2026-09-30 | authoring부터 재생성 | builder가 정본 및 mirror parity를 관리 | 배포 YAML 단독 변경 방지 |
|
||
|
||
## Evidence Ledger
|
||
|
||
| 명제 | 확인 근거 | 상태 |
|
||
|---|---|---|
|
||
| 기존 builder는 두 task를 거절한다 | extract_run_code_task의 EXACTLY_ONE_TASK_REQUIRED·EXACTLY_ONE_RUN_CODE_REQUIRED | 확인 |
|
||
| 현재 request 저장은 쓰기 허용 root 밖이다 | S2_00 binding의 write_root_rule | 계약에서 확인; live 강제 여부는 미확인 |
|
||
| localdocs 원자적 lock/CAS 지원 | 현재 allowlist에 read/write만 있음 | 지원 근거 없음, 사용 가능하다고 가정하지 않음 |
|
||
| 선행 task를 현재 backend가 어떻게 인자 결속하는가 | 구체 backend 구현을 아직 확인하지 않음 | 미확정 |
|
||
| request writer의 생성 필요 | 현재 소비 코드 및 이전 폴더 전체 검색 결과 | 현 패키지에 실사용 writer 없음 |
|
||
|
||
## Risks and Failure Modes
|
||
|
||
- YAML만 바꾸면 builder·code pointer·권한·hash 계약에서 실패한다.
|
||
- `wait_until`만 추가하면 prepare 실패 후 ingress가 진행될 수 있다.
|
||
- 고정 request 파일에 write/read-back만 구현하면 동시 요청이 서로 덮어쓸 수 있다.
|
||
- lock TTL 이후 오래된 writer가 살아 있으면 새 요청을 오염시킬 수 있다.
|
||
- 기존 release 제한을 이번 변경의 실패로 혼동하거나, 이를 제거해 정상 실행을 과장할 수 있다.
|
||
- 다른 request가 같은 run binding으로 귀결될 때 기존 status bytes 일치 요건은 여전히 적용된다. 기존 출력 충돌을 자동 덮어쓰기로 해소하지 않는다.
|
||
|
||
롤백은 두 task 실행을 먼저 정지하고 진행 중 I/O 종료를 확인한 뒤, authoring·배포본·mirror·schema·binding·receipt를 검증된 동일 버전 묶음으로 복원한다. 이전 버전도 외부 request 공급 없이는 실행되지 않으므로 롤백 자체를 서비스 정상화로 보지 않는다. 사건 입력·이미 발행된 결과는 일괄 삭제하지 않는다.
|
||
|
||
## Results and Residual Uncertainty
|
||
|
||
계획은 작성 완료하였고, 구현은 미착수다. 가장 중요한 미확정 항목은 backend의 structured 인자/receipt 전달과 workspace 단위 직렬화·worker 종료 통제이다. 이 기능이 확인되거나 구현되어야 안전한 2-task 실행이 완성된다. 완료 판정은 request 생성 성공뿐 아니라 **동일 요청의 후행 소비, 실패 시 차단, 동시 실행 안전성, 빌드·hash 일치**를 모두 통과하는 것으로 한다. 실제 backend 시험 전에는 live-ready로 판정하지 않는다.
|