14 KiB
14 KiB
Milestone: 에이전트 작업성 중심 저장소 구조 리팩터링
위치
- Roadmap: ROADMAP.md
- Phase: PHASE.md
목표
생성물과 대형 데이터 파일을 제외한 사람이 관리하는 프로젝트 소스와 테스트를 책임과 변경 이유가 드러나는 단위로 재구성한다. 기존 API, wire, config schema와 런타임 동작을 유지하면서 에이전트가 한 기능을 수정하기 위해 읽어야 하는 파일 수와 task-local context를 줄이고, 이후 변경에서 다시 거대 파일이 생기지 않도록 측정 가능한 기준선을 둔다.
상태
[완료]
승격 조건
- 없음
구현 잠금
- 상태: 해제
- SDD: 불필요
- SDD 문서: 없음
- SDD 사유: 외부 API/proto/config schema나 runtime 책임 경계를 바꾸지 않고 동일 패키지 내 책임 분리, 테스트 재배치와 저장소 위생 개선을 수행하는 동작 보존형 리팩터링이다.
- 잠금 해제 조건: 없음
- 결정 필요: 없음
범위
- 추적 중인 빌드 바이너리와 파일 길이 측정 노이즈를 정리하고, 생성물·lockfile·PBX·대형 fixture 예외를 구분하는 저장소 가독성 기준선을 둔다.
apps/edge/internal/openai,apps/edge/internal/service,apps/edge/cmd/edge,apps/node/internal/node,apps/node/internal/adapters,apps/control-plane/cmd/control-plane,packages/go/config, Flutter client와 E2E script의 거대 파일을 책임과 변경 이유 기준으로 분해한다.- 거대 테스트 파일을 기능 시나리오별로 나누고, 만능 fake와 반복 fixture setup을 feature-local stub/helper로 정리한다.
- 120줄 이상 장기 함수, 과도한 parameter list와 closure 기반 상태 처리를 명명된 context/session 객체와 단계별 함수 후보로 정리한다.
agent-testinventory의 canonical 데이터는 유지하면서 프로젝트 전용 query 경로로 전체 읽기 비용을 줄인다.agent-ops/rules/common/**와agent-ops/skills/common/**는 공유 Agent-Ops 경계이므로 이 프로젝트 리팩터링의 측정·수정·분해 대상에서 제외한다.- 파일 이동 뒤 domain rule, agent-spec source evidence와 현재 계약 포인터가 실제 구현 경로를 계속 가리키도록 동기화한다.
기능
Epic: [hygiene] 저장소 노이즈와 가독성 기준선
에이전트 탐색을 오염시키는 artifact를 제거하고 신규 구조 부채를 조기에 확인할 수 있는 기준을 만든다.
- [tracked-artifacts] 루트의 추적 중 ELF 빌드 산출물
node,edge,openai.test를 Git 추적에서 제거하고 공식 빌드 산출 위치와 ignore 규칙을 정렬한다. Git history 재작성은 수행하지 않는다. 검증:git ls-files node edge openai.test가 비어 있고 공식 build target이build/아래 산출물을 만든다. - [readability-baseline] 생성물과 data-only 예외를 제외한 파일 LOC, 함수 크기와 task-local read set을 점검하는 기준선과 ratchet 정책을 둔다. 기본 code/test 입력은 Git이 추적하는 Go/Dart/Shell/Python/Kotlin/Swift 파일로 정의하고 protobuf·Dart 생성 경로와 공유 Agent-Ops common 경계는 제외한다. 운영 파일 500줄 경고/800줄 분리 검토/1,000줄 예외, 테스트 800줄 경고/1,000줄 분리 검토, 함수 80줄 경고/120줄 분리 검토, 프로젝트 전용 Skill 진입 파일 300줄 경고/500줄 분리 검토를 기본값으로 기록한다. 검증: 동일 입력에서 재현 가능한 audit 결과가 생성되고 신규 초과 또는 기존 초과 증가가 실패하거나 명시적 allowlist 사유를 요구한다.
Epic: [tests] 기능 시나리오 기반 테스트 분해
기능 변경 시 관련 테스트와 fixture만 읽어도 회귀 조건을 이해할 수 있게 테스트 토폴로지를 재구성한다.
- [openai-tests]
apps/edge/internal/openai/server_test.go를 auth/routes/models, chat handler/stream, Responses, provider tunnel, workspace/metadata, tool parsing/validation 시나리오로 분리하고 거대fakeRunService를 feature-local stub 또는 함수 필드 기반 test double로 축소한다. 검증:go test ./apps/edge/internal/openai가 통과하고 기존 테스트 케이스가 누락되지 않는다. - [core-tests]
packages/go/config/config_test.go,apps/node/internal/node/node_test.go,apps/edge/internal/service/model_queue_test.go,apps/edge/internal/service/service_test.go,apps/edge/internal/bootstrap/runtime_test.go를 config 영역과 run/cancel/command/refresh/tunnel, admission/scheduling/long-context/snapshot, runtime refresh 책임별로 분리하고 반복 setup을 명시적 helper로 정리한다. 검증:go test ./packages/go/config ./apps/node/internal/node ./apps/edge/internal/service ./apps/edge/internal/bootstrap가 통과한다. - [adapter-command-tests]
apps/node/internal/adapters의 1,000줄 이상 adapter/CLI 테스트와apps/edge/cmd/edge,apps/control-plane/cmd/control-plane,apps/edge/internal/configrefresh의 거대 command/config refresh 테스트를 실행 모드와 command 책임별로 분리한다. 검증: 대상 패키지 테스트가 통과하고 audit 결과에 사유 없는 1,000줄 초과 테스트가 남지 않는다. - [client-tests]
apps/client/test/widget_test.dart를 app shell과 panel/integration 시나리오별 파일로 분리하고 공통 harness가 개별 테스트 의도를 가리지 않게 축소한다. 검증:make client-test가 통과한다.
Epic: [modules] 동일 패키지 내 책임 중심 소스 분해
새 package/API를 먼저 만들지 않고 기존 package 경계를 유지한 채 파일명만으로 주요 책임을 찾을 수 있게 한다.
- [openai-modules]
types.go,stream.go,chat_handler.go,responses_handler.go를 chat/Responses DTO, text tool parser, schema/command normalization, normalized SSE, provider tunnel/rewrite, route/policy 책임별 파일로 분리한다. 검증: 공개·내부 동작 계약을 바꾸지 않고go test ./apps/edge/internal/openai가 통과한다. - [config-modules]
packages/go/config/config.go를 Node/Edge/provider/adapter 타입, load/default, normalization, validation 책임별 파일로 분리하고 테스트 파일과 대응시킨다. 검증: config 예시 roundtrip과go test ./packages/go/config가 통과한다. - [service-node-modules] Edge
run_dispatch.go/model_queue.go와 Nodenode.go를 run/provider resolution/provider pool/tunnel/cancel/session, admission/release/snapshot, run/tunnel/command/refresh/sink 책임별 파일로 분리한다. 검증:go test ./apps/edge/internal/service ./apps/node/internal/node가 통과한다. - [secondary-modules] OpenAI-compatible/vLLM/Ollama/CLI adapter, Flutter runtime panel, E2E shell처럼 500~800줄 이상인 후순위 후보를 동일한 책임/변경 이유 기준으로 분해하고, 단순 LOC 충족을 위한 micro-package나
utils집합은 만들지 않는다.
Epic: [complexity] 장기 함수와 상태 전달 구조화
파일 이동만으로 남는 함수 내부 인지 복잡도를 명명된 상태와 단계별 처리 경계로 낮춘다.
- [stream-session]
streamChatCompletion의 content/reasoning/tool/usage/trace 상태와 terminal event 처리를 명명된 stream session/context와 event별 단계로 분리한다. 검증: live SSE, buffered strict output, tool-call, cancel/timeout, usage 회귀 테스트가 통과한다. - [dispatch-context] 10개 이상 parameter를 전달하는 Chat/Responses/provider-pool 경로를 명명된 request/dispatch context로 바꾸고, queue reservation과 release의 성공/실패 경로를 한눈에 추적할 수 있게 한다.
- [long-functions] 120줄 이상 함수의 책임 혼합 여부를 점검하고
Classify, adapterExecute, Node/transport handler와 E2E orchestration을 단계별 함수로 축소하거나 응집된 예외 사유를 남긴다.
Epic: [agent-context] 구조화 인벤토리 읽기 비용 절감
큰 프로젝트 인벤토리는 필요한 조각만 결정적으로 조회할 수 있게 한다.
- [inventory-query]
agent-test/dev/inventory.yaml과agent-test/dev-corp/inventory.yaml의 canonical machine-readable 역할은 유지하면서 env/model/node/provider selector로 필요한 bounded 결과만 얻는 결정적 query 경로를 제공한다. - [evidence-links] 활성 코드의 bare SDD section anchor를 현재 invariant 또는 contract/spec 식별자로 보강하고, 파일 분해 뒤 domain rule과 agent-spec
source_evidence가 실제 현재 경로를 가리키도록 갱신한다.
Epic: [verification] 동작 보존과 가독성 회귀 검증
구조 변경이 사용자 실행 계약을 바꾸지 않았고 새 기준선이 실질적인 읽기 범위 축소로 이어졌음을 검증한다.
- [regression] 전체 Go/Flutter 회귀와 변경 범위의 E2E/full-cycle 검증을 수행한다. 검증:
go test ./...,make client-test와 testing domain rule이 요구하는 관련 smoke/full-cycle 경로가 통과한다. - [read-set] 대표 프로젝트 변경 시나리오인 OpenAI chat stream, provider-pool dispatch, Node config refresh, Flutter runtime panel마다 필수 규칙·주요 소스·직접 테스트 파일 목록과 LOC 합계를 재현 가능한 audit evidence로 남긴다. 각 task-local read set은 가능한 경우 1,500~2,000줄 안으로 축소하고, 공유 Agent-Ops common 경로는 포함하지 않는다.
완료 리뷰
- 상태: 통과
- 요청일: 2026-07-19
- 완료 근거: 전체 저장소 회귀와 runtime full-cycle이 PASS했고, 후자는 현재 구현 HEAD에서 Go/Flutter/readability 회귀와 E2E 및 실제 CLI 4종 검증을 완료했다.
- 완료 근거: 모든 기능 Task가 evidence와 함께 충족됐고 구현 잠금과 SDD 차단 항목이 없다.
- 코드레벨 감사: 현재 소스가 runtime full-cycle 검증 커밋과 동일하며, 현재 워크트리에서 Go/Flutter/readability/E2E 회귀를 다시 통과했다. 리팩터링 전 통합 테스트를 가리키던 활성 계약 포인터는 현재 분할 테스트 경로로 보정했다.
- Spec sync: Spec update not needed. 관련 현재 구현 스펙인 Edge-Node 실행, Provider Pool Config Refresh, OpenAI-compatible 입력 표면의 source evidence와 불변식이 현재 코드와 일치한다.
- 검토 항목:
- 생성물 예외를 제외한 P0/P1 거대 파일이 기준선 아래로 분해되거나 명시적 예외 근거를 가진다
- 전체 Go/Flutter 회귀와 관련 E2E/full-cycle 검증이 통과한다
- 공유 Agent-Ops common 경계가 프로젝트 readability 측정·수정 대상에서 제외되고 마일스톤 중 유입된 common 변경이 복구된다
- domain rule, agent-spec, contract pointer가 이동된 현재 코드 경로와 일치한다
- agent-ui 상태 반영: 해당 없음
- 리뷰 코멘트: 종료 차단 이슈 없음. 작은 계약 포인터 불일치는 검증 후 즉시 보정했다.
범위 제외
- OpenAI-compatible/A2A API, proto wire, config schema, runtime routing 정책의 기능 변경
- LOC를 맞추기 위한 package 남발, 타입 하나당 파일 하나 생성, 범용
utils/common패키지 승격 - protobuf/Dart 생성물, lockfile, PBX project, data-only fixture에 대한 동일 LOC 제한 강제
- 기존 Git history에서 binary blob을 제거하는 history rewrite
- archive 문서 재포맷이나 과거 완료 작업의 일반 컨텍스트 로딩
agent-ops/rules/common/**,agent-ops/skills/common/**의 규칙·스킬·템플릿 변경 또는 프로젝트 readability ratchet 편입- 리팩터링 과정에서 발견한 신규 제품 기능의 동시 구현
작업 컨텍스트
- 관련 경로:
apps/edge/internal/openai,apps/edge/internal/service,apps/edge/cmd/edge,apps/node/internal/node,apps/node/internal/adapters,apps/control-plane/cmd/control-plane,packages/go/config,apps/client,scripts,agent-ops/skills/project,agent-test,agent-spec - 표준선(선택): 같은 package 안에서 테스트와 파일을 먼저 기계적으로 분해하고 회귀 검증을 확보한 뒤 장기 함수와 상태 전달을 구조화한다. 파일 수보다 변경 이유의 응집도와 task-local read set을 우선한다. 공유 Agent-Ops common 경계는 수정하거나 프로젝트 ratchet 대상으로 삼지 않는다.
- 기준선(2026-07-16): Git이 추적하는 Go/Dart/Shell/Python/Kotlin/Swift 중
proto/gen/**와apps/client/lib/gen/**를 제외한 사람이 관리하는 코드·테스트는 242개, 파일 LOC 중앙값은 216줄, 500줄 이상은 54개, 1,000줄 이상은 22개이며 이 중 테스트가 14개, 운영 코드가 8개다. 루트 추적 ELF 3개는 합계 65,474,597byte(약 65.5MB)다. - SDD 재판정 조건: 리팩터링 중 외부 API/proto/config schema, runtime routing 정책 또는 공유 Agent-Ops common 경계 변경이 필요해지면 해당 변경을 현재 범위에서 중단하고 roadmap/SDD gate를 재판정한다.
- 선행 작업: 없음
- 후속 작업: 필요하면 Epic별 split 구현 계획으로 나누되 같은 Milestone 완료 근거로 수렴한다.
- 확인 필요: 없음