- 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
11 KiB
Implementation Plan - AUTHORING_RUNTIME
이 파일을 읽는 구현 에이전트에게
이 plan은 split predecessors 01_iop_long_run과 02+01_iop_progress의 complete.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.mdagent-test/local/core-smoke.mdagent-test/local/workspace-ops-smoke.mdagent-test/live-cycle-smoke.mdagent-roadmap/phase/agent-ops-mcp-control-plane/milestones/plane-origin-authoring-roundtrip-sync.mdagent-roadmap/sdd/agent-ops-mcp-control-plane/plane-origin-authoring-roundtrip-sync/SDD.mdservices/core/internal/model/model.goservices/core/internal/agent/agent.goservices/core/internal/adapters/a2a/client.goservices/core/internal/adapters/a2a/client_test.goservices/core/internal/adapters/openai/client.goservices/core/internal/adapters/openai/client_test.goservices/core/internal/authoring/request.goservices/core/internal/authoring/request_test.goservices/core/internal/authoring/result.goservices/core/internal/authoring/result_test.goservices/core/internal/scheduler/jobs.goservices/core/internal/scheduler/jobs_test.goservices/core/internal/scheduler/river.goservices/core/internal/scheduler/river_test.goservices/core/cmd/server/main.goservices/core/README.mdservices/core/go.mod
테스트 환경 규칙
- test_env:
local. agent-test/local/rules.md,core-smoke,workspace-ops-smokeread.- 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.mdread 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:978proves 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 genericbridge_failed/error. - No test proves
wait_type=develop_matchis set only after push-only request succeeds.
심볼 참조
- If adding
BuildAuthoringPushInputor similar helper, update only scheduler/authoring tests. - If changing
TaskWorkerfields or model/agent interface, updateservices/core/internal/scheduler/river.go,services/core/cmd/server/main.go, and test fakes.
분할 판단
- split decision policy evaluated.
- Directory dependency
03+01,02_push_commandmeans predecessors01_iop_long_runand02+01_iop_progressmust finish first. - Predecessor
01: missing active/archivecomplete.log. - Predecessor
02: missing active/archivecomplete.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-gateTask 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_matchand waits for remotedevelopconfirmation via the existing Gito/develop match path; push-only failure recordspush_failedand maps slot todirty. 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_runand02+01_iop_progressmust producecomplete.logbefore 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.GenerateInputfrom 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
runAuthoringTaskhelper: 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
markFailedWithTaskmaps toauthoring_failure_category=push_failed,failure_type=execution, and slotdirty. - Keep remote
developconfirmation delegated to existing Gito scan/develop match finalization. The scheduler must remain running withwait_type=develop_matchafter 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 remainspush_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의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.