nomadcode/agent-task/m-plane-origin-authoring-roundtrip-sync/02+01_iop_progress/PLAN-cloud-G07.md
toki 6d4553bdc9 feat: m-plane-origin-authoring-roundtrip-sync G07-G08 progress and core scheduler improvements
- Add code review and plan logs for cloud G07, G08 subtasks
- Add stale task detection to scheduler
- Update OpenAI client config and tests
- Fix core services Makefile, README, docker-compose, and run script
2026-06-20 18:33:39 +09:00

10 KiB

Implementation Plan - AUTHORING_RUNTIME

이 파일을 읽는 구현 에이전트에게

이 plan은 split predecessor 01_iop_long_runcomplete.log가 필요하다. 구현 시작 전 agent-task/m-plane-origin-authoring-roundtrip-sync/01_iop_long_run/complete.log 또는 matching archive complete.log가 있는지 확인한다. 구현 완료는 active CODE_REVIEW-cloud-G07.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운 뒤에만 성립한다. 사용자에게 직접 질문하지 말고, 선택된 SDD/Milestone lock 결정만 review stub의 사용자 리뷰 요청에 기록한다.

배경

iop-progress Task는 dev IOP의 /v1/responses streaming 지원 여부를 확인하고, stream 미지원이면 silent failure가 아니라 명시 metadata와 stale monitor 기준으로 대체하라고 요구한다. 현재 OpenAI-compatible adapter는 stream:false를 hard-code하고 응답 body를 한 번에 읽는다. Scheduler는 authoring_run_updated_at을 시작과 최종 대기 상태에서만 갱신하므로 진행 갱신 중단을 감지할 수 없다.

사용자 리뷰 요청 흐름

구현 중 직접 사용자에게 질문하지 않는다. 선택된 SDD 결정 또는 Milestone lock 결정이 실제 구현을 차단할 때만 active CODE_REVIEW-cloud-G07.md사용자 리뷰 요청 섹션에 근거와 재개 조건을 기록한다. code-review가 해당 요청을 검증하고 필요 시 USER_REVIEW.md를 작성한다.

Roadmap Targets

  • Milestone: agent-roadmap/phase/agent-ops-mcp-control-plane/milestones/plane-origin-authoring-roundtrip-sync.md
  • Task ids:
    • iop-progress: /v1/responses streaming 지원 여부를 dev IOP 계약으로 확인하고, stream 미지원 환경에서는 authoring_run_updated_at과 task metadata 기반 stale monitor로 대체한다.
  • Completion mode: check-on-pass

Spec Targets

  • SDD: agent-roadmap/sdd/agent-ops-mcp-control-plane/plane-origin-authoring-roundtrip-sync/SDD.md
  • Acceptance scenarios:
    • S03: task=iop-progress; evidence=IOP streaming capability check and fallback stale-monitor evidence
  • Completion mode: spec-check-on-pass

분석 결과

읽은 파일

  • agent-test/local/rules.md
  • agent-test/local/core-smoke.md
  • agent-test/local/workspace-ops-smoke.md
  • agent-test/live-cycle-smoke.md
  • agent-roadmap/phase/agent-ops-mcp-control-plane/milestones/plane-origin-authoring-roundtrip-sync.md
  • agent-roadmap/sdd/agent-ops-mcp-control-plane/plane-origin-authoring-roundtrip-sync/SDD.md
  • services/core/internal/model/model.go
  • services/core/internal/workflow/model.go
  • services/core/internal/adapters/openai/client.go
  • services/core/internal/adapters/openai/client_test.go
  • services/core/internal/scheduler/jobs.go
  • services/core/internal/scheduler/jobs_test.go
  • services/core/internal/config/config.go
  • services/core/internal/config/config_test.go
  • services/core/README.md
  • services/core/go.mod

테스트 환경 규칙

  • test_env: local.
  • agent-test/local/rules.md, core-smoke, workspace-ops-smoke read.
  • focused verification: cd services/core && go test -count=1 ./internal/model/... ./internal/adapters/openai/... ./internal/scheduler/... ./internal/config/....
  • git diff --check for docs/task artifact whitespace.

테스트 커버리지 공백

  • services/core/internal/adapters/openai/client_test.go covers non-streaming response shape and workspace metadata.
  • No test covers stream:true, SSE parsing, streaming unsupported fallback, progress callback, or scheduler metadata updates from progress events.

심볼 참조

  • If model.Client.Generate signature remains unchanged, no call-site rename is needed.
  • If adding progress callback fields to model.GenerateInput or model.GenerateResult, update fake clients in services/core/internal/scheduler/jobs_test.go and adapter tests.

분할 판단

  • split decision policy evaluated.
  • Directory dependency 02+01_iop_progress means predecessor 01_iop_long_run must finish first.
  • Predecessor 01: missing complete.log at active agent-task/m-plane-origin-authoring-roundtrip-sync/01_iop_long_run/complete.log; no archive candidate was read because no candidate path exists for this new split group.
  • This plan is separate because streaming/progress changes touch the model adapter contract and can be reviewed independently from timeout policy and push-only flow.

범위 결정 근거

  • 포함: model progress metadata, OpenAI-compatible Responses stream/fallback behavior, scheduler metadata updates for progress/stale.
  • 제외: initial long-run timeout defaults (01_iop_long_run).
  • 제외: push-only request and remote develop gate (03+01,02_push_command).
  • Exclude live Plane full-cycle evidence; this plan may document dev IOP stream capability but does not claim full-cycle.

빌드 등급

  • cloud-G07: streaming support/fallback can pass unit tests while still breaking live IOP semantics, so cloud lane is required.

구현 체크리스트

  • iop-progress 기준으로 /v1/responses stream 지원/미지원이 task metadata에 명시되고, 진행 갱신이 있을 때 authoring_run_updated_at이 갱신된다. 검증: stream 지원 path와 stream 미지원 fallback path unit tests가 모두 통과한다.
  • stream 미지원은 silent failure가 아니라 authoring_progress_mode/authoring_progress_reason 같은 명시 metadata로 남긴다.
  • cd services/core && go test -count=1 ./internal/model/... ./internal/adapters/openai/... ./internal/scheduler/... ./internal/config/...git diff --check를 실행한다.
  • CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

의존 관계 및 구현 순서

  • Runtime dependency from directory name: 01_iop_long_run must produce complete.log before this subtask starts.
  • Do not add hidden dependencies beyond the directory name.

[AUTHORING_RUNTIME-1] Responses progress contract and fallback metadata

문제:

services/core/internal/adapters/openai/client.go:66 builds a Responses request with Stream: false at services/core/internal/adapters/openai/client.go:71, then reads the whole body at services/core/internal/adapters/openai/client.go:102 through services/core/internal/adapters/openai/client.go:118. services/core/internal/model/model.go:27 has no progress callback/result field. services/core/internal/scheduler/jobs.go:69 through services/core/internal/scheduler/jobs.go:79 only record initial authoring_run_updated_at, so progress interruption and stream unsupported states are invisible.

Before:

// services/core/internal/adapters/openai/client.go:66
reqBody := responsesRequest{
	Model:           modelName,
	Input:           input.Input,
	Instructions:    input.Instructions,
	Metadata:        buildRequestMetadata(input),
	Stream:          false,
	Temperature:     input.Temperature,
	TopP:            input.TopP,
	MaxOutputTokens: input.MaxOutputTokens,
}

해결 방법:

  • Add an internal model progress representation without exposing raw stream payloads or secrets. Suggested fields: progress mode (streaming, stream_unsupported, non_streaming), reason, last event time, and optional callback on GenerateInput.
  • Add config/env for enabling Responses streaming only when dev IOP supports it, defaulting to non-streaming fallback. If the endpoint returns an unsupported stream error, retry once non-streaming and return explicit fallback reason.
  • Implement SSE parsing for OpenAI-compatible Responses stream events that update progress and final text. Keep non-streaming behavior compatible.
  • In scheduler authoring path, pass a progress callback that merges authoring_run_updated_at and progress metadata through Lifecycle.MergeTaskMetadata.
  • Add tests for stream supported, stream unsupported fallback, and scheduler metadata merge on progress.

수정 파일 및 체크리스트:

  • services/core/internal/model/model.go: add progress fields/callback types.
  • services/core/internal/adapters/openai/client.go: support stream-enabled path, unsupported fallback, and progress result metadata.
  • services/core/internal/adapters/openai/client_test.go: add SSE supported and unsupported fallback tests.
  • services/core/internal/config/config.go: add stream enable/config field only if needed.
  • services/core/internal/config/config_test.go: assert stream config defaults/overrides if added.
  • services/core/internal/scheduler/jobs.go: persist authoring progress metadata safely.
  • services/core/internal/scheduler/jobs_test.go: add progress callback metadata regression test.
  • services/core/README.md: document stream default/fallback and stale-monitor metadata without secrets.

테스트 작성:

  • Required. Add adapter tests for stream support and fallback.
  • Required. Add scheduler test for authoring_run_updated_at update on progress.

중간 검증:

cd services/core && go test -count=1 ./internal/model/... ./internal/adapters/openai/... ./internal/scheduler/... ./internal/config/...

Expected: pass with stream/fallback/progress metadata tests.

수정 파일 요약

파일 항목
services/core/internal/model/model.go AUTHORING_RUNTIME-1
services/core/internal/adapters/openai/client.go AUTHORING_RUNTIME-1
services/core/internal/adapters/openai/client_test.go AUTHORING_RUNTIME-1
services/core/internal/config/config.go AUTHORING_RUNTIME-1
services/core/internal/config/config_test.go AUTHORING_RUNTIME-1
services/core/internal/scheduler/jobs.go AUTHORING_RUNTIME-1
services/core/internal/scheduler/jobs_test.go AUTHORING_RUNTIME-1
services/core/README.md AUTHORING_RUNTIME-1

최종 검증

cd services/core && go test -count=1 ./internal/model/... ./internal/adapters/openai/... ./internal/scheduler/... ./internal/config/...

Expected: pass; Go test cache is not acceptable because stream/progress behavior changed.

git diff --check

Expected: no output.

모든 코드 변경 완료 후 반드시 CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.