nomadcode/agent-task/m-plane-origin-authoring-roundtrip-sync/03+01,02_push_command/PLAN-cloud-G08.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

11 KiB

Implementation Plan - AUTHORING_RUNTIME

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

이 plan은 split predecessors 01_iop_long_run02+01_iop_progresscomplete.log가 필요하다. 구현 시작 전 두 predecessor가 완료되었는지 확인한다. 구현 완료는 active CODE_REVIEW-cloud-G08.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운 뒤에만 성립한다. 사용자에게 직접 질문하지 말고, 선택된 SDD/Milestone lock 결정만 review stub의 사용자 리뷰 요청에 기록한다.

배경

push-command Task는 첫 authoring 응답 성공만으로 task completion이나 projection으로 넘어가지 않고, 별도 push-only workspace agent 요청과 remote develop 확인을 요구한다. 현재 scheduler는 authoring model call을 한 번만 실행하고 결과를 in_progress로 두어 develop match를 기다린다. push-only 요청이 없으므로 생성된 milestone이 remote develop에 반영되지 않을 수 있다.

사용자 리뷰 요청 흐름

구현 중 직접 사용자에게 질문하지 않는다. 선택된 SDD 결정 또는 Milestone lock 결정이 실제 구현을 차단할 때만 active CODE_REVIEW-cloud-G08.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:
    • push-command: authoring 결과 작성 이후 Core가 workspace agent에 변경된 내용에 대해 develop 브런치에 푸시해 push-only 요청을 별도 단계로 보낼 수 있다.
  • 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:
    • S04: task=push-command; evidence=scheduler/runtime test or smoke showing push-only request and remote develop verification gate
  • 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/agent/agent.go
  • services/core/internal/adapters/a2a/client.go
  • services/core/internal/adapters/a2a/client_test.go
  • services/core/internal/adapters/openai/client.go
  • services/core/internal/adapters/openai/client_test.go
  • services/core/internal/authoring/request.go
  • services/core/internal/authoring/request_test.go
  • services/core/internal/authoring/result.go
  • services/core/internal/authoring/result_test.go
  • services/core/internal/scheduler/jobs.go
  • services/core/internal/scheduler/jobs_test.go
  • services/core/internal/scheduler/river.go
  • services/core/internal/scheduler/river_test.go
  • services/core/cmd/server/main.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/authoring/... ./internal/scheduler/... ./internal/adapters/openai/... ./internal/agent/... ./internal/adapters/a2a/....
  • agent-test/live-cycle-smoke.md read as runtime-equivalent context; live Plane/secret evidence remains outside this Task's required pass condition unless implementation chooses to run it and records redacted output.

테스트 커버리지 공백

  • services/core/internal/scheduler/jobs_test.go:978 proves authoring waits for develop match after model success.
  • No test proves a second push-only request is sent.
  • No test proves push-only failure becomes push_failed/dirty instead of generic bridge_failed/error.
  • No test proves wait_type=develop_match is set only after push-only request succeeds.

심볼 참조

  • If adding BuildAuthoringPushInput or similar helper, update only scheduler/authoring tests.
  • If changing TaskWorker fields or model/agent interface, update services/core/internal/scheduler/river.go, services/core/cmd/server/main.go, and test fakes.

분할 판단

  • split decision policy evaluated.
  • Directory dependency 03+01,02_push_command means predecessors 01_iop_long_run and 02+01_iop_progress must finish first.
  • Predecessor 01: missing active/archive complete.log.
  • Predecessor 02: missing active/archive complete.log.
  • This plan is separated because push-only behavior changes authoring completion semantics and failure categories after the timeout/progress foundation is available.

범위 결정 근거

  • 포함: push-only workspace agent/model request, failure category mapping, scheduler wait gate, unit/runtime-equivalent tests.
  • 제외: actual Gito webhook delivery and Plane Todo projection; those are gito-plane/live-gate Task scopes.
  • Exclude provider identity injection/matching; that belongs to identity-sync.

빌드 등급

  • cloud-G08: terminal-agent behavior and remote branch verification are central, and a plausible local-only implementation could still fail the runtime roundtrip.

구현 체크리스트

  • push-command 기준으로 first authoring response success alone does not complete or advance projection; a push-only request is sent with the exact user-facing command and workspace metadata. 검증: scheduler test captures two authoring model/agent calls and the second command text.
  • push-only success records wait_type=develop_match and waits for remote develop confirmation via the existing Gito/develop match path; push-only failure records push_failed and maps slot to dirty.
  • cd services/core && go test -count=1 ./internal/authoring/... ./internal/scheduler/... ./internal/adapters/openai/... ./internal/agent/... ./internal/adapters/a2a/...git diff --check를 실행한다.
  • CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

의존 관계 및 구현 순서

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

[AUTHORING_RUNTIME-1] Push-only authoring stage and develop-match gate

문제:

services/core/internal/scheduler/jobs.go:167 calls w.Model.Generate once for Plane-origin authoring. services/core/internal/scheduler/jobs.go:171 through services/core/internal/scheduler/jobs.go:191 returns authoring_run_state=in_progress immediately after that first response. services/core/internal/scheduler/jobs.go:105 through services/core/internal/scheduler/jobs.go:129 keeps the task running for develop match, but no push-only workspace request is ever sent. services/core/internal/authoring/result.go:47 already has PushFailed, but scheduler cannot currently reach it for push-only failure.

Before:

// services/core/internal/scheduler/jobs.go:167
generated, err := w.Model.Generate(ctx, generateInput)
if err != nil {
	return nil, "", err
}
decision := authoring.DecideAuthoringResult(authoring.DecisionInput{
	BridgeSuccess: true,
})

해결 방법:

  • Add an authoring helper that builds a push-only model.GenerateInput from the original task/workspace metadata. The command text must be exactly 변경된 내용에 대해 develop 브런치에 푸시해 unless a local constant is introduced with that exact value.
  • Refactor scheduler authoring path into a small runAuthoringTask helper: first call authoring generate, then call push-only generate. Do not mark/wait for develop match until push-only returns success.
  • Persist distinct metadata keys for first authoring response and push-only response, for example authoring_response_id, push_response_id, push_request_state=succeeded.
  • On push-only error, surface an authoring failure that markFailedWithTask maps to authoring_failure_category=push_failed, failure_type=execution, and slot dirty.
  • Keep remote develop confirmation delegated to existing Gito scan/develop match finalization. The scheduler must remain running with wait_type=develop_match after push-only succeeds.

수정 파일 및 체크리스트:

  • services/core/internal/authoring/request.go: add push-only input helper and constant.
  • services/core/internal/authoring/request_test.go: assert command text, workspace metadata, and provider identity are preserved.
  • services/core/internal/authoring/result.go: add helper/error mapping if needed so push failures do not become bridge failures.
  • services/core/internal/authoring/result_test.go: assert push failure category remains push_failed.
  • services/core/internal/scheduler/jobs.go: refactor authoring run, perform push-only call, gate develop wait after push success.
  • services/core/internal/scheduler/jobs_test.go: add two-call success test, no-complete-before-develop-match assertion, push failure metadata/slot dirty test.
  • services/core/README.md: document first authoring response, push-only request, and develop match as separate stages.

테스트 작성:

  • Required scheduler unit tests for success and push failure.
  • Required authoring helper tests for exact command and metadata preservation.
  • No DB migration test required.

중간 검증:

cd services/core && go test -count=1 ./internal/authoring/... ./internal/scheduler/... ./internal/adapters/openai/... ./internal/agent/... ./internal/adapters/a2a/...

Expected: pass with push-only success/failure coverage.

수정 파일 요약

파일 항목
services/core/internal/authoring/request.go AUTHORING_RUNTIME-1
services/core/internal/authoring/request_test.go AUTHORING_RUNTIME-1
services/core/internal/authoring/result.go AUTHORING_RUNTIME-1
services/core/internal/authoring/result_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/authoring/... ./internal/scheduler/... ./internal/adapters/openai/... ./internal/agent/... ./internal/adapters/a2a/...

Expected: pass; Go test cache is not acceptable because scheduler behavior changed.

git diff --check

Expected: no output.

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