DevPay Gem Socketing: 004 + 009 + Mixed 004/009
리비전 및 관측된 기준선
| 출처 | 관측 값 |
|---|---|
| Gem 루트 | /home/<user>/workspace/nougat-gems (읽기 전용 명세 소스) |
| Gem 브랜치 / 커밋 | main / 69b0707633a4afc0888ba1ce5092375386b630cd |
| 대상 리포지터리 | /home/<user>/workspace/nougat-playground, 브랜치 feat/pg-magician |
| 점검 시점 대상 HEAD | bcde4c23c2870e307c7972daa7c8524ae7a06a8a |
| 대상 애플리케이션 디렉터리 | nougat-devpay/ |
| 대상 워크트리 | 점검 시점 clean |
리포지터리는 nougat-devpay/의 부모이다. 이 작업의 변경은 해당 디렉터리로 제한된다. 모든 Task 레코드는 Gem 루트와 불변 Gem 커밋을 유지해야 생성된 워크트리가 동일한 명세 리비전을 해석할 수 있다. Gem 문서는 애플리케이션에 복사되지 않으며 수정되지 않는다.
증적 분류
- Observed는 점검된 DevPay 리비전에 존재하는 코드, 설정 또는 테스트를 뜻한다. 해당 동작이 이 환경에서 실행됐다는 뜻은 아니다.
- Proposed는 Gem 계약을 충족하기 위해 여기서 설계된 어댑터 또는 새 동작을 뜻한다.
- Historical Target Blueprint는
origin/009-agentic-development-control-plane/prompt-to-push-implementation-spec.md를 뜻한다. 이것은 목표 설계이지 현재 Gem 구현의 증거가 아니다. README, 아키텍처, 계약, 프레임워크, 런타임 격리, 실패/복구의 현행 Origin 009 계약이 우선한다. - Origin 004 애플리케이션 Action 계약과 Mixed 004+009 크로스 플레인 엔벌로프는 Gem 소스의 제안이며, 이 애플리케이션에 존재한다고 가정하지 않는다.
계약 추적 매트릭스
| Gem / 섹션 | 엔지니어링 의도 및 필수 불변조건 | DevPay 관측 상태 | 계약 갭 / 어댑터 | 의도된 구현 및 담당 파트 | 테스트 / 상태 |
|---|---|---|---|---|---|
| Origin 009 README, Architecture: Task isolation | 병렬 작업 편집은 체크아웃을 공유하면 안 됨; 각 Task가 브랜치와 워크트리를 소유. | Base에 매니저 없음; Task ID별 워크트리/브랜치가 Gem/Base 핀과 함께 존재. | 프로젝트 경계와 소유 정리를 가진 CLI 및 Git 워크트리 어댑터. | tools/devpay_control/control.py, git_worktrees.py; ④. | 독립 픽스처 Task 2개 + 실제 Task 8cc5…; 소유 워크트리 정리됨. VERIFIED. |
| Origin 009 Contracts / Framework: lifecycle and persistence | 상태 전이와 시도 증적은 내구적이어야 함; 재시도는 시도를 추가. | 애플리케이션 SQLite는 프라이빗 control-plane SQLite와 분리. | Append-only attempts/events/gates/artifact 해시 + SQLite task/queue 상태. | store.py, control.py, provenance.py. | 실패/재시도를 거쳐 10개 시도 보존; 크래시 복구 테스트. 로컬 범위 VERIFIED. |
| Origin 009 Contracts / Framework: verification profiles | 변경 유형으로 검사 선택; 없거나 사용 불가한 검사는 통과 불가. | 기존 CI가 이미 Worker, Axum, FE, Playwright 잡을 분리. | 보수적 프로필; 미지 경로는 에스컬레이션; FE 브라우저 커버리지 필수. | profiles.py, runner.py, browser_runner.py; ④/⑤. | 정확한 control/typecheck/browser 프로필이 Gate 1/2 통과; 알 수 없는/누락 테스트. 이 프로필 범위 VERIFIED. |
| Origin 009 Architecture / Contracts: Gate 1 | 제출된 정확한 Task HEAD 검증, 실패 증적 보존. | Base에 Gate 없음. | 분리된 워크트리, 전후 정확한 SHA, 정책·컨트롤러 다이제스트 바인딩. | control.py, git_worktrees.py. | Gate 1 a2ce2a33… PASS at 3963ed8…; 이전 실패 시도 보존. VERIFIED. |
| Origin 009 Architecture / Contracts: Gate 2 | Gate 1 통과 SHA를 최신 검증 Base에 통합; 통과한 Candidate만 Base 전진. | Base에 Candidate 게이트 없음. | 직렬화된 머지 워크트리, Candidate 회귀, expected-old CAS. | control.py, git_worktrees.py; PM / Tech Lead. | Gate 2 17545197… PASS at 4c36a04…, Base bcde4c2…; 로컬 Ref만. VERIFIED. |
| Origin 009 Architecture / Failure & Recovery: queue, retry, CAS | 공유 ref는 단일 writer; 오래되거나 실패한 candidate는 promote 불가; 시도 보존. | 단일 호스트 로컬 큐와 통합 잠금; 분산 lease/fencing 없음. | SQLite 큐, flock, Git expected-old 업데이트와 append-only 시도. | control.py, store.py, git_worktrees.py. | Candidate 실패, 오래된 Base, 충돌, 이동한 HEAD, 재시도와 복구. PARTIAL; 분산 스케줄링 부재. |
| Origin 009 Runtime Isolation / Failure & Recovery | Task/Gate 소유 Xephyr/프로필/아티팩트/프로세스 소유권; 호스트 DISPLAY 폴백 없음. | 기존 Playwright는 로컬; Base에 런타임 할당 없음. | Xvfb 부모 + Xephyr 디스플레이, 프라이빗 프로필/사용자 홈 디렉터리/PID 식별 정리, fail closed. | runtime.py, browser_runner.py; ④/⑤. | 실제 Xephyr 디스플레이 2개와 headed Gate 1/2 Browser 테스트. Linux 브라우저 범위 VERIFIED; 네이티브 OS 입력은 미주장. |
| Origin 009 Contracts / Framework: evidence, artifacts, security | 결과를 Task/Attempt/Gate/정확한 SHA/프로필/아티팩트에 바인딩; 비밀/원시 출력 제외. | Base에 커밋 바운드 오케스트레이션 증적 없음. | SQLite 콘텐츠 해시, 안전한 Action 수신 투영; 명령 stdout/stderr 억제. | store.py, control.py, runner.py. | 정확한 SHA 아티팩트, 불변 행, 프라이버시·출처 네거티브 테스트. 로컬 범위 VERIFIED. |
| Origin 009 Publish / Historical Target Blueprint | Gate 2 이후 non-force publish만; 전달에는 원격 계보 증명 필요. | 배포 스크립트는 별개; 오케스트레이션 퍼블리셔 없음. | 원격 publish 비활성; 원격 ref 미접촉. 대상 브랜치는 Gate 1/2 후 로컬에서만 fast-forward. | 퍼블리셔 모듈 없음. | refs/devpay/validated/local만; 원격 공개는 로컬 전용 지시로 PARTIAL. |
| Origin 004 Design: Registry, schema/version, single dispatch | 안정적인 의미 ID/버전과 페이로드 검증; 백엔드 인가가 권위 유지. | useOverlayNav는 네비게이션 전용; 판매자 상품 UI가 db.saveProduct를 직접 호출. | 별도 도메인 Action 레지스트리/디스패처; URL/Overlay 계약 보존. 백엔드 license_json 별칭 정규화. | fe/lib/actions/registry.ts, dispatcher.ts, product-create.ts, product-update.ts, product-contract.ts; ③ Seller FE, ② 공유 FE 어댑터. | Product-create/Update Gate E2E가 정확한 Task/Candidate SHA에서 검증. 라이프사이클 슬라이스 VERIFIED; 다른 Action은 미이전. |
| Origin 004 Design: safe Trace and Receipt | 명령 결과는 도메인/런타임 검사와 다름; 누락된 검증은 미검증. | 제품 수신 또는 독립 UI/도메인 검증 없음. | 경계된 안전 수신; 서버 read-after-write와 렌더된 상세는 독립 검사. | receipts.ts, dispatcher.ts, product-create.ts, product-update.ts. | Gate 1/2 수신이 create/update 도메인·런타임 검사를 assert. 이 슬라이스 VERIFIED. |
| Origin 004 Design: navigation/legacy bridge | Router/Overlay 보존; URL은 선택이며 변이/비밀을 제외. | useOverlayNav가 ?action= 히스토리/수명/포커스 소유. | Product create/update는 비-URL Action; Nav 소스 재작성 없음. | useOverlayNav.ts 변경 없음. | 기존 Overlay Playwright 스위트가 Gate 1/2 통과. VERIFIED. |
| Origin 004 Design: backend authority and side-effect safety | UI 검증은 인가가 아님; API가 인가; 안전하지 않은 부작용을 자동 재생하지 않음. | Axum과 Worker/D1은 별개 유지; 판매자 상품 CRUD API는 seller 스코프. | 기존 seller API 재사용; 로컬 Axum은 일회용 SQLite/dev-auth 픽스처; D1/프로덕션 아님. | 라우트/인증/결제 정책 변경 없음; ④. | 로컬 create/update와 독립 GET 통과; 전체 Axum 스위트가 명시적 테스트 픽스처로 green. 이 Action 범위 VERIFIED. |
| Mixed 004+009 Architecture / Contracts: envelope and run trust | 수신을 신뢰된 Task/Attempt/Gate/Commit/Scenario에 조인; correlation ID만으로는 신뢰 불가. | Base에 크로스 플레인 엔벌로프 없음. | 읽기 전용 수집기가 정확한 run 튜플, Action 스키마/버전, HMAC과 드라이버 assertion 검증. Git/큐/ref 메서드 없음. | action_evidence.py, provenance.py; ④/⑤. | 위조 서명/커밋, 잘못된 run, 중복 거부; 두 Action 모두 Gate 1/2 정확한 SHA 검증. 판매자 라이프사이클 VERIFIED. |
| Mixed 004+009 Contracts / Validation: reconciliation | 필수 Action/버전/검사/충실도가 일치해야 함; 명령 성공만으로 통과 불가. | 기존 E2E에 의미 커버리지 계약 없음. | 지속된 도메인 행, 보이는 상세/업데이트, 독립 드라이버 assertion, 브라우저 충실도 요구. | PRODUCT_ACTION_COVERAGE, 신뢰된 브라우저 시나리오, Gate 어댑터. | 누락 assertion, 명령 전용, 버전/run 불일치, 예상 밖 Action 테스트; 정확한 create/update Candidate 수신. v1 VERIFIED. |
| Mixed 004+009 Privacy / Recovery | 네임스페이스 분리; 중단된 증적 보존; 원시 페이로드/토큰/쿠키/이메일/경로 제외. | Base에 브리지 없음. | 안전한 수신 투영, 프라이빗 아티팩트, 불변 재시도 시도; Playwright 스크린샷이나 원시 출력 없음. | action_evidence.py, store.py, runtime.py. | 불안전한 투영 거부, 이전 시도 보존, Gate 아티팩트 해시 검증. 로컬 범위 VERIFIED. |
| Axum fixture / regression contract (보충) | 프로덕션 시딩 비활성 유지; 테스트는 일회용 픽스처 데이터를 소유하고 인증/테넌트/결제/원장 assertion 유지. | db::open()은 의도적으로 기본 자동 시드 안 함. 이전 테스트는 데모 행 존재에 의존. | APP_ENV=production과 OS 임시 디렉터리 밖 DB 경로를 거부하는 명시적 테스트 전용 시드 헬퍼 추가. 마이그레이션 테스트가 open()이 시드하지 않음을 검증. 라우트나 커머스 정책 변경 없음. | be/src/db.rs, be/tests/{api_test,migration_test,security_test,outbox_test}.rs; ④. | 전체 Axum cargo test --locked --offline 통과; 로컬 Gate 1/2 백엔드 프로필 통과. VERIFIED. |
현재 시스템 경계 (관측)
- 프런트엔드: Nuxt 3 / Vue / Pinia.
useOverlayNav는 확립된 네비게이션 전용 어댑터로 유지. 판매자 상품 create/update는seller.product.create와seller.product.updatev1 Action을 디스패치하고db.saveProduct→fe/lib/api/client.ts→ seller 보호 API를 재사용. Mock 모드는 도메인 증거로 인정되지 않음. - 소유권: 공개 및 플랫폼 운영자 화면은 Platform Frontend 소유; 판매자 상품 워크플로는 Seller Frontend 소유. 공유 FE 액션 배관은 단일 스튜어드 필요. 백엔드/Cloudflare와 계약 변경은 Backend & Infrastructure 소유; 독립 인수는 QA & Release 소유. AI 작업은 벤더나 사람 인수를 대표하지 않음.
- 백엔드:
be/는 Rust Axum + SQLite/로컬 테스트 경로.be-cloudflare/는 Rust Worker + D1 배포 경로. Axum 성공을 Worker/D1 검증으로 보고할 수 없음. 기존 인증된 상품 라우트와 FE API 클라이언트 재사용; 인증/결제/DB 정책 약화 없음. - 검증/배포: Playwright는 로컬 Nuxt용으로 구성, 현재 E2E 설정은 Axum dev auth와 임시 DB 사용. GitHub Actions는 Axum 테스트, Worker WASM 빌드, FE 타입체크, Playwright, Docker 스모크를 실행. 스크립트로 Cloudflare 배포 가능; 이 작업에 배포나 프로덕션/스테이징 DB 작업은 없음.
- Base의 도구: Git 워크트리 컨트롤러, 작업 큐, Xephyr 런타임 할당기, action-to-gate 증적 수집기가 없었음. 세션은 사용자 소유의 체크섬 검증된 Node/pnpm/Rust/Xephyr/Chromium 도구체인을 준비. 잠긴 Cargo 의존성은 승인 후에만 페치. Gem 리포지터리, 패키지 매니페스트/락파일, 프로덕션/스테이징 리소스는 변경하지 않음.
계약 갭과 해결
- 분리된 상태 권위: 앱 도메인 SQLite/D1과 control-plane SQLite는 분리 유지. control plane은 오케스트레이션/증적 메타데이터와 로컬 Git 경로만 저장; 브라우저 러너는 일회용 시드 Axum SQLite DB 사용.
- Gate 증적: 명령 종료 코드 하나로는 불충분. Gate 1은 정확한 Task HEAD에 바인딩; Gate 2는 정확한 머지된 Candidate와 최신 Base에 바인딩. 둘 다 모든 프로필 검사와 필수 Mixed 증적 요구.
- CAS와 공개: Git 로컬 브랜치 전진은 expected-old SHA 사용. 원격 publish와 DevPay 배포는 비활성 유지; force 작업 불가.
- 런타임 가용성: 호스트 DISPLAY 폴백 없음. Xephyr 전제 조건이 없으면 GUI 검증은 BLOCKED이며 게이트 통과 불가. 헤드리스 Rust/API/DB 검사는 GUI를 시작하지 않음.
- Mock 대 실물: mock 상품 액션은 디스패치만 테스트 가능; 서버/도메인 검증을 충족하지 못함. API 모드는 독립적인 read-after-write 검증 필요.
- 역사적 청사진: 2026-10 Prompt-to-Push 문서는 역사적 목표. 추상 PUBLISHED, 다중 호스트 분산 lease, 외부 알림, 완전 재개 동작은 관측된 계약이나 구현된 기능으로 취급하지 않음.
- Control-plane 출처: submit과 gate 실행은 control-plane 소스 다이제스트와 Python 버전을 핀. 분리된 Gate 실행은 러너와 시나리오 소스가 그 다이제스트와 일치하지 않으면 BLOCKED — 오염된 컨트롤러 체크아웃이 다른 제출 SHA의 증적을 공급하는 것을 방지.
공유 FE API 어댑터
- 관측된 갭:
parseJsonFields가 백엔드license_json속성을license로 변환하는데, FEProduct계약은licensePolicy를 기대. 기존FIELD_MAP은licenseJson을 정규화했으나 실제 파싱된 키를 커버하지 못함. 엄격한 Action 페이로드 검증이 첫 Product Update Gate에서 이 예상 밖 필드를 올바르게 거부. - 구현된 어댑터:
fe/lib/api/client.ts에서 파싱된license_json필드를licensePolicy로 정규화. 요청/응답 JSON, Rust/Worker 인가, D1, 마이그레이션은 변경하지 않음. - 소유권: Main Agent / Tech Lead가 공유
fe/lib/api/client.ts에 단일 writer를 지정; Seller Frontend가 Product Action과 페이지 소유. - 증적: 실제 Gate 실행이 예상 밖 DTO 키(
PRODUCT_INVALID_SHAPE)를 포착; 어댑터 수정이 정확한 Task/Candidate SHA에서 타입체크와 로컬 Axum create/update 브라우저 Gate 통과.
제안된 모듈 경계와 소유권
text
tools/devpay_control/
cli.py 로컬 CLI 경계
control.py 작업 생명주기, Gate 1/2, CAS와 런타임 lease
git_worktrees.py 정확한 SHA, 워크트리 소유자와 로컬 잠금 연산
profiles.py 허용 목록 분류기와 정책 리비전
runner.py 셸 없는 검사, 타임아웃과 안전한 결과 투영
browser_runner.py 격리된 로컬 API + headed Playwright Gate
runtime.py 작업/Gate 소유 Xephyr와 PID 소유권
action_evidence.py 읽기 전용 Mixed 검증과 정합성
provenance.py control-plane/시나리오 콘텐츠 다이제스트
store.py 프라이빗 SQLite 작업과 증적 레코드
trusted_product_scenario.mjs 독립 브라우저/서버 assertion
fe/lib/actions/
registry.ts 의미 ID/버전과 페이로드 계약
dispatcher.ts 앱 측 디스패치 정책과 안전한 수신
receipts.ts 경계된 허용 목록 앱 수신
product-create.ts 판매자 상품 생성 수직 액션
product-update.ts 판매자 상품 수정 수직 액션
product-contract.ts 공유 엄격 Product 페이로드 검증기1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Product Action Plane은 작업 명령을 호출하지 않는다. Mixed 어댑터는 Git, 큐, ref 업데이트, 배포, publish 기능이 없다. 기존 라우트와 API 인가는 권위로 유지된다.
전달 계획과 인수
- Phase 0 — VERIFIED: 추적성, 현재 계약 갭, 모듈 경계, 안전한 실행 계획.
- Phase 1 — VERIFIED (로컬 전용): 독립 픽스처 Task 2개가 Gate 1 통과; 실패한 Candidate는 Base 변경 없이 둠; 재시도 통과. 실제 Task
3963ed8…이 Gate 1 통과, Candidate4c36a04…가 Gate 2/CAS 통과. 후속 로컬 Backend 픽스처 Task도 Gate 1/2 통과. 원격 publish는 비활성 유지. - Phase 2 — 로컬 Linux 브라우저 범위 VERIFIED: 작업/Gate 소유 Xvfb+Xephyr, 프라이빗 프로필/아티팩트, 프로세스 소유권과 정리, headed Chromium Gate 실행 통과. 네이티브 OS 입력 충실도는 미주장.
- Phase 3 — 판매자 상품 create/update v1 VERIFIED: 엄격한 Action 페이로드 검증과 drop 동시성이 seller API 재사용; 별도 서버 read-after-write와 렌더된 상세 검사가 Gate 1·Gate 2 통과. 다른 Action은 미이전.
- Phase 4 — 판매자 상품 라이프사이클 VERIFIED: create/update 도메인/런타임/드라이버 수신이 정확한 Task/Candidate 실행과 정합. 누락, 불일치, 중복, mock 충실도, 명령 전용 증적은 통과 불가.
범위는 단일 호스트 유지: 분산 lease/fencing, 완전한 뷰어, 알림 서비스, 원격 퍼블리셔, 프로덕션 인증 검증, 스테이징/D1 검증, 프로덕션 릴리스는 미구현.
인수는 임시 Git 리포지터리, 작업 소유 워크트리, 로컬 ref, 프라이빗 SQLite, 픽스처 데이터 사용. 프로덕션/스테이징 DB, 배포, 실제 결제, 원격 push, 비밀 포함 아티팩트 캡처는 없음.
실행된 증적과 남은 한계
| 증적 | 정확한 범위/결과 |
|---|---|
| 명세/대상 | Gem main@69b0707633a4afc0888ba1ce5092375386b630cd; 대상 feat/pg-magician@bcde4c23c2870e307c7972daa7c8524ae7a06a8a. |
| 실제 Task / Gate 1 | Task 8cc5d2c7966b4b738ea58506eebe7956, 최종 head 3963ed8ece653d0557b9f1ebf679fc51d1778d0b, Gate a2ce2a33e7e340e19a276620a825b3f7 PASS. |
| Product Candidate / Gate 2 | Candidate 4c36a04a2c24d6960a9ec70d6d9726ea6402c7cc, 예상 Base bcde4c23c2870e307c7972daa7c8524ae7a06a8a, Gate 175451974648404e8102a14892015811 PASS; 로컬 ref만. |
| Product create/update Task | Task f3f27b680bff4ad9aa9af0dbba6f233c, 최종 Task Head f40559921485918dd47af9eaeb204384b9ed6302, Gate 1 4c12cfb7… PASS; Candidate 86c384b5f76ebdbc0dc9bb9f80174d6e7dabcb45, Gate 2 45bf1b4f… PASS. 이전 시도는 스키마와 DTO 어댑터 실패를 보존. |
| Backend fixture Task / Gate 1 + 2 | Task 92393119356c4b50966fc7f0857bbdb8 head 3d7a3ebf590fb7f9ba0c910024273cd914de8578; Gate 1 f9b2b917… 및 Gate 2 82986cbd… PASS. Backend fixture candidate 58890079461f4c32346ad899ac62d75862756dc8는 문서 전용 후속 전에 로컬 검증됨. |
| 실제 브라우저 증적 | 소유 Xephyr의 headed Chromium; 판매자 Product create/update + 기존 product-flow와 Overlay Playwright 스펙이 Gate 1/2 통과. 두 Action 모두 정확한 Gate/Commit/Scenario와 일치하고 6개 도메인/런타임/드라이버 검사 전부 통과. |
| Control-plane 테스트 | python3 -m unittest discover -s tools/devpay_control/tests -v: 총 28개, 26개 통과, 실제 Xephyr 테스트 2개 기본 스킵. DEVPAY_TEST_XEPHYR=1 실행은 28개 전부 통과. |
| 프런트엔드 검사 | pnpm exec vue-tsc --noEmit -p tsconfig.json PASS; pnpm exec nuxi generate PASS (기존 dynamic-import 경고). 잠긴 FE 락파일 SHA256은 7e0b3dfe1c042aa8c3e18f2ee61f8ee3a3eb17e7f9a6e9d50f4554088a4040c0 유지. |
| Worker 빌드 | cargo build --locked --offline --release --target wasm32-unknown-unknown PASS. 이것은 로컬 빌드이며 D1 또는 Cloudflare 배포 테스트가 아님. |
| Axum 스위트 | cargo test --locked --offline PASS (픽스처 전용 수정 후): API 8, migration 5, outbox 5, security 7, store 4 통과; PG 서버 미구성으로 PostgreSQL 테스트 1개 무시. 명시적 픽스처 헬퍼는 프로덕션과 비임시 DB 경로를 거부. API 라우트, 인증, 테넌트, 결제, 원장 정책 완화 없음. |