From af639537ec4d70b53c29ca1fb2eb10be7bfed1f3 Mon Sep 17 00:00:00 2001 From: toki Date: Sat, 13 Jun 2026 23:33:39 +0900 Subject: [PATCH] chore: archive completed subtask files and update server_test.go --- .../code_review_cloud_G07_0.log} | 103 +++++++++++++----- .../07_nomad_metadata_shape/complete.log | 43 ++++++++ .../plan_cloud_G07_0.log} | 0 apps/edge/internal/openai/server_test.go | 44 ++++++++ 4 files changed, 160 insertions(+), 30 deletions(-) rename agent-task/{m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/CODE_REVIEW-cloud-G07.md => archive/2026/06/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/code_review_cloud_G07_0.log} (65%) create mode 100644 agent-task/archive/2026/06/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/complete.log rename agent-task/{m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/PLAN-cloud-G07.md => archive/2026/06/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/plan_cloud_G07_0.log} (100%) diff --git a/agent-task/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/CODE_REVIEW-cloud-G07.md b/agent-task/archive/2026/06/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/code_review_cloud_G07_0.log similarity index 65% rename from agent-task/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/CODE_REVIEW-cloud-G07.md rename to agent-task/archive/2026/06/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/code_review_cloud_G07_0.log index 6361dc0..1bad6c2 100644 --- a/agent-task/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/CODE_REVIEW-cloud-G07.md +++ b/agent-task/archive/2026/06/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/code_review_cloud_G07_0.log @@ -42,41 +42,42 @@ task=m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape, plan=0 | 항목 | 완료 여부 | |------|---------| -| [NOMAD_METADATA-1] NomadCode OpenAI Responses client가 `WorkspaceMetadata.Path`를 flat `metadata.workspace` string으로 보내도록 바꾸고 tests를 갱신한다. | [ ] | -| [NOMAD_METADATA-2] IOP consumer fixture가 old object shape를 거부하고 flat task/source/workspace contract를 유지함을 테스트한다. | [ ] | +| [NOMAD_METADATA-1] NomadCode OpenAI Responses client가 `WorkspaceMetadata.Path`를 flat `metadata.workspace` string으로 보내도록 바꾸고 tests를 갱신한다. | [x] | +| [NOMAD_METADATA-2] IOP consumer fixture가 old object shape를 거부하고 flat task/source/workspace contract를 유지함을 테스트한다. | [x] | ## 구현 체크리스트 -- [ ] [NOMAD_METADATA-1] NomadCode OpenAI Responses client가 `WorkspaceMetadata.Path`를 flat `metadata.workspace` string으로 보내도록 바꾸고 tests를 갱신한다. -- [ ] [NOMAD_METADATA-2] IOP consumer fixture가 old object shape를 거부하고 flat task/source/workspace contract를 유지함을 테스트한다. -- [ ] `cd ../nomadcode/services/core && go test -count=1 ./...`와 IOP Edge tests를 실행한다. -- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. +- [x] [NOMAD_METADATA-1] NomadCode OpenAI Responses client가 `WorkspaceMetadata.Path`를 flat `metadata.workspace` string으로 보내도록 바꾸고 tests를 갱신한다. +- [x] [NOMAD_METADATA-2] IOP consumer fixture가 old object shape를 거부하고 flat task/source/workspace contract를 유지함을 테스트한다. +- [x] `cd ../nomadcode/services/core && go test -count=1 ./...`와 IOP Edge tests를 실행한다. +- [x] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다. ## 코드리뷰 전용 체크리스트 > **[REVIEW AGENT ONLY]** 이 체크리스트는 코드리뷰 에이전트만 사용한다. > 구현 에이전트는 이 섹션을 수정하거나 체크하지 않는다. -- [ ] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다. -- [ ] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다. -- [ ] active `CODE_REVIEW-*-G??.md`를 `code_review_cloud_G07_N.log`로 아카이브한다. -- [ ] active `PLAN-*-G??.md`를 `plan_cloud_G07_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-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/`를 `agent-task/archive/YYYY/MM/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/`로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다. -- [ ] PASS이고 task group이 `m-`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다. -- [ ] PASS split 작업이면 이동 후 빈 active parent `agent-task/m-openai-workspace-agent-execution-contract/`를 제거하거나, 남은 sibling/file이 있어 유지했다고 확인한다. +- [x] `코드리뷰 결과`에 `PASS`, `WARN`, `FAIL` 중 하나의 판정을 append한다. +- [x] 판정과 `차원별 평가`, Required/Suggested/Nit 분류가 서로 일치한다. +- [x] active `CODE_REVIEW-*-G??.md`를 `code_review_cloud_G07_N.log`로 아카이브한다. +- [x] active `PLAN-*-G??.md`를 `plan_cloud_G07_M.log`로 아카이브한다. +- [x] `.gitignore`의 Agent-Ops 관리 block이 `agent-task/**/*.md`와 `agent-task/**/*.log`를 unignore하고 `agent-roadmap/current.md`를 ignore하는지 확인한다. +- [x] PASS이면 `agent-ops/skills/common/code-review/templates/complete-log-template.md` 기준으로 `complete.log`를 작성하고 active `.md` 파일을 남기지 않는다. +- [x] PASS이면 active task 디렉터리 `agent-task/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/`를 `agent-task/archive/YYYY/MM/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/`로 이동하고 최종 archive 경로에서 이 체크리스트를 갱신한다. +- [x] PASS이고 task group이 `m-`이면 런타임이 읽을 완료 이벤트 메타데이터를 보고하고, roadmap 수정이나 `update-roadmap` 직접 호출을 하지 않는다. +- [x] PASS split 작업이면 이동 후 빈 active parent `agent-task/m-openai-workspace-agent-execution-contract/`를 제거하거나, 남은 sibling/file이 있어 유지했다고 확인한다. - [ ] WARN/FAIL이고 user-review gate가 트리거되지 않았으면 다음 active `PLAN-cloud-G07.md`와 `CODE_REVIEW-cloud-G07.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로 이동한다. ## 계획 대비 변경 사항 -_구현 에이전트가 계획과 다르게 구현한 부분을 이유와 함께 기록한다._ +없음. 계획한 바와 동일하게 모든 항목을 정상 구현 완료하였습니다. ## 주요 설계 결정 -_구현 에이전트가 주요 설계 결정 사항을 기록한다._ +- NomadCode OpenAI responses client의 `buildRequestMetadata`가 `WorkspaceMetadata` 객체 전체 대신, `Path` 필드만 flat string으로 `workspace` 키에 담도록 수정하였습니다. +- IOP Edge `responsesMetadata` 모델 구조상 flat string을 수신하도록 선언되어 있어, 객체 형태의 workspace metadata가 전달될 시 JSON 에러와 함께 400 Bad Request("invalid metadata format")로 거부됨을 확인하고, 이를 명시적으로 보장하는 테스트 케이스를 `server_test.go`에 추가하여 contract drift를 원천 방지하였습니다. ## 사용자 리뷰 요청 @@ -99,37 +100,55 @@ _기본값은 `없음`이다. 구현 중 사용자 결정, 사용자 소유 외 ## 검증 결과 -_구현 에이전트가 각 중간 검증 및 최종 검증 명령 실행 후 출력을 여기에 붙여 넣는다._ - -필수 규칙: -- 검증 명령은 고정된 계약이다. 임의로 대체하지 않는다. -- 대체가 필요하면 `계획 대비 변경 사항`에 이유와 대체 명령을 기록한다. -- `검증 결과`에는 실제 stdout/stderr를 붙여 넣는다. -- 사용자 리뷰 요청으로 명령을 끝까지 실행하지 못했다면 `사용자 리뷰 요청`에 실행한 명령, 실제 출력, 미실행 명령의 사유를 기록한다. -- mobile/UI hang, timeout, 또는 2분 무진행은 blind retry를 중단하고 focused rerun 명령과 screenshot/window/UI-tree evidence path를 남기며, 불가능하면 정확한 사유를 남긴다. +각 중간 검증과 최종 검증의 모든 명령어 및 결과 출력은 다음과 같습니다. ### NOMAD_METADATA-1 중간 검증 ```bash $ cd ../nomadcode/services/core && go test -count=1 ./internal/adapters/openai ./internal/authoring ./internal/scheduler -(output) +ok github.com/nomadcode/nomadcode-core/internal/adapters/openai 0.006s +ok github.com/nomadcode/nomadcode-core/internal/authoring 0.003s +ok github.com/nomadcode/nomadcode-core/internal/scheduler 2.013s ``` ### NOMAD_METADATA-2 중간 검증 ```bash $ go test -count=1 ./apps/edge/internal/openai ./apps/edge/cmd/edge -(output) +ok iop/apps/edge/internal/openai 1.510s +ok iop/apps/edge/cmd/edge 0.029s ``` ### 최종 검증 ```bash $ cd ../nomadcode/services/core && go test -count=1 ./... -(output) +ok github.com/nomadcode/nomadcode-core/cmd/plane-smoke 0.006s +? github.com/nomadcode/nomadcode-core/cmd/server [no test files] +ok github.com/nomadcode/nomadcode-core/internal/adapters/a2a 0.008s +ok github.com/nomadcode/nomadcode-core/internal/adapters/jira 0.007s +ok github.com/nomadcode/nomadcode-core/internal/adapters/mattermost 0.008s +ok github.com/nomadcode/nomadcode-core/internal/adapters/openai 0.006s +ok github.com/nomadcode/nomadcode-core/internal/adapters/plane 0.009s +? github.com/nomadcode/nomadcode-core/internal/agent [no test files] +ok github.com/nomadcode/nomadcode-core/internal/authoring 0.009s +ok github.com/nomadcode/nomadcode-core/internal/config 0.003s +? github.com/nomadcode/nomadcode-core/internal/db [no test files] +ok github.com/nomadcode/nomadcode-core/internal/http 0.007s +? github.com/nomadcode/nomadcode-core/internal/model [no test files] +ok github.com/nomadcode/nomadcode-core/internal/notification 0.004s +ok github.com/nomadcode/nomadcode-core/internal/projectsync 0.003s +ok github.com/nomadcode/nomadcode-core/internal/protosocket 0.011s +ok github.com/nomadcode/nomadcode-core/internal/roadmapsync 0.004s +ok github.com/nomadcode/nomadcode-core/internal/scheduler 2.010s +ok github.com/nomadcode/nomadcode-core/internal/storage 0.006s +ok github.com/nomadcode/nomadcode-core/internal/workflow 0.004s +ok github.com/nomadcode/nomadcode-core/internal/workitem 0.004s +ok github.com/nomadcode/nomadcode-core/internal/workitempipeline 0.004s $ go test -count=1 ./apps/edge/internal/openai ./apps/edge/cmd/edge -(output) +ok iop/apps/edge/internal/openai 1.509s +ok iop/apps/edge/cmd/edge 0.032s $ git diff --check -(output) +(성공 - 아무 출력 없음) ``` --- @@ -152,3 +171,27 @@ $ git diff --check | 리뷰어를 위한 체크포인트 | Fixed at stub creation | Implementing agent must not modify. | | 검증 결과 | Implementing agent | Fill command output only; command changes require `계획 대비 변경 사항`. | | 코드리뷰 결과 | Review agent appends | Not included in stub. | + +## 코드리뷰 결과 + +- 종합 판정: PASS +- 차원별 평가: + - correctness: Pass + - completeness: Pass + - test coverage: Pass + - API contract: Pass + - code quality: Pass + - plan deviation: Pass + - verification trust: Pass +- 발견된 문제: 없음 +- 다음 단계: PASS이므로 active plan/review를 log로 아카이브하고 `complete.log`를 작성한 뒤 task directory를 `agent-task/archive/2026/06/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/`로 이동한다. `m-openai-workspace-agent-execution-contract` completion metadata를 보고하며 roadmap 수정은 수행하지 않는다. + +### 리뷰 검증 메모 + +- NomadCode producer는 `WorkspaceMetadata.Path`만 `metadata.workspace` flat string으로 직렬화하고 `task_id`/`source` flat metadata를 보존한다. +- IOP consumer는 `responsesMetadata.Workspace string` decode 경계에서 object workspace shape를 `invalid metadata format` 400으로 거부한다. +- 재실행 검증: + - `cd ../nomadcode/services/core && go test -count=1 ./internal/adapters/openai ./internal/authoring ./internal/scheduler` PASS + - `cd ../nomadcode/services/core && go test -count=1 ./...` PASS + - `go test -count=1 ./apps/edge/internal/openai ./apps/edge/cmd/edge` PASS + - `git diff --check` PASS diff --git a/agent-task/archive/2026/06/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/complete.log b/agent-task/archive/2026/06/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/complete.log new file mode 100644 index 0000000..4b448f4 --- /dev/null +++ b/agent-task/archive/2026/06/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/complete.log @@ -0,0 +1,43 @@ +# Complete - m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape + +## 완료 일시 + +2026-06-13 + +## 요약 + +NomadCode metadata workspace wire shape를 flat string contract로 정렬하고 IOP consumer rejection fixture를 보강한 작업을 1회 리뷰에서 PASS로 종료했다. + +## 루프 이력 + +| Plan | Review | Verdict | 메모 | +|------|--------|---------|------| +| `plan_cloud_G07_0.log` | `code_review_cloud_G07_0.log` | PASS | NomadCode producer와 IOP consumer fixture가 계획 범위와 OpenAI-compatible metadata contract에 부합함을 확인했다. | + +## 구현/정리 내용 + +- NomadCode OpenAI Responses client가 `WorkspaceMetadata.Path`를 `metadata.workspace` flat string으로 보내도록 정렬했다. +- NomadCode OpenAI client test와 model comment를 flat workspace wire contract에 맞췄다. +- IOP Edge OpenAI-compatible tests에 object workspace metadata rejection coverage를 추가했다. + +## 최종 검증 + +- `cd ../nomadcode/services/core && go test -count=1 ./internal/adapters/openai ./internal/authoring ./internal/scheduler` - PASS; targeted producer/authoring/scheduler tests passed. +- `cd ../nomadcode/services/core && go test -count=1 ./...` - PASS; all NomadCode core packages passed. +- `go test -count=1 ./apps/edge/internal/openai ./apps/edge/cmd/edge` - PASS; IOP OpenAI-compatible and edge command tests passed. +- `git diff --check` - PASS; no whitespace errors. + +## Roadmap Completion + +- Milestone: `agent-roadmap/phase/automation-runtime-bridge/milestones/openai-workspace-agent-execution-contract.md` +- Completed task ids: + - `nomad-metadata-shape`: PASS; evidence=`agent-task/archive/2026/06/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/plan_cloud_G07_0.log`, `agent-task/archive/2026/06/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/code_review_cloud_G07_0.log`; verification=`cd ../nomadcode/services/core && go test -count=1 ./...`, `go test -count=1 ./apps/edge/internal/openai ./apps/edge/cmd/edge`, `git diff --check` +- Not completed task ids: 없음 + +## 잔여 Nit + +- 없음 + +## 후속 작업 + +- 없음 diff --git a/agent-task/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/PLAN-cloud-G07.md b/agent-task/archive/2026/06/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/plan_cloud_G07_0.log similarity index 100% rename from agent-task/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/PLAN-cloud-G07.md rename to agent-task/archive/2026/06/m-openai-workspace-agent-execution-contract/07_nomad_metadata_shape/plan_cloud_G07_0.log diff --git a/apps/edge/internal/openai/server_test.go b/apps/edge/internal/openai/server_test.go index 9ece61d..e640d33 100644 --- a/apps/edge/internal/openai/server_test.go +++ b/apps/edge/internal/openai/server_test.go @@ -634,6 +634,28 @@ func TestChatCompletionsRejectsCLIMetadata(t *testing.T) { } } +func TestChatCompletionsRejectsObjectWorkspaceMetadata(t *testing.T) { + srv := NewServer(config.EdgeOpenAIConf{Adapter: "ollama", Target: "llama"}, &fakeRunService{}, nil) + req := httptest.NewRequest(http.MethodPost, "/v1/chat/completions", strings.NewReader(`{ + "model":"m", + "messages":[{"role":"user","content":"hi"}], + "metadata":{ + "workspace": { + "path": "/home/user/workspace", + "source_branch": "develop" + } + } + }`)) + w := httptest.NewRecorder() + srv.routes().ServeHTTP(w, req) + if w.Code != http.StatusBadRequest { + t.Fatalf("got %d want 400, body=%s", w.Code, w.Body.String()) + } + if !strings.Contains(w.Body.String(), "invalid metadata format") { + t.Fatalf("expected 'invalid metadata format' error, got %s", w.Body.String()) + } +} + func TestResponsesAcceptsFlatNomadCodeMetadataAliases(t *testing.T) { fake := &fakeRunService{events: make(chan *iop.RunEvent, 2)} fake.events <- &iop.RunEvent{Type: "delta", Delta: "ok"} @@ -752,6 +774,28 @@ func TestResponsesRejectsCLIMetadata(t *testing.T) { } } +func TestResponsesRejectsObjectWorkspaceMetadata(t *testing.T) { + srv := NewServer(config.EdgeOpenAIConf{Adapter: "ollama", Target: "llama"}, &fakeRunService{}, nil) + req := httptest.NewRequest(http.MethodPost, "/v1/responses", strings.NewReader(`{ + "model":"m", + "input":"hi", + "metadata":{ + "workspace": { + "path": "/home/user/workspace", + "source_branch": "develop" + } + } + }`)) + w := httptest.NewRecorder() + srv.routes().ServeHTTP(w, req) + if w.Code != http.StatusBadRequest { + t.Fatalf("got %d want 400, body=%s", w.Code, w.Body.String()) + } + if !strings.Contains(w.Body.String(), "invalid metadata format") { + t.Fatalf("expected 'invalid metadata format' error, got %s", w.Body.String()) + } +} + func TestResponsesReturnsNomadCodeCompatibleShape(t *testing.T) { fake := &fakeRunService{events: make(chan *iop.RunEvent, 3)} fake.events <- &iop.RunEvent{Type: "delta", Delta: "answer"}