From 7f5abb1e0ad5423c087c6c2e52493be2b67d8e6d Mon Sep 17 00:00:00 2001 From: toki Date: Sun, 14 Jun 2026 18:23:02 +0900 Subject: [PATCH] update roadmap and milestone docs for agent-shell-package-iop-backend-boundary --- README.md | 30 ++- agent-roadmap/ROADMAP.md | 3 +- .../milestones/operation-event-outbox.md | 15 +- .../phase/agent-shell-iop-execution/PHASE.md | 18 +- ...gent-shell-package-iop-backend-boundary.md | 73 +++++++ .../milestones/agent-shell-runtime-channel.md | 68 ------ .../command-policy-and-cancellation.md | 35 ++-- .../milestones/iop-agent-run-bridge.md | 18 +- .../phase/control-plane-foundation/PHASE.md | 8 +- .../CODE_REVIEW-local-G05.md | 150 +++++++++++++ .../PLAN-local-G05.md | 197 ++++++++++++++++++ apps/client/README.md | 12 ++ docs/architecture.md | 22 +- .../contracts/notes/gito-control-plane.md | 20 +- .../core/internal/storage/postgres_test.go | 38 +++- 15 files changed, 560 insertions(+), 147 deletions(-) rename agent-roadmap/{ => archive}/phase/control-plane-foundation/milestones/operation-event-outbox.md (81%) create mode 100644 agent-roadmap/phase/agent-shell-iop-execution/milestones/agent-shell-package-iop-backend-boundary.md delete mode 100644 agent-roadmap/phase/agent-shell-iop-execution/milestones/agent-shell-runtime-channel.md create mode 100644 agent-task/m-agent-shell-package-iop-backend-boundary/CODE_REVIEW-local-G05.md create mode 100644 agent-task/m-agent-shell-package-iop-backend-boundary/PLAN-local-G05.md diff --git a/README.md b/README.md index 4cd2f81..95007c2 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ # Gito Gito는 agent-driven development를 위한 platformless Git control plane이다. -여러 Git repository를 등록하고, workspace lease, Git operation, agent-shell, -IOP 실행, provider adapter, normalized event를 하나의 제어 흐름으로 묶는다. +여러 Git repository를 등록하고, workspace lease, Git operation, provider +adapter, normalized event를 하나의 제어 흐름으로 묶는다. Agent interaction +UI는 sibling `../agent-shell` Flutter package를 사용하고, 그 UI를 구동하는 +backend/runtime은 sibling `../iop` 프로젝트가 맡는 방향으로 둔다. Git 자체 작업은 GitHub/GitLab/Gitea 같은 플랫폼을 몰라도 동작해야 한다. PR/MR, review, checks, webhook 같은 플랫폼 기능은 provider adapter 뒤에 둔다. @@ -14,7 +16,7 @@ Flutter client는 control surface 경계만 잡혀 있다. 현재 가능한 범위: -- Go `server`, `worker`, `shell` command build +- Go `server`, `worker`, legacy `shell` scaffold command build - health/readiness REST placeholder - platformless `gitengine` 최소 테스트 - core domain DTO 후보 @@ -26,8 +28,10 @@ Flutter client는 control surface 경계만 잡혀 있다. - 실제 proto-socket channel/action - 실제 PostgreSQL store wiring -- agent-shell outbound 연결과 command streaming -- IOP CLI 실행 orchestration +- `agent_shell: path: ../agent-shell` package를 쓰는 Flutter host + integration +- `../iop` backend/runtime 결과를 Gito operation/event 계약으로 수렴시키는 + 연결 - GitHub/GitLab/Gitea provider adapter - Flutter 화면 구성과 operation event 구독 @@ -76,12 +80,12 @@ curl http://127.0.0.1:8080/readyz | --- | --- | | `services/core/cmd/server/` | control plane server entrypoint | | `services/core/cmd/worker/` | operation worker entrypoint | -| `services/core/cmd/shell/` | agent-shell runner entrypoint | +| `services/core/cmd/shell/` | legacy shell scaffold entrypoint; canonical agent backend/runtime은 `../iop`가 소유 | | `services/core/internal/controlplane/` | REST/proto-socket surface, auth/policy gate 후보 | | `services/core/internal/core/` | provider-neutral domain model | | `services/core/internal/gitengine/` | platformless Git operation layer | | `services/core/internal/worker/` | operation 실행 orchestration 후보 | -| `services/core/internal/agentshell/` | local command/IOP execution boundary | +| `services/core/internal/agentshell/` | legacy shell scaffold boundary; 새 방향에서는 agent backend/runtime을 직접 확장하지 않음 | | `services/core/internal/provider/` | GitHub/GitLab/Gitea/Plane/Jira adapter boundary | | `services/core/internal/events/` | normalized event model | | `services/core/internal/storage/` | PostgreSQL store boundary | @@ -105,7 +109,7 @@ Core Domain | Worker / Scheduler | -Agent Shell / IOP / Git Engine +IOP backend/runtime + Git Engine | Provider Adapters ``` @@ -114,8 +118,12 @@ Provider Adapters - `controlplane`은 요청, 정책, 관찰, event stream을 소유한다. - `core`는 repo, workspace lease, operation, revision cursor, event 원장을 소유한다. -- `worker`는 operation 실행을 조율한다. -- `agentshell`은 실제 workspace command, Git CLI, IOP CLI 실행을 맡는다. +- `worker`는 operation 실행과 외부 runtime 결과 수렴을 조율한다. +- Flutter host는 `agent_shell: path: ../agent-shell` dependency로 agent + interaction UI/domain package를 붙인다. +- `../agent-shell`은 Flutter agent UI/package이며 Gito backend가 아니다. +- `../iop`는 agent backend/runtime을 맡고, Gito는 그 결과를 Git operation과 + event 원장으로 수렴한다. - `gitengine`은 platformless여야 하며 local bare repo만으로 테스트 가능해야 한다. - `provider`는 PR/MR/review/checks/webhook 같은 플랫폼 기능만 맡는다. - PostgreSQL은 source of truth이고, Redis는 필요할 때 fanout/stream 가속 계층으로만 둔다. @@ -160,7 +168,7 @@ Provider Adapters | `REDIS_URL` | optional Redis endpoint | 아니오 | | `PROTO_SOCKET_PATH` | proto-socket endpoint path, 기본값 `/proto-socket` | 아니오 | | `WORKER_ENABLED` | worker 실행 여부, 기본값 `true` | 아니오 | -| `GITO_SHELL_ID` | agent-shell 식별자, 기본값 `local-shell` | 아니오 | +| `GITO_SHELL_ID` | legacy shell scaffold 식별자, 기본값 `local-shell` | 아니오 | Credential 값은 tracked 파일에 쓰지 않는다. 필요한 경우 `credential_ref`나 ignored local secret file로 연결한다. diff --git a/agent-roadmap/ROADMAP.md b/agent-roadmap/ROADMAP.md index 8101c8f..fda5b31 100644 --- a/agent-roadmap/ROADMAP.md +++ b/agent-roadmap/ROADMAP.md @@ -16,7 +16,7 @@ Gito는 GitHub, GitLab, Gitea 같은 플랫폼에 묶이지 않는 Git control p - 요약: platformless Git control plane의 모듈 경계, repo/workspace/operation/event 원장, proto-socket 우선 transport 기준을 build 가능한 baseline으로 닫는다. - [계획] Agent Shell IOP Execution - 경로: `agent-roadmap/phase/agent-shell-iop-execution/PHASE.md` - - 요약: workspace command 실행 주체인 agent-shell과 IOP CLI를 연결해 Git 작업과 agent run을 안전하게 수행한다. + - 요약: `../agent-shell`은 Flutter agent UI/package로 사용하고, backend/runtime owner는 `../iop`로 지정해 Gito Git control plane과 연결한다. - [계획] Provider Change Request Integration - 경로: `agent-roadmap/phase/provider-change-request-integration/PHASE.md` - 요약: GitHub PR, GitLab MR, Gitea PR 같은 provider 기능을 ChangeRequest 추상화와 adapter 구조로 통합한다. @@ -49,4 +49,3 @@ Gito는 GitHub, GitLab, Gitea 같은 플랫폼에 묶이지 않는 Git control p - 선택된 Milestone의 `구현 잠금` 섹션이 없거나 상태가 `잠금`이면 코드 구현, `agent-task` 구현 계획 생성, 세부 API/파일 구조 확정을 시작하기 전에 현재 요청에 직접 영향을 주는 `결정 필요` 항목만 확인한다. - 현재 요청과 직접 관련 없는 미정 항목은 잠금 상태로 남겨도 되며, 기존 구조/도메인 rule/플랫폼 관례로 정할 수 있는 작업은 표준선으로 기록하고 진행할 수 있다. - Milestone 전체에서 사용자만 결정할 항목이 더 이상 없고 에이전트가 표준선에 따라 실행하면 되는 상태라면 `구현 잠금` 상태를 `해제`로 둔다. - diff --git a/agent-roadmap/phase/control-plane-foundation/milestones/operation-event-outbox.md b/agent-roadmap/archive/phase/control-plane-foundation/milestones/operation-event-outbox.md similarity index 81% rename from agent-roadmap/phase/control-plane-foundation/milestones/operation-event-outbox.md rename to agent-roadmap/archive/phase/control-plane-foundation/milestones/operation-event-outbox.md index 6bfd732..0bb152a 100644 --- a/agent-roadmap/phase/control-plane-foundation/milestones/operation-event-outbox.md +++ b/agent-roadmap/archive/phase/control-plane-foundation/milestones/operation-event-outbox.md @@ -11,7 +11,7 @@ operation lifecycle과 normalized event를 PostgreSQL 원장에 기록하고, pr ## 상태 -[검토중] +[완료] ## 승격 조건 @@ -50,16 +50,17 @@ operation 결과를 durable event로 남기고 fanout 대상이 읽을 수 있 ## 완료 리뷰 -- 상태: 요청됨 +- 상태: 승인됨 - 요청일: 2026-06-14 - 완료 근거: - `agent-task/archive/2026/06/m-operation-event-outbox_1/complete.log`의 Roadmap Completion이 `event-store` PASS를 기록했다. - 원격 code-server compose의 `code-server-postgres`에 `gito_test` DB를 만들고 `TestPostgresOperationEventStoreAppendsListsMarksPublishedAndValidates`를 `SKIP` 없이 PASS했다. - `cd /config/workspace/gito/services/core && GITO_TEST_DATABASE_URL= go test ./... -count=1`이 PASS했다. + - 2026-06-14 코드레벨 재검토에서 operation lifecycle/store/pick/outbox 경계와 계약 shape를 확인했고, operation event fixture를 계약 payload 형식에 맞춘 뒤 검증을 통과했다. - 리뷰 필요: - - [ ] 사용자가 완료 결과를 확인했다 - - [ ] archive 이동을 승인했다 -- 리뷰 코멘트: 모든 기능 Task와 명시 검증이 evidence와 함께 충족되어 Milestone 완료 후보로 전환한다. 사용자 승인 후 `[완료]` 및 archive 이동을 진행한다. + - [x] 사용자가 완료 결과를 확인했다 + - [x] archive 이동을 승인했다 +- 리뷰 코멘트: 모든 기능 Task와 명시 검증이 evidence와 함께 충족되었고, 코드레벨 재검토와 통합 검증 PASS 후 사용자 조건부 승인에 따라 `[완료]` 및 archive 이동을 진행했다. ## 범위 제외 @@ -72,8 +73,8 @@ operation 결과를 durable event로 남기고 fanout 대상이 읽을 수 있 - 관련 경로: `services/core/internal/events/`, `services/core/internal/storage/`, `services/core/internal/worker/`, `services/core/migrations/` - 표준선(선택): Postgres outbox가 event source of truth이며 Redis는 optional acceleration이다. -- 현재 작업현황: `event-store` 구현과 DB-backed 검증이 완료되어 Milestone은 사용자 완료 확인 및 archive 승인 대기 상태다. +- 현재 작업현황: `event-store` 구현과 DB-backed 검증, 코드레벨 재검토가 완료되어 Milestone은 `[완료]` 처리 후 archive로 이동했다. - 검증 완료: 원격 code-server compose의 `code-server-postgres`에서 `gito_test` DB를 사용해 event order, retry 가능한 pending publish 상태, mark-published 동작을 검증했다. - 선행 작업: Platformless Git Operation Engine - 후속 작업: Agent Shell Runtime Channel -- 확인 필요: 사용자가 완료 결과를 확인하고 archive 이동 여부를 승인한다. +- 확인 필요: 없음 diff --git a/agent-roadmap/phase/agent-shell-iop-execution/PHASE.md b/agent-roadmap/phase/agent-shell-iop-execution/PHASE.md index 6d09ca6..79f4f14 100644 --- a/agent-roadmap/phase/agent-shell-iop-execution/PHASE.md +++ b/agent-roadmap/phase/agent-shell-iop-execution/PHASE.md @@ -6,7 +6,7 @@ ## 목표 -agent-shell을 실제 workspace command 실행 주체로 세우고 IOP CLI와 연결한다. control plane은 operation을 만들고, worker는 lease와 실행을 조율하며, agent-shell은 Git CLI와 IOP CLI 실행, 로그 streaming, cancel/timeout, dirty guard를 담당한다. +workspace 상위 sibling 프로젝트 `../agent-shell`을 제품 비종속 Flutter agent UI/package로 사용하고, 그 UI를 구동하는 backend/runtime은 `../iop` 프로젝트가 맡도록 경계를 정리한다. Gito는 agent backend를 직접 구현하지 않고, repo/workspace/operation/event control plane과 Git 결과 수렴 계약을 제공한다. ## Milestone 흐름 @@ -14,22 +14,22 @@ agent-shell을 실제 workspace command 실행 주체로 세우고 IOP CLI와 완료, 검토중, 진행중, 계획, 스케치 순서로 두어 아래로 갈수록 미래 작업에 가까워지게 정렬한다. 스케치 Milestone은 아직 구현 가능한 계획이 아니므로 계획 Milestone보다 아래에 둔다. -- [계획] Agent Shell Runtime Channel - - 경로: `agent-roadmap/phase/agent-shell-iop-execution/milestones/agent-shell-runtime-channel.md` - - 요약: agent-shell이 outbound proto-socket으로 control plane에 연결하고 command dispatch/heartbeat/log stream을 처리한다. +- [계획] Agent Shell Package and IOP Backend Boundary + - 경로: `agent-roadmap/phase/agent-shell-iop-execution/milestones/agent-shell-package-iop-backend-boundary.md` + - 요약: `../agent-shell`은 Flutter agent UI/package로 사용하고, backend/runtime owner는 `../iop` 프로젝트로 지정한다. - [계획] IOP Agent Run Bridge - 경로: `agent-roadmap/phase/agent-shell-iop-execution/milestones/iop-agent-run-bridge.md` - - 요약: IOP CLI를 workspace operation의 agent 실행 통로로 연결하고 run 결과를 Git operation과 event로 수렴시킨다. + - 요약: IOP backend가 수행한 agent run 결과를 Gito의 Git operation과 event 원장으로 수렴시키는 계약을 만든다. - [계획] Command Policy and Cancellation - 경로: `agent-roadmap/phase/agent-shell-iop-execution/milestones/command-policy-and-cancellation.md` - - 요약: command allowlist, timeout, cancel, dirty workspace guard, log redaction 기준을 실행 경계에 적용한다. + - 요약: IOP backend가 소유하는 command policy/cancel/log redaction 결과를 Gito operation state와 event로 반영하는 경계를 정한다. ## Phase 경계 -- agent-shell은 local workspace command 실행만 맡고 provider API 호출을 직접 소유하지 않는다. +- `../agent-shell`은 UI/package이며 local workspace command 실행 backend가 아니다. +- agent execution backend/runtime은 `../iop` 프로젝트가 소유한다. - IOP 내부 모델 라우팅, RAG, output validation은 Gito의 소유 범위가 아니다. -- control plane은 arbitrary shell command를 직접 실행하지 않고 agent-shell capability로 위임한다. +- control plane은 arbitrary shell command를 직접 실행하지 않고 IOP backend/runtime 결과를 Git control plane 계약으로 수렴한다. - provider-specific PR/MR 작업은 ChangeRequest adapter Phase에서 처리한다. - diff --git a/agent-roadmap/phase/agent-shell-iop-execution/milestones/agent-shell-package-iop-backend-boundary.md b/agent-roadmap/phase/agent-shell-iop-execution/milestones/agent-shell-package-iop-backend-boundary.md new file mode 100644 index 0000000..0028fe0 --- /dev/null +++ b/agent-roadmap/phase/agent-shell-iop-execution/milestones/agent-shell-package-iop-backend-boundary.md @@ -0,0 +1,73 @@ +# Milestone: Agent Shell Package and IOP Backend Boundary + +## 위치 + +- Roadmap: `agent-roadmap/ROADMAP.md` +- Phase: `agent-roadmap/phase/agent-shell-iop-execution/PHASE.md` + +## 목표 + +workspace 상위 sibling 프로젝트 `../agent-shell`을 제품 비종속 Flutter agent UI/package로 사용하는 방향을 확정한다. `agent_shell` package를 사용하는 host의 backend/runtime은 `../iop` 프로젝트로 지정하고, Gito는 agent backend를 직접 소유하지 않고 Git control plane 계약과 operation/event 경계를 제공한다. + +## 상태 + +[검토중] + +## 승격 조건 + +- 없음 + +## 구현 잠금 + +- 상태: 해제 +- 결정 필요: 없음 + +## 범위 + +- `../agent-shell` Flutter package 사용 방식 +- `../iop` backend/runtime owner 지정 +- Gito control plane과 IOP backend 사이의 Git operation/event 경계 +- Gito Flutter control surface가 `agent_shell` UI를 붙일 때의 책임 분리 +- 기존 Go `gito-shell` scaffold의 향후 정리 방향 + +## 기능 + +### Epic: [agent-shell-boundary] Agent shell package boundary + +`../agent-shell`은 embeddable UI/domain package로 사용하고, backend/runtime은 IOP 프로젝트가 담당하도록 경계를 정리한다. + +- [x] [package-use] Gito/host Flutter surface가 `agent_shell: path: ../agent-shell`로 UI package를 사용하는 방향을 문서화한다. +- [x] [iop-backend] `agent_shell` host의 backend/runtime owner를 `../iop` 프로젝트로 지정한다. +- [x] [gito-boundary] Gito는 agent execution backend가 아니라 repo/workspace/operation/event control plane을 제공한다는 경계를 contracts와 docs에 반영한다. +- [x] [scaffold-cleanup] 기존 Go `gito-shell`/`internal/agentshell` scaffold를 유지, rename, 제거 중 어떤 정리 경로로 둘지 후속 계획에 남긴다. 후속 계획: `agent-task/m-agent-shell-package-iop-backend-boundary/PLAN-local-G05.md` + +## 완료 리뷰 + +- 상태: 요청됨 +- 요청일: 2026-06-14 +- 완료 근거: + - `README.md`, `docs/architecture.md`, `apps/client/README.md`, `packages/contracts/notes/gito-control-plane.md`에 `agent_shell: path: ../agent-shell`, `../iop` backend/runtime owner, Gito control plane 경계를 반영했다. + - legacy Go `gito-shell`/`internal/agentshell` scaffold 정리는 active 후속 plan `agent-task/m-agent-shell-package-iop-backend-boundary/PLAN-local-G05.md`와 review stub로 남겼다. + - local smoke search와 `git diff --check`가 통과했다. +- 리뷰 필요: + - [ ] 사용자가 완료 결과를 확인했다 + - [ ] archive 이동을 승인했다 +- 리뷰 코멘트: 사용자 최종 확인 전까지 `[검토중]`으로 유지한다. + +## 범위 제외 + +- `../agent-shell` package 내부 widget/domain model 구현 +- IOP backend/Edge/Node 구현 +- IOP CLI invocation 세부 +- provider API 호출 +- Flutter runner management UX +- remote shell installation 자동화 + +## 작업 컨텍스트 + +- 관련 경로: `apps/client/`, `packages/contracts/notes/gito-control-plane.md`, `docs/architecture.md`, `README.md` +- 외부 프로젝트: `../agent-shell`은 Flutter UI/package, `../iop`는 agent backend/runtime owner다. +- 표준선(선택): Gito는 agent backend를 직접 구현하지 않고 IOP가 제공하는 runtime/backend와 Git control plane 계약으로 연결한다. +- 선행 작업: Operation Event Outbox +- 후속 작업: IOP Agent Run Bridge +- 확인 필요: 없음 diff --git a/agent-roadmap/phase/agent-shell-iop-execution/milestones/agent-shell-runtime-channel.md b/agent-roadmap/phase/agent-shell-iop-execution/milestones/agent-shell-runtime-channel.md deleted file mode 100644 index fe58023..0000000 --- a/agent-roadmap/phase/agent-shell-iop-execution/milestones/agent-shell-runtime-channel.md +++ /dev/null @@ -1,68 +0,0 @@ -# Milestone: Agent Shell Runtime Channel - -## 위치 - -- Roadmap: `agent-roadmap/ROADMAP.md` -- Phase: `agent-roadmap/phase/agent-shell-iop-execution/PHASE.md` - -## 목표 - -agent-shell이 runner machine에서 outbound proto-socket으로 control plane에 연결하고, heartbeat, capability registration, command dispatch, log stream을 처리한다. control plane은 연결된 shell에 workspace operation을 배정할 수 있어야 한다. - -## 상태 - -[계획] - -## 승격 조건 - -- 없음 - -## 구현 잠금 - -- 상태: 해제 -- 결정 필요: 없음 - -## 범위 - -- agent-shell identity와 capability model -- outbound proto-socket 연결 -- heartbeat와 runner 상태 event -- command dispatch request/response shape -- stdout/stderr log stream shape - -## 기능 - -### Epic: [shell-channel] Shell channel - -agent-shell과 control plane 사이의 runtime channel을 만든다. - -- [ ] [identity] `GITO_SHELL_ID`와 runner capability registration model을 확정한다. -- [ ] [heartbeat] shell heartbeat와 disconnect 상태를 operation event로 투영한다. 검증: fake shell disconnect가 runner offline event를 남긴다. -- [ ] [dispatch] command dispatch proto-socket action 후보를 구현한다. 검증: test shell이 no-op command request를 받고 response를 반환한다. -- [ ] [logs] stdout/stderr chunk stream shape를 정의하고 event stream에 연결한다. - -## 완료 리뷰 - -- 상태: 없음 -- 요청일: 없음 -- 완료 근거: 없음 -- 리뷰 필요: - - [ ] 사용자가 완료 결과를 확인했다 - - [ ] archive 이동을 승인했다 -- 리뷰 코멘트: 없음 - -## 범위 제외 - -- IOP CLI invocation 세부 -- provider API 호출 -- Flutter runner management UX -- remote shell installation 자동화 - -## 작업 컨텍스트 - -- 관련 경로: `services/core/internal/agentshell/`, `services/core/internal/controlplane/`, `services/core/internal/events/`, `packages/contracts/notes/gito-control-plane.md` -- 표준선(선택): runner는 가능하면 outbound connection으로 control plane에 붙는다. -- 선행 작업: Operation Event Outbox -- 후속 작업: IOP Agent Run Bridge -- 확인 필요: 없음 - diff --git a/agent-roadmap/phase/agent-shell-iop-execution/milestones/command-policy-and-cancellation.md b/agent-roadmap/phase/agent-shell-iop-execution/milestones/command-policy-and-cancellation.md index 88b6739..09b7828 100644 --- a/agent-roadmap/phase/agent-shell-iop-execution/milestones/command-policy-and-cancellation.md +++ b/agent-roadmap/phase/agent-shell-iop-execution/milestones/command-policy-and-cancellation.md @@ -7,7 +7,7 @@ ## 목표 -agent-shell command execution에 policy gate, timeout, cancellation, log redaction, dirty workspace guard를 적용한다. agent가 Git과 IOP를 사용할 수 있어도 destructive action은 명시된 policy와 operation state를 통해 제어되어야 한다. +`../iop` backend/runtime이 소유하는 command policy, timeout, cancellation, log redaction, dirty workspace guard 결과를 Gito operation state와 event로 반영하는 경계를 정한다. Gito는 arbitrary command 실행 backend를 직접 구현하지 않고, policy 결과와 Git workspace 결과를 원장에 수렴한다. ## 상태 @@ -26,30 +26,29 @@ agent-shell command execution에 policy gate, timeout, cancellation, log redacti ## 범위 -- command allowlist/denylist 후보 -- operation별 timeout과 cancellation -- signal handling -- dirty workspace guard -- stdout/stderr secret redaction +- IOP backend command allowlist/denylist 결과 수신 경계 +- operation별 timeout과 cancellation state mapping +- dirty workspace guard 결과 반영 +- stdout/stderr secret redaction 결과의 Gito 저장 정책 - failed/cancelled event 정책 ## 기능 -### Epic: [policy] Command policy +### Epic: [policy] Command policy result -agent-shell이 실행할 수 있는 command 범위와 승인 조건을 제어한다. +IOP backend가 소유하는 command policy 결과를 Gito operation/event 원장에 반영한다. -- [ ] [allowlist] Git/IOP 중심 command allowlist를 정의한다. -- [ ] [destructive] destructive command는 policy gate 없이는 실행하지 않도록 막는다. 검증: deny 대상 command가 rejected event를 남긴다. -- [ ] [redaction] log stream에서 credential-like token을 redaction한다. +- [ ] [allowlist] Git/IOP 중심 command allowlist의 source of truth를 IOP backend로 두고 Gito에는 결과 계약만 남긴다. +- [ ] [destructive] destructive command 거부 결과가 rejected event로 수렴한다. 검증: fake IOP policy rejection이 rejected event를 남긴다. +- [ ] [redaction] redacted log chunk만 Gito event/log 저장 경계로 들어오도록 계약을 정리한다. ### Epic: [control] Timeout and cancel -긴 실행을 제어하고 중단 결과를 원장에 남긴다. +긴 실행의 중단 결과를 Gito operation 원장에 남긴다. -- [ ] [timeout] operation timeout을 command context에 적용한다. -- [ ] [cancel] running command cancel request를 처리한다. 검증: fake long command가 cancel 후 `cancelled` state로 종료된다. -- [ ] [dirty] command 종료 후 workspace dirty state를 lease에 반영한다. +- [ ] [timeout] IOP timeout 결과를 Gito operation state와 event로 매핑한다. +- [ ] [cancel] running operation cancel request/result를 처리한다. 검증: fake IOP cancel result가 `cancelled` state로 종료된다. +- [ ] [dirty] IOP/Git 결과가 보고한 workspace dirty state를 lease에 반영한다. ## 완료 리뷰 @@ -67,12 +66,12 @@ agent-shell이 실행할 수 있는 command 범위와 승인 조건을 제어한 - secret manager 구현 - provider permission API - UI approval workflow +- IOP backend 내부 command runner 구현 ## 작업 컨텍스트 -- 관련 경로: `services/core/internal/agentshell/`, `services/core/internal/worker/`, `services/core/internal/events/` -- 표준선(선택): policy는 allow by explicit capability, deny by default 방향을 따른다. +- 관련 경로: `services/core/internal/worker/`, `services/core/internal/events/`, `packages/contracts/notes/gito-control-plane.md` +- 표준선(선택): policy source of truth는 IOP backend이고, Gito는 explicit capability/result만 받아 원장에 남긴다. - 선행 작업: IOP Agent Run Bridge - 후속 작업: Provider Adapter Foundation - 확인 필요: command allowlist와 redaction 기준 - diff --git a/agent-roadmap/phase/agent-shell-iop-execution/milestones/iop-agent-run-bridge.md b/agent-roadmap/phase/agent-shell-iop-execution/milestones/iop-agent-run-bridge.md index 7bc4fbc..8fc17e3 100644 --- a/agent-roadmap/phase/agent-shell-iop-execution/milestones/iop-agent-run-bridge.md +++ b/agent-roadmap/phase/agent-shell-iop-execution/milestones/iop-agent-run-bridge.md @@ -7,7 +7,7 @@ ## 목표 -IOP CLI를 agent-shell command execution 경계에 연결해 workspace 안에서 agent-driven Git 작업을 수행한다. IOP run은 operation lifecycle과 Git revision event로 수렴해야 하며, 성공 기준은 구조화 응답이 아니라 workspace의 실제 Git 상태와 push 결과로 확인한다. +`../iop` backend/runtime이 수행한 agent run을 Gito의 workspace operation과 Git revision event로 수렴시키는 계약을 만든다. `../agent-shell`은 host UI/package로 남고, 실제 backend 실행과 IOP CLI/Edge/Node orchestration은 IOP 프로젝트가 소유한다. 성공 기준은 구조화 응답이 아니라 workspace의 실제 Git 상태와 push 결과로 확인한다. ## 상태 @@ -26,8 +26,8 @@ IOP CLI를 agent-shell command execution 경계에 연결해 workspace 안에서 ## 범위 -- IOP CLI invocation contract -- workspace path, repo context, operation instruction 전달 +- IOP backend invocation/result contract +- workspace path, repo context, operation instruction 전달 경계 - agent run state model - IOP run success/failure 판정 - run 이후 Git status/diff/commit/push와 revision scan 연결 @@ -36,10 +36,10 @@ IOP CLI를 agent-shell command execution 경계에 연결해 workspace 안에서 ### Epic: [iop-run] IOP execution -IOP CLI를 workspace operation 실행 통로로 연결한다. +IOP backend를 workspace operation 실행 통로로 연결한다. - [ ] [input] repo, branch, workspace path, user instruction, policy context를 IOP 입력으로 전달하는 형식을 정한다. -- [ ] [invoke] agent-shell이 IOP CLI를 실행하고 stdout/stderr를 stream한다. 검증: fake IOP command가 expected input을 받고 operation log를 남긴다. +- [ ] [invoke] Gito가 직접 IOP CLI를 실행하지 않고 IOP backend invocation/result 계약을 호출하거나 수신하는 형식을 정한다. 검증: fake IOP backend result가 operation log를 남긴다. - [ ] [state] `queued`, `running`, `succeeded`, `failed`, `cancelled` run state를 operation lifecycle에 매핑한다. - [ ] [result] run 이후 Git status와 revision diff로 성공 여부를 확인한다. @@ -64,15 +64,15 @@ agent run 결과를 Git revision과 operation event로 수렴한다. ## 범위 제외 - IOP 내부 모델 라우팅 +- `../agent-shell` package 내부 UI/domain 구현 - provider PR/MR 생성 - Plane/Jira work item lifecycle - Flutter UI ## 작업 컨텍스트 -- 관련 경로: `services/core/internal/agentshell/`, `services/core/internal/worker/`, `services/core/internal/gitengine/`, `services/core/internal/events/` +- 관련 경로: `services/core/internal/worker/`, `services/core/internal/gitengine/`, `services/core/internal/events/`, `packages/contracts/notes/gito-control-plane.md` - 표준선(선택): IOP run 결과는 Git 상태와 operation event로 검증한다. -- 선행 작업: Agent Shell Runtime Channel +- 선행 작업: Agent Shell Package and IOP Backend Boundary - 후속 작업: Command Policy and Cancellation -- 확인 필요: IOP CLI invocation contract - +- 확인 필요: IOP backend invocation/result contract diff --git a/agent-roadmap/phase/control-plane-foundation/PHASE.md b/agent-roadmap/phase/control-plane-foundation/PHASE.md index b6f6710..394d6d0 100644 --- a/agent-roadmap/phase/control-plane-foundation/PHASE.md +++ b/agent-roadmap/phase/control-plane-foundation/PHASE.md @@ -26,14 +26,14 @@ Gito의 초기 control plane을 build 가능한 modular monolith로 구성한다 - 경로: `agent-roadmap/archive/phase/control-plane-foundation/milestones/platformless-git-operation-engine.md` - 요약: clone, fetch, status, diff, commit, push, revision scan을 provider 없이 local bare repo 기반으로 검증한다. +- [완료] Operation Event Outbox + - 경로: `agent-roadmap/archive/phase/control-plane-foundation/milestones/operation-event-outbox.md` + - 요약: operation lifecycle, idempotency, audit event, outbox 발행을 PostgreSQL 기준으로 구성한다. + - [검토중] Runtime Scaffold and Contract Baseline - 경로: `agent-roadmap/phase/control-plane-foundation/milestones/runtime-scaffold-and-contract-baseline.md` - 요약: Go command, Flutter control surface placeholder, contracts, agent-ops, README, architecture 문서를 실행 가능한 기준선으로 정리한다. -- [검토중] Operation Event Outbox - - 경로: `agent-roadmap/phase/control-plane-foundation/milestones/operation-event-outbox.md` - - 요약: operation lifecycle, idempotency, audit event, outbox 발행을 PostgreSQL 기준으로 구성한다. - ## Phase 경계 - 이 Phase는 Gito 자체 control plane과 platformless Git 기반만 다룬다. diff --git a/agent-task/m-agent-shell-package-iop-backend-boundary/CODE_REVIEW-local-G05.md b/agent-task/m-agent-shell-package-iop-backend-boundary/CODE_REVIEW-local-G05.md new file mode 100644 index 0000000..50e78ae --- /dev/null +++ b/agent-task/m-agent-shell-package-iop-backend-boundary/CODE_REVIEW-local-G05.md @@ -0,0 +1,150 @@ + + +# Code Review Reference - REFACTOR + +> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.** +> The task is NOT complete until every implementation-owned section below is filled in. +> Complete the `구현 체크리스트`; the final checklist item is mandatory before saving. +> Fill implementation-owned sections, then stop with active files in place and report ready for review. +> If implementation is blocked by a user-only decision, user-owned external environment prerequisite, or scope conflict, fill `사용자 리뷰 요청` with evidence and stop with active files in place; code-review decides whether to write `USER_REVIEW.md`. Evidence gaps that a follow-up agent can close by rerunning commands or collecting artifacts are normal follow-up issues, not user-review blockers by themselves. +> Do not ask the user directly, present choices in chat, or call `request_user_input` during implementation; record the needed decision in `사용자 리뷰 요청` and stop for code-review. +> Finalization (`코드리뷰 결과`, log rename, `complete.log`, archive moves, `코드리뷰 전용 체크리스트`) is review-agent-only, even after compaction/resume. +> Follow the ownership table at the bottom of this file for which sections you own. + +## 개요 + +date=2026-06-14 +task=m-agent-shell-package-iop-backend-boundary, plan=0, tag=REFACTOR + +## 이 파일을 읽는 리뷰 에이전트에게 + +> **[REVIEW AGENT ONLY]** 아래 종결 절차는 코드리뷰 에이전트 전용이다. 구현 에이전트는 이 섹션을 실행하지 않는다. + +각 항목의 구현을 실제 소스 파일과 대조하고, `검증 결과` 섹션의 출력이 코드와 일치하는지 확인하세요. +리뷰 완료는 아래 순서까지 끝난 상태를 의미합니다. + +1. 판정을 append한다. +2. `CODE_REVIEW-local-G05.md` → `code_review_local_G05_N.log`, `PLAN-local-G05.md` → `plan_local_G05_M.log`로 아카이브한다. +3. PASS이면 `complete.log` 작성 후 active task 디렉터리를 `agent-task/archive/YYYY/MM/m-agent-shell-package-iop-backend-boundary/`로 이동한다. WARN/FAIL이면 user-review gate를 확인한 뒤 다음 active plan/review 파일 또는 `USER_REVIEW.md`를 작성한다. `USER_REVIEW.md`가 사용자 결정으로 완료/PASS 해소되면 code-review가 `USER_REVIEW.md`를 해소 상태로 갱신하고 `complete.log` 작성 후 archive 이동한다. +4. PASS이고 task group이 `m-`이면 완료 이벤트 메타데이터를 보고한다. roadmap 상태 체크와 `update-roadmap` 호출은 런타임 책임이다. +5. 적용 가능한 `코드리뷰 전용 체크리스트` 항목을 최종 `.log` 위치에서 체크한 뒤 보고한다. + +--- + +## 구현 항목별 완료 여부 + +| 항목 | 완료 여부 | +|------|---------| +| [REFACTOR-1] Legacy shell scaffold cleanup | [ ] | + +## 구현 체크리스트 + +- [ ] `gito-shell`/`internal/agentshell` 정리 전략을 compatibility placeholder 유지, command 제거, rename 중 하나로 확정하고 코드와 docs에 일관되게 적용한다. +- [ ] 선택한 전략에 맞춰 `bin/build`, `services/core/cmd/shell/main.go`, `services/core/internal/agentshell/shell.go`, `services/core/internal/config/config.go`, `services/core/internal/config/config_test.go`를 정리한다. +- [ ] README, architecture, contract notes, domain rule에서 legacy shell wording과 build artifact 목록을 실제 상태와 맞춘다. +- [ ] `rg --sort path -n "gito-shell|cmd/shell|internal/agentshell|agent shell scaffold|GITO_SHELL_ID|agentshell" . -g '!agent-task/archive/**' -g '!agent-roadmap/archive/**' -g '!agent-test/local/**'`로 남은 참조가 의도된 예외뿐인지 확인한다. +- [ ] `cd services/core && go test ./...`와 `bin/build`를 실행한다. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +## 코드리뷰 전용 체크리스트 + +> **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다. +> 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다. + +- [ ] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다. +- [ ] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다. +- [ ] active `CODE_REVIEW-*-G??.md`를 `code_review_local_G05_N.log`로 아카이브한다. +- [ ] active `PLAN-*-G??.md`를 `plan_local_G05_M.log`로 아카이브한다. +- [ ] `.gitignore`의 Agent-Ops 관리 block이 `agent-task/**/*.md`와 `agent-task/**/*.log`를 unignore하고 `agent-roadmap/current.md`를 ignore하는지 확인한다. +- [ ] PASS이면 `agent-ops/skills/common/code-review/templates/complete-log-template.md` 기준으로 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다. +- [ ] PASS이면 active task 디렉터리 `agent-task/m-agent-shell-package-iop-backend-boundary/`를 `agent-task/archive/YYYY/MM/m-agent-shell-package-iop-backend-boundary/`로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다. +- [ ] PASS이고 task group이 `m-`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다. +- [ ] PASS split 작업이면 이동 후 빈 active parent `agent-task/m-agent-shell-package-iop-backend-boundary/`를 제거하거나, 남은 sibling/file이 있어 유지했다고 확인한다. +- [ ] WARN/FAIL이고 user-review gate가 트리거되지 않았으면 다음 active `PLAN-local-G05.md`와 `CODE_REVIEW-local-G05.md`를 작성하고 `complete.log`를 작성하지 않는다. +- [ ] USER_REVIEW이면 `agent-ops/skills/common/code-review/templates/user-review-template.md` 기준으로 `USER_REVIEW.md`를 작성하고 active `PLAN-*.md`, `CODE_REVIEW-*.md`, `complete.log`를 남기지 않는다. +- [ ] USER_REVIEW가 사용자 결정으로 완료/PASS 해소되면 `USER_REVIEW.md`를 해소 상태로 갱신하고 `complete.log`를 작성한 뒤 task directory를 archive로 이동한다. + +## 계획 대비 변경 사항 + +_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._ + +## 주요 설계 결정 + +_구현 에이전트가 주요 설계 결정 사항을 기록한다._ + +## 사용자 리뷰 요청 + +_기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외부 환경/secret/서비스 준비, 또는 계획 범위 변경 없이는 안전하게 진행할 수 없으면 아래 항목을 실제 내용으로 교체하고, 구현을 중단한 뒤 active 파일을 그대로 둔 채 리뷰를 요청한다. 구현 에이전트는 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하지 않는다. 후속 에이전트가 명령 재실행이나 산출물 수집으로 해소할 수 있는 검증 증거 공백만으로는 사용자 리뷰 요청을 작성하지 않는다._ + +- 상태: 없음 +- 사유 유형: 없음 +- 결정 필요: 없음 +- 차단 근거: 없음 +- 실행한 검증/명령: 없음 +- 자동 후속 불가 이유: 없음 +- 재개 조건: 없음 + +## 리뷰어를 위한 체크포인트 + +- `gito-shell`, `cmd/shell`, `internal/agentshell`, `GITO_SHELL_ID` 남은 참조가 모두 의도된 예외인지 확인한다. +- `bin/build` 산출물과 README build artifact 목록이 일치하는지 확인한다. +- `../agent-shell`/`../iop` 경계가 docs와 contracts에서 유지되는지 확인한다. +- `cd services/core && go test ./...`와 `bin/build` 출력이 실제 코드 상태와 일치하는지 확인한다. + +## 검증 결과 + +_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._ + +필수 규칙: +- 검증 명령은 고정된 계약이다. 임의로 대체하지 않는다. +- 대체가 필요하면 `계획 대비 변경 사항`에 이유와 대체 명령을 기록한다. +- `검증 결과`에는 실제 stdout/stderr를 붙여 넣는다. +- 사용자 리뷰 요청으로 명령을 끝까지 실행하지 못했다면 `사용자 리뷰 요청`에 실행한 명령, 실제 출력, 미실행 명령의 사유를 기록한다. +- mobile/UI hang, timeout, 또는 2분 무진행은 blind retry를 중단하고 focused rerun 명령과 screenshot/window/UI-tree evidence path를 남기며, 불가능하면 정확한 사유를 남긴다. + +### REFACTOR-1 중간 검증 +``` +$ rg --sort path -n "gito-shell|cmd/shell|internal/agentshell|agent shell scaffold|GITO_SHELL_ID|agentshell" . -g '!agent-task/archive/**' -g '!agent-roadmap/archive/**' -g '!agent-test/local/**' +(output) + +$ cd services/core && go test ./... +(output) + +$ bin/build +(output) +``` + +### 최종 검증 +``` +$ rg --sort path -n "gito-shell|cmd/shell|internal/agentshell|agent shell scaffold|GITO_SHELL_ID|agentshell" . -g '!agent-task/archive/**' -g '!agent-roadmap/archive/**' -g '!agent-test/local/**' +(output) + +$ cd services/core && go test ./... +(output) + +$ bin/build +(output) + +$ rg --sort path -n "Gito|agent-shell|agent_shell|iop|gito-shell|control plane" README.md docs packages/contracts agent-roadmap -g '!agent-roadmap/archive/**' +(output) +``` + +--- + +> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section: completion table, implementation checklist, changes from plan, design decisions, and verification output?** +> If anything is blank, go back and fill it in before saving this file. +> Leave review-agent-only sections unchanged. + +Sections and their ownership: + +| Section | Owner | Note | +|---------|-------|------| +| Header comment, 개요, 리뷰 에이전트 지시 | Fixed at stub creation | Implementing agent must not modify or execute these (archive, complete.log, and task-directory archive move are review-agent only) | +| 구현 항목별 완료 여부 (item names) | Fixed at stub creation | Implementing agent checks `[ ]` -> `[x]` only | +| 구현 체크리스트 (item text/order) | Fixed at stub creation from plan | Implementing agent checks `[ ]` -> `[x]` only; final checkbox is mandatory before saving | +| 코드리뷰 전용 체크리스트 | Review agent only | Implementing agent must not modify or check this section | +| 계획 대비 변경 사항, 주요 설계 결정 | Implementing agent | Replace placeholder text with actual content | +| 사용자 리뷰 요청 | Implementing agent | Keep `상태: 없음` unless user input is required to proceed; do not ask the user directly during implementation; when filled, include exact decision, evidence, commands/output, why automatic follow-up cannot resolve it, and resume condition | +| 리뷰어를 위한 체크포인트 | Fixed at stub creation | Pre-filled from plan | +| 검증 결과 (section headings + commands) | Fixed at stub creation | Implementing agent fills in command output only; command changes require a `계획 대비 변경 사항` entry | +| 코드리뷰 결과 | Review agent appends | Not included in stub | diff --git a/agent-task/m-agent-shell-package-iop-backend-boundary/PLAN-local-G05.md b/agent-task/m-agent-shell-package-iop-backend-boundary/PLAN-local-G05.md new file mode 100644 index 0000000..df1bf2a --- /dev/null +++ b/agent-task/m-agent-shell-package-iop-backend-boundary/PLAN-local-G05.md @@ -0,0 +1,197 @@ + + +# Plan - REFACTOR Scaffold Cleanup + +## 이 파일을 읽는 구현 에이전트에게 + +`CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션 작성은 필수다. 구현 후 검증을 실행하고 실제 변경 내용, 검증 출력, 계획 대비 변경 사항을 채운 뒤 active 파일을 그대로 두고 리뷰 준비 상태를 보고한다. 최종 판정, log archive, `complete.log` 작성, task directory archive 이동은 code-review 스킬 전용이다. 구현 중 사용자 결정, 사용자 소유 외부 환경, scope conflict 없이는 진행할 수 없으면 review stub의 `사용자 리뷰 요청` 섹션에 정확한 근거를 남기고 중단한다. 구현 에이전트는 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`, `USER_REVIEW.md`, `complete.log`, archive 이동을 수행하지 않는다. 후속 에이전트가 재실행이나 증거 수집으로 닫을 수 있는 검증 공백은 사용자 리뷰 요청이 아니다. + +## 배경 + +현재 마일스톤은 `../agent-shell`을 Flutter UI/package로, `../iop`를 backend/runtime owner로 정리한다. Gito에는 아직 `gito-shell` command와 `internal/agentshell` scaffold가 남아 있어 README, build artifact, config가 새 책임 경계와 어긋날 수 있다. 이 계획은 legacy scaffold를 제거하거나 compatibility placeholder로 축소하는 정리 경로를 구현 단위로 고정한다. + +## 사용자 리뷰 요청 흐름 + +구현 중 blocker는 active review stub의 `사용자 리뷰 요청` 섹션에 기록한다. 해당 섹션은 `agent-ops/skills/common/_templates/implementation-user-review-request-section.md` 형식을 따른다. 구현 에이전트는 직접 사용자 프롬프트를 만들지 않고, code-review가 사용자 리뷰 필요성을 검증하고 실제 `USER_REVIEW.md` 작성을 담당한다. + +## 분석 결과 + +### 읽은 파일 + +- `agent-ops/rules/project/rules.md` +- `agent-ops/rules/project/domain/core/rules.md` +- `agent-ops/rules/project/domain/workspace-ops/rules.md` +- `agent-ops/rules/project/domain/contracts/rules.md` +- `agent-ops/rules/project/domain/client/rules.md` +- `agent-ops/rules/common/rules-roadmap.md` +- `agent-ops/skills/common/plan/SKILL.md` +- `agent-ops/skills/common/create-test/SKILL.md` +- `agent-ops/skills/common/_templates/implementation-user-review-request-section.md` +- `agent-roadmap/current.md` +- `agent-roadmap/phase/agent-shell-iop-execution/PHASE.md` +- `agent-roadmap/phase/agent-shell-iop-execution/milestones/agent-shell-package-iop-backend-boundary.md` +- `agent-contract/index.md` +- `agent-test/local/rules.md` +- `agent-test/local/core-smoke.md` +- `agent-test/local/workspace-ops-smoke.md` +- `README.md` +- `docs/architecture.md` +- `packages/contracts/notes/gito-control-plane.md` +- `apps/client/README.md` +- `bin/build` +- `bin/test` +- `bin/lint` +- `services/core/go.mod` +- `apps/client/pubspec.yaml` +- `services/core/cmd/shell/main.go` +- `services/core/internal/agentshell/shell.go` +- `services/core/internal/config/config.go` +- `services/core/internal/config/config_test.go` + +### 테스트 환경 규칙 + +- test_env: `local` +- `agent-test/local/rules.md`는 기존 tracked 규칙을 보존한 상태로 읽었다. +- 라우팅된 smoke profile 문서들은 작업 시작 시 worktree에 없어서 create-test 흐름으로 local profile baseline을 생성한 뒤 읽었다. +- 매칭 profile: + - `agent-test/local/core-smoke.md`: Go scaffold 변경은 `cd services/core && go test ./...`를 필수 검증으로 둔다. + - `agent-test/local/workspace-ops-smoke.md`: README/docs/bin 변경은 `rg --sort path -n "Gito|agent-shell|agent_shell|iop|gito-shell|control plane" README.md docs packages/contracts agent-roadmap -g '!agent-roadmap/archive/**'` smoke를 둔다. +- fallback verification: `bin/build`는 README와 build artifact 계약을 직접 검증하기 위해 추가한다. +- `<확인 필요>` 값: 없음. + +### 테스트 커버리지 공백 + +- `gito-shell` command 제거/rename은 기존 unit test가 직접 보장하지 않는다. `bin/build`와 `cd services/core && go test ./...`로 compile break를 잡는다. +- `GITO_SHELL_ID` 제거 여부는 `services/core/internal/config/config_test.go`를 갱신해야 보장된다. +- README/docs 계약 문구는 automated assertion이 없으므로 deterministic `rg --sort path` smoke와 reviewer inspection으로 확인한다. + +### 심볼 참조 + +- `agentshell`: `services/core/cmd/shell/main.go`, `services/core/internal/agentshell/shell.go`, `agent-ops/rules/project/domain/core/rules.md`, roadmap references. +- `gito-shell`: `README.md`, `bin/build`, roadmap references. +- `GITO_SHELL_ID`: `README.md`, `services/core/internal/config/config.go`, `services/core/internal/config/config_test.go`. +- 변경 전 `rg --sort path -n "gito-shell|cmd/shell|internal/agentshell|agent shell scaffold|GITO_SHELL_ID|agentshell" . -g '!agent-task/archive/**' -g '!agent-roadmap/archive/**' -g '!agent-test/local/**'`를 다시 실행해 call site를 확정한다. + +### 분할 판단 + +- split decision policy를 먼저 평가했다. +- 이 plan은 단일 active plan으로 둔다. 핵심 변경은 legacy shell scaffold 정리 하나이며, `bin/build`, Go config, README/docs가 같은 compatibility 결정을 공유한다. +- core와 workspace-ops를 함께 건드리지만 변경은 legacy artifact 제거/rename에 따른 기계적 동기화다. core만 먼저 바꾸면 README/build 문서가 깨지고, docs만 먼저 바꾸면 실제 binary 계약과 어긋난다. +- API/foundation 대 call-site rollout, migration, storage, auth, concurrency split은 없다. + +### 범위 결정 근거 + +- `../agent-shell` package 내부와 `../iop` backend 구현은 제외한다. +- provider adapter, proto-socket action 구현, operation/event bridge 구현은 후속 Milestone 범위다. +- 이번 plan은 `gito-shell`/`internal/agentshell` scaffold와 그 직접 참조만 정리한다. +- `agent-ops/rules/project/domain/core/rules.md`의 "Agent command execution belongs in internal/agentshell" 문구는 실제 scaffold 정리 후 같은 구현에서 함께 갱신해야 한다. + +### 빌드 등급 + +- `local-G05`: bounded legacy scaffold cleanup이며 compile/search 검증으로 review 가능하지만, build artifact와 docs 계약이 같이 움직여 중간 정도 주의가 필요하다. + +## 구현 체크리스트 + +- [ ] `gito-shell`/`internal/agentshell` 정리 전략을 compatibility placeholder 유지, command 제거, rename 중 하나로 확정하고 코드와 docs에 일관되게 적용한다. +- [ ] 선택한 전략에 맞춰 `bin/build`, `services/core/cmd/shell/main.go`, `services/core/internal/agentshell/shell.go`, `services/core/internal/config/config.go`, `services/core/internal/config/config_test.go`를 정리한다. +- [ ] README, architecture, contract notes, domain rule에서 legacy shell wording과 build artifact 목록을 실제 상태와 맞춘다. +- [ ] `rg --sort path -n "gito-shell|cmd/shell|internal/agentshell|agent shell scaffold|GITO_SHELL_ID|agentshell" . -g '!agent-task/archive/**' -g '!agent-roadmap/archive/**' -g '!agent-test/local/**'`로 남은 참조가 의도된 예외뿐인지 확인한다. +- [ ] `cd services/core && go test ./...`와 `bin/build`를 실행한다. +- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. + +### [REFACTOR-1] Legacy shell scaffold cleanup + +#### 문제 + +- [README.md](/config/workspace/gito/README.md:46)는 build output에 `bin/gito-shell`을 포함한다. +- [bin/build](/config/workspace/gito/bin/build:10)는 `./cmd/shell`을 `bin/gito-shell`로 빌드한다. +- [services/core/cmd/shell/main.go](/config/workspace/gito/services/core/cmd/shell/main.go:7)는 `internal/agentshell`을 import하고 실행한다. +- [services/core/internal/agentshell/shell.go](/config/workspace/gito/services/core/internal/agentshell/shell.go:18)는 scaffold ready log만 남긴다. +- [services/core/internal/config/config.go](/config/workspace/gito/services/core/internal/config/config.go:18)는 shell-only `ShellID`를 전역 config에 둔다. + +#### 해결 방법 + +기본 구현 방향은 legacy command 제거다. `../iop`가 backend/runtime owner이므로 Gito root build artifact에서 `gito-shell`을 제거하고, `cmd/shell`, `internal/agentshell`, `GITO_SHELL_ID`를 삭제한다. 단, 구현 중 active compatibility consumer가 발견되면 사용자에게 직접 묻지 말고 review stub의 `사용자 리뷰 요청`에 compatibility 유지가 필요한 근거를 남긴다. + +Before: + +```sh +# bin/build:8-10 +(cd "$ROOT_DIR/services/core" && go build -o "$OUT_DIR/gito-server" ./cmd/server) +(cd "$ROOT_DIR/services/core" && go build -o "$OUT_DIR/gito-worker" ./cmd/worker) +(cd "$ROOT_DIR/services/core" && go build -o "$OUT_DIR/gito-shell" ./cmd/shell) +``` + +After: + +```sh +(cd "$ROOT_DIR/services/core" && go build -o "$OUT_DIR/gito-server" ./cmd/server) +(cd "$ROOT_DIR/services/core" && go build -o "$OUT_DIR/gito-worker" ./cmd/worker) +``` + +Before: + +```go +// services/core/internal/config/config.go:17-18 +WorkerEnabled bool +ShellID string +``` + +After: + +```go +WorkerEnabled bool +``` + +#### 수정 파일 및 체크리스트 + +- [ ] `bin/build`: `gito-shell` build step 제거. +- [ ] `services/core/cmd/shell/main.go`: command 제거 또는 compatibility 유지가 필요하면 명시적 deprecation command로 축소. +- [ ] `services/core/internal/agentshell/shell.go`: package 제거 또는 deprecation-only package로 축소. +- [ ] `services/core/internal/config/config.go`: `ShellID`와 `GITO_SHELL_ID` load 제거. +- [ ] `services/core/internal/config/config_test.go`: shell env override assertion 제거. +- [ ] `README.md`: build artifact, structure table, environment variable table, current scope wording 갱신. +- [ ] `docs/architecture.md`: Gito가 arbitrary shell command를 직접 실행하지 않는다는 경계를 유지하고 legacy command 상태를 반영. +- [ ] `packages/contracts/notes/gito-control-plane.md`: `agent_shell` placeholder 문구가 실제 compatibility 상태와 맞는지 확인. +- [ ] `agent-ops/rules/project/domain/core/rules.md`: `internal/agentshell` 소유권 문구를 실제 구조에 맞게 갱신. + +#### 테스트 작성 + +- 새 테스트는 작성하지 않는다. 제거/rename은 compile, config unit test 갱신, deterministic reference search로 검증한다. + +#### 중간 검증 + +```sh +rg --sort path -n "gito-shell|cmd/shell|internal/agentshell|agent shell scaffold|GITO_SHELL_ID|agentshell" . -g '!agent-task/archive/**' -g '!agent-roadmap/archive/**' -g '!agent-test/local/**' +cd services/core && go test ./... +bin/build +``` + +Expected: search output은 의도된 compatibility/roadmap references만 남고, Go tests와 build는 exit 0. + +## 수정 파일 요약 + +| 파일 | 항목 | +| --- | --- | +| `bin/build` | REFACTOR-1 | +| `services/core/cmd/shell/main.go` | REFACTOR-1 | +| `services/core/internal/agentshell/shell.go` | REFACTOR-1 | +| `services/core/internal/config/config.go` | REFACTOR-1 | +| `services/core/internal/config/config_test.go` | REFACTOR-1 | +| `README.md` | REFACTOR-1 | +| `docs/architecture.md` | REFACTOR-1 | +| `packages/contracts/notes/gito-control-plane.md` | REFACTOR-1 | +| `agent-ops/rules/project/domain/core/rules.md` | REFACTOR-1 | + +## 최종 검증 + +```sh +rg --sort path -n "gito-shell|cmd/shell|internal/agentshell|agent shell scaffold|GITO_SHELL_ID|agentshell" . -g '!agent-task/archive/**' -g '!agent-roadmap/archive/**' -g '!agent-test/local/**' +cd services/core && go test ./... +bin/build +rg --sort path -n "Gito|agent-shell|agent_shell|iop|gito-shell|control plane" README.md docs packages/contracts agent-roadmap -g '!agent-roadmap/archive/**' +``` + +Expected: only intentional legacy/roadmap references remain; Go tests pass; `bin/build` produces the documented binaries; docs smoke exits 0. Go test cache output is acceptable because this is a compile/reference cleanup, not timing-sensitive behavior. + +모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다. diff --git a/apps/client/README.md b/apps/client/README.md index 9fd2e78..be9a2f7 100644 --- a/apps/client/README.md +++ b/apps/client/README.md @@ -6,3 +6,15 @@ The first slice keeps the client scaffold light. It should consume Gito through proto-socket for operation requests, event streams, and log streams. REST is only for health/readiness and operational compatibility endpoints. +Agent interaction UI should come from the sibling Flutter package: + +```yaml +dependencies: + agent_shell: + path: ../agent-shell +``` + +That package is UI/domain surface only. The backend/runtime for agent execution, +shell command execution, command policy, cancellation, and log redaction belongs +to the sibling `../iop` project. Gito's client should treat Gito as the Git +control surface and operation/event stream, not as the agent runtime backend. diff --git a/docs/architecture.md b/docs/architecture.md index 3b0e1c6..c1d32e3 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -1,8 +1,10 @@ # Architecture Gito starts as a modular monolith with separable process roles. The codebase can -run as one service at first, but its boundaries should allow separate server, -worker, and shell deployments later. +run as one service at first, but its boundaries should allow separate server and +worker deployments later. Agent interaction UI is provided by the sibling +`../agent-shell` Flutter package, and the agent backend/runtime is owned by the +sibling `../iop` project. ## Layers @@ -26,16 +28,20 @@ worker, and shell deployments later. - Picks pending operations. - Coordinates workspace leases. -- Calls agent-shell for filesystem and command execution. +- Coordinates with the IOP backend/runtime for agent execution results. - Records operation outcomes and emits events. - Handles retry and backoff policy. -### Agent Shell +### Agent Shell Package And IOP Backend -- Runs on a machine that owns local workspace access. -- Executes Git CLI and IOP CLI commands. -- Streams logs, handles cancellation, and enforces dirty-workspace guards. -- Connects outbound to the control plane where possible. +- `../agent-shell` is a product-agnostic Flutter UI/domain package. +- Flutter hosts attach it as an `agent_shell: path: ../agent-shell` package + dependency rather than treating Gito as the agent UI package. +- `../iop` owns the backend/runtime that executes agents, shell commands, and + model/runtime orchestration. +- Gito does not execute arbitrary workspace commands directly. +- Gito records IOP backend results as operation state, Git revision, and event + records. ### Git Engine diff --git a/packages/contracts/notes/gito-control-plane.md b/packages/contracts/notes/gito-control-plane.md index d05806f..a56ee28 100644 --- a/packages/contracts/notes/gito-control-plane.md +++ b/packages/contracts/notes/gito-control-plane.md @@ -16,7 +16,7 @@ | `operation` | Create, cancel, inspect, and stream operations. | | `git` | Request platformless Git operations. | | `change_request` | Manage provider-neutral PR/MR operations. | -| `agent_shell` | Shell heartbeat, command dispatch, and log streaming. | +| `agent_shell` | Reserved/legacy shell scaffold metadata; canonical agent UI is `../agent-shell` and backend/runtime is `../iop`. | | `event` | Subscribe to normalized events. | ## proto-socket Action Registry Scaffold @@ -32,7 +32,7 @@ own Milestone wires storage, worker, or provider behavior. | `operation` | `create`, `cancel`, `get`, `stream` | | `git` | `clone`, `fetch`, `status`, `diff`, `commit`, `push` | | `change_request` | `open`, `update`, `list` | -| `agent_shell` | `heartbeat`, `dispatch`, `stream_logs` | +| `agent_shell` | `heartbeat`, `dispatch`, `stream_logs` remain placeholder-only until an explicit compatibility Milestone scopes them. | | `event` | `subscribe`, `list`, `ack` | ## REST Bootstrap Exceptions @@ -42,6 +42,22 @@ proto-socket `repo` channel is still placeholder-only. Those helpers must stay limited to bootstrap registration, lookup, and listing, and must use the same Repo DTO fields documented below. +## Agent Shell / IOP Boundary + +`../agent-shell` is the product-agnostic Flutter package for agent interaction +UI and domain models. It is not the Gito backend. Hosts that use that package +should depend on it as `agent_shell: path: ../agent-shell` and route +agent runtime/backend behavior through the sibling `../iop` project. + +Gito's responsibility is the Git control plane boundary: repository registry, +workspace leases, operations, revision events, durable event records, and +provider-neutral Git results. IOP owns agent execution, shell command execution, +model/runtime routing, command policy, cancellation, and log redaction source of +truth. Gito may persist IOP results only after they are expressed as operation +state, Git revision/diff, workspace lease state, or normalized event records. +Gito must not expose a competing agent execution API from this contract note +unless a later Milestone explicitly defines an IOP bridge contract. + ## MVP: Forgejo Branch Event Flow Forgejo branch event delivery is now a provided contract: diff --git a/services/core/internal/storage/postgres_test.go b/services/core/internal/storage/postgres_test.go index 69eb177..673c1c7 100644 --- a/services/core/internal/storage/postgres_test.go +++ b/services/core/internal/storage/postgres_test.go @@ -792,6 +792,23 @@ func TestPostgresOperationEventStoreAppendsListsMarksPublishedAndValidates(t *te created1 := time.Now().UTC().Truncate(time.Microsecond) created2 := created1.Add(time.Second) + subject := "operation:" + op.ID + startedPayload := fmt.Sprintf( + `{"operation_id":%q,"repo_id":%q,"type":%q,"state":%q,"started_at":%q}`, + op.ID, + repo.ID, + op.Type, + core.OperationRunning, + created1.Format(time.RFC3339Nano), + ) + completedPayload := fmt.Sprintf( + `{"operation_id":%q,"repo_id":%q,"type":%q,"state":%q,"completed_at":%q}`, + op.ID, + repo.ID, + op.Type, + core.OperationSucceeded, + created2.Format(time.RFC3339Nano), + ) // Append two events ev1 := storage.OperationEvent{ @@ -799,8 +816,8 @@ func TestPostgresOperationEventStoreAppendsListsMarksPublishedAndValidates(t *te Event: events.Event{ ID: "evt-001", Type: events.OperationStarted, - Subject: "clone", - Payload: []byte(`{"state":"running"}`), + Subject: subject, + Payload: []byte(startedPayload), CreatedAt: created1, }, } @@ -809,8 +826,8 @@ func TestPostgresOperationEventStoreAppendsListsMarksPublishedAndValidates(t *te Event: events.Event{ ID: "evt-002", Type: events.OperationCompleted, - Subject: "clone", - Payload: []byte(`{"state":"succeeded"}`), + Subject: subject, + Payload: []byte(completedPayload), CreatedAt: created2, }, } @@ -828,7 +845,7 @@ func TestPostgresOperationEventStoreAppendsListsMarksPublishedAndValidates(t *te Event: events.Event{ ID: "evt-003", Type: events.OperationCompleted, - Subject: "clone", + Subject: subject, Payload: nil, CreatedAt: created2.Add(time.Second), }, @@ -857,10 +874,10 @@ func TestPostgresOperationEventStoreAppendsListsMarksPublishedAndValidates(t *te if listed[0].Event.Type != events.OperationStarted { t.Errorf("ev1: type mismatch: got %q want %q", listed[0].Event.Type, events.OperationStarted) } - if listed[0].Event.Subject != "clone" { - t.Errorf("ev1: subject mismatch: got %q want %q", listed[0].Event.Subject, "clone") + if listed[0].Event.Subject != subject { + t.Errorf("ev1: subject mismatch: got %q want %q", listed[0].Event.Subject, subject) } - assertJSONPayload(t, listed[0].Event.Payload, `{"state":"running"}`) + assertJSONPayload(t, listed[0].Event.Payload, startedPayload) if !listed[0].Event.CreatedAt.Equal(created1) { t.Errorf("ev1: CreatedAt mismatch: got %v want %v", listed[0].Event.CreatedAt, created1) } @@ -875,7 +892,10 @@ func TestPostgresOperationEventStoreAppendsListsMarksPublishedAndValidates(t *te if listed[1].Event.ID != "evt-002" { t.Errorf("ev2: eventID mismatch") } - assertJSONPayload(t, listed[1].Event.Payload, `{"state":"succeeded"}`) + if listed[1].Event.Subject != subject { + t.Errorf("ev2: subject mismatch: got %q want %q", listed[1].Event.Subject, subject) + } + assertJSONPayload(t, listed[1].Event.Payload, completedPayload) if !listed[1].Event.CreatedAt.Equal(created2) { t.Errorf("ev2: CreatedAt mismatch") }