update: agent-test files - refine dev rules, live-cycle smoke tests, and plane-dev
This commit is contained in:
parent
1d5708542e
commit
ea97e73608
3 changed files with 244 additions and 6 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
test_env: dev
|
test_env: dev
|
||||||
last_rule_updated_at: 2026-07-01
|
last_rule_updated_at: 2026-07-03
|
||||||
---
|
---
|
||||||
|
|
||||||
# dev 테스트 규칙
|
# dev 테스트 규칙
|
||||||
|
|
@ -16,6 +16,7 @@ last_rule_updated_at: 2026-07-01
|
||||||
- raw token, password, webhook secret, provider credential, private key는 ignored local profile 또는 remote secret store에서만 주입한다.
|
- raw token, password, webhook secret, provider credential, private key는 ignored local profile 또는 remote secret store에서만 주입한다.
|
||||||
- 컨테이너 내부 listen 포트는 제품 기본값을 우선 유지하고, workspace 충돌 관리는 host publish/direct smoke 포트로 처리한다.
|
- 컨테이너 내부 listen 포트는 제품 기본값을 우선 유지하고, workspace 충돌 관리는 host publish/direct smoke 포트로 처리한다.
|
||||||
- 테스트용 Docker subnet을 새로 만들 때는 `192.168.0.0/24` 대역을 사용하지 않는다.
|
- 테스트용 Docker subnet을 새로 만들 때는 `192.168.0.0/24` 대역을 사용하지 않는다.
|
||||||
|
- Plane-origin full-cycle 검증은 `agent-test/live-cycle-smoke.md`를 따른다. 수동 Gito redelivery는 진단/복구 근거일 뿐 자동 Forgejo -> Gito 경로 통과 근거로 기록하지 않는다.
|
||||||
|
|
||||||
## 기본 환경
|
## 기본 환경
|
||||||
|
|
||||||
|
|
@ -49,8 +50,17 @@ dev NomadCode의 Gito webhook target은 `http://127.0.0.1:18011/api/integrations
|
||||||
- `GITO_DEVELOP_REPO_PATH`는 Core container에서 접근 가능한 checkout path여야 한다.
|
- `GITO_DEVELOP_REPO_PATH`는 Core container에서 접근 가능한 checkout path여야 한다.
|
||||||
- 계약 원문은 `agent-contract/outer/gito-branch-webhook-consumer-v1.md`와 Gito 제공 계약 `../gito/agent-contract/provided/gito-forgejo-branch-events-v1.md`를 함께 따른다.
|
- 계약 원문은 `agent-contract/outer/gito-branch-webhook-consumer-v1.md`와 Gito 제공 계약 `../gito/agent-contract/provided/gito-forgejo-branch-events-v1.md`를 함께 따른다.
|
||||||
|
|
||||||
|
## Forgejo -> Gito Webhook 기준
|
||||||
|
|
||||||
|
- dev Forgejo repository hook이 host Gito dev port로 delivery할 때 target은 `http://host.docker.internal:18061/callbacks/forgejo/push?repo_id=nomadcode` 형태일 수 있다.
|
||||||
|
- 이 경우 Forgejo app config `[webhook] ALLOWED_HOST_LIST`에는 기존 허용 host와 함께 `host.docker.internal`이 포함되어야 한다.
|
||||||
|
- allowlist가 막히면 Forgejo `hook_task.response_content`에 `webhook can only call allowed HTTP servers`가 남고, Core task는 git push 후 `develop_match` 대기에서 멈출 수 있다.
|
||||||
|
- allowlist를 조정할 때는 config 백업을 먼저 만들고, raw secret이나 token 값은 조회/출력/기록하지 않는다.
|
||||||
|
- Forgejo 컨테이너에서 `curl http://host.docker.internal:18061/healthz`가 성공해야 provider callback 네트워크가 열린 것으로 본다.
|
||||||
|
|
||||||
## 라우팅
|
## 라우팅
|
||||||
|
|
||||||
|
- core / full-cycle / Plane-origin milestone authoring, git develop push, Forgejo/Gito branch.updated, Plane Todo projection: `agent-test/live-cycle-smoke.md`
|
||||||
- core / smoke / services/core backend baseline: `agent-test/local/core-smoke.md`
|
- core / smoke / services/core backend baseline: `agent-test/local/core-smoke.md`
|
||||||
- mobile / smoke / apps/client Flutter baseline: `agent-test/local/mobile-smoke.md`
|
- mobile / smoke / apps/client Flutter baseline: `agent-test/local/mobile-smoke.md`
|
||||||
- mobile / smoke / Android SDK remote runner and debug APK validation: `agent-test/local/mobile-android-sdk-smoke.md`
|
- mobile / smoke / Android SDK remote runner and debug APK validation: `agent-test/local/mobile-android-sdk-smoke.md`
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,29 @@
|
||||||
---
|
---
|
||||||
test_env: local
|
test_env: local
|
||||||
|
test_env_scope: local_and_dev_profiles
|
||||||
test_profile: live-cycle-smoke
|
test_profile: live-cycle-smoke
|
||||||
domain: core
|
domain: core
|
||||||
verification_type: smoke
|
verification_type: smoke
|
||||||
last_rule_updated_at: 2026-06-21
|
last_rule_updated_at: 2026-07-03
|
||||||
---
|
---
|
||||||
|
|
||||||
# live-cycle-smoke
|
# live-cycle-smoke
|
||||||
|
|
||||||
전체 webhook → authoring → develop match → Plane projection → slot 회수 사이클을 검증한다.
|
전체 webhook -> authoring -> git develop push -> Forgejo/Gito branch event -> Plane projection -> slot 회수 사이클을 검증한다.
|
||||||
이 문서는 절차 기술과 runtime-equivalent 근거를 함께 기록한다.
|
이 문서는 절차 기술과 runtime-equivalent 근거를 함께 기록한다.
|
||||||
|
|
||||||
## 읽기 조건
|
## 읽기 조건
|
||||||
|
|
||||||
- `live-webhook-task`, `webhook-auto-enqueue`, `live-creation-projection` 증거가 필요한 경우.
|
- `live-webhook-task`, `webhook-auto-enqueue`, `live-creation-projection` 증거가 필요한 경우.
|
||||||
|
- dev profile에서 Plane-origin milestone 생성이 git에 등록되고 다시 Plane `Todo`로 이동하는지 검증하는 경우.
|
||||||
- `agent-task/m-milestone-work-item-creation-sync/14+12,13_live_cycle_smoke` 구현/리뷰 시.
|
- `agent-task/m-milestone-work-item-creation-sync/14+12,13_live_cycle_smoke` 구현/리뷰 시.
|
||||||
|
|
||||||
## 환경
|
## 환경
|
||||||
|
|
||||||
- host: standard remote runner `toki@toki-labs.com`, checkout `$HOME/agent-work/nomadcode`.
|
- host: standard remote runner `toki@toki-labs.com`.
|
||||||
- Core server: Docker Compose (`services/core/docker-compose.yml`), host port `18010->8080`.
|
- local profile checkout: `$HOME/agent-work/nomadcode`, Core host port `18010->8080`, Gito source `18060`.
|
||||||
|
- dev profile checkout: `$HOME/agent-work/nomadcode-dev`, Core host port `18011->8080`, Gito source `18061`.
|
||||||
|
- Core server: Docker Compose (`services/core/docker-compose.yml`).
|
||||||
- Plane dev: `https://plane.toki-labs.com`, workspace `general`, project `NOMAD`.
|
- Plane dev: `https://plane.toki-labs.com`, workspace `general`, project `NOMAD`.
|
||||||
- Secrets: `.env.plane.local` (ignored), SOPS `secrets/nomadcode.dev.sops.yaml` (webhook secret).
|
- Secrets: `.env.plane.local` (ignored), SOPS `secrets/nomadcode.dev.sops.yaml` (webhook secret).
|
||||||
- runner checkout: 검증용 disposable mirror다. dirty worktree, uncommitted 변경, 임시 파일을 이유로 중단하지 않고 현재 대화 workspace의 요청 범위 상태와 같게 reset/clean/reclone 또는 파일 동기화한 뒤 테스트한다.
|
- runner checkout: 검증용 disposable mirror다. dirty worktree, uncommitted 변경, 임시 파일을 이유로 중단하지 않고 현재 대화 workspace의 요청 범위 상태와 같게 reset/clean/reclone 또는 파일 동기화한 뒤 테스트한다.
|
||||||
|
|
@ -30,6 +34,32 @@ last_rule_updated_at: 2026-06-21
|
||||||
- `PLANE_WEBHOOK_SECRET`, `PLANE_TOKEN` 등 secret은 `.env.plane.local` 또는 SOPS에서 로드한다.
|
- `PLANE_WEBHOOK_SECRET`, `PLANE_TOKEN` 등 secret은 `.env.plane.local` 또는 SOPS에서 로드한다.
|
||||||
- Plane dev 서버가 `https://plane.toki-labs.com`에서 정상 동작 중이어야 한다.
|
- Plane dev 서버가 `https://plane.toki-labs.com`에서 정상 동작 중이어야 한다.
|
||||||
- workspace slot 행이 DB에 `available` 상태로 최소 1개 이상 있어야 한다.
|
- workspace slot 행이 DB에 `available` 상태로 최소 1개 이상 있어야 한다.
|
||||||
|
- dev profile에서는 `agent-test/dev/rules.md`를 먼저 읽고, Core `18011`, Gito `18061`, Forgejo provider hook 경로가 모두 열려 있어야 한다.
|
||||||
|
- Forgejo repository hook이 `host.docker.internal:18061`로 Gito에 전달하는 환경이면 Forgejo `[webhook] ALLOWED_HOST_LIST`가 `host.docker.internal`을 허용해야 한다.
|
||||||
|
|
||||||
|
## dev profile 프리플라이트
|
||||||
|
|
||||||
|
아래 확인은 secret 값을 출력하지 않는다. 실패하면 Plane work item을 새로 만들기 전에 환경을 먼저 고친다.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# 1. Core/Gito readiness
|
||||||
|
curl -fsS http://127.0.0.1:18011/readyz
|
||||||
|
curl -fsS http://127.0.0.1:18061/readyz
|
||||||
|
|
||||||
|
# 2. Gito branch watch / subscription
|
||||||
|
curl -fsS http://127.0.0.1:18061/api/listeners/branches
|
||||||
|
curl -fsS http://127.0.0.1:18061/api/webhook-subscriptions
|
||||||
|
# Expected: repo_id=nomadcode, branch=develop, event=branch.updated.
|
||||||
|
|
||||||
|
# 3. Forgejo container -> Gito host endpoint reachability
|
||||||
|
docker exec forgejo curl -fsS --max-time 5 http://host.docker.internal:18061/healthz
|
||||||
|
|
||||||
|
# 4. Forgejo webhook allowlist
|
||||||
|
docker exec forgejo sh -c 'grep -n "^ALLOWED_HOST_LIST" /data/gitea/conf/app.ini'
|
||||||
|
# Expected when hook target uses host.docker.internal: value includes host.docker.internal.
|
||||||
|
```
|
||||||
|
|
||||||
|
Gito watch 또는 subscription이 없으면 Gito 제공 계약의 `/api/listeners/branches`와 `/api/webhook-subscriptions` bootstrap 절차를 따른다. raw secret 대신 `secret_ref` 또는 환경 참조만 사용한다.
|
||||||
|
|
||||||
## Fixture IDs (non-secret)
|
## Fixture IDs (non-secret)
|
||||||
|
|
||||||
|
|
@ -87,6 +117,107 @@ for t in d.get('tasks', []):
|
||||||
# 9. slot 재사용 확인: 두 번째 smoke 티켓 생성 → 같은 slot_id 또는 새 available slot에서 reservation
|
# 9. slot 재사용 확인: 두 번째 smoke 티켓 생성 → 같은 slot_id 또는 새 available slot에서 reservation
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## dev profile 자동 경로 체크리스트
|
||||||
|
|
||||||
|
dev profile에서는 아래 순서가 모두 이어져야 Plane-origin full-cycle 통과로 본다.
|
||||||
|
|
||||||
|
1. Plane에서 새 `Backlog + AGENT assignee` work item을 만든다.
|
||||||
|
- 제목/본문에는 유일한 timestamp를 넣는다.
|
||||||
|
- 요청 범위는 roadmap milestone 문서 생성처럼 작은 산출물로 제한한다.
|
||||||
|
- 생성 직후 work item UUID만 기록하고 token, webhook secret, private key는 기록하지 않는다.
|
||||||
|
2. Core task 생성과 authoring 진입을 확인한다.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
CORE_URL="http://127.0.0.1:18011"
|
||||||
|
WORK_ITEM_UUID="<plane-work-item-uuid>"
|
||||||
|
curl -fsS "$CORE_URL/api/tasks" | python3 -c "
|
||||||
|
import json, sys
|
||||||
|
wid='$WORK_ITEM_UUID'
|
||||||
|
for t in json.load(sys.stdin).get('tasks', []):
|
||||||
|
if t.get('external_id') == wid:
|
||||||
|
m=t.get('metadata') or {}
|
||||||
|
print('task_id:', t.get('id'))
|
||||||
|
print('status:', t.get('status'))
|
||||||
|
print('authoring_run_state:', m.get('authoring_run_state'))
|
||||||
|
print('push_request_state:', m.get('push_request_state'))
|
||||||
|
print('wait_type:', m.get('wait_type'))
|
||||||
|
"
|
||||||
|
```
|
||||||
|
|
||||||
|
3. git remote `develop`에 새 revision이 생겼는지 확인한다.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd "$HOME/agent-work/nomadcode-dev/workspaces/nomadcode/branches/develop"
|
||||||
|
git fetch -q origin develop
|
||||||
|
git log --oneline -1 origin/develop
|
||||||
|
git diff-tree --no-commit-id --name-status -r origin/develop
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Forgejo provider hook delivery가 성공했는지 확인한다.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker exec -i forgejo-db sh -lc 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -At' <<'SQL'
|
||||||
|
select id, hook_id, uuid, event_type, is_delivered, is_succeed, left(request_content, 400), left(response_content, 220)
|
||||||
|
from hook_task
|
||||||
|
order by id desc
|
||||||
|
limit 5;
|
||||||
|
SQL
|
||||||
|
```
|
||||||
|
|
||||||
|
기대값은 현재 `AFTER_SHA`나 milestone path가 들어 있는 push task의 `event_type=push`, `is_delivered=t`, `is_succeed=t`, response status `202`다. 동시 push가 있을 수 있으므로 단순 최신 행이 아니라 현재 테스트의 `after` revision 또는 changed file path와 매칭한다.
|
||||||
|
|
||||||
|
5. Gito가 `branch.updated` event를 만들었는지 확인한다.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
AFTER_SHA="<origin-develop-after-sha>"
|
||||||
|
tmp=$(mktemp)
|
||||||
|
curl -fsS http://127.0.0.1:18061/api/events > "$tmp"
|
||||||
|
python3 - "$tmp" "$AFTER_SHA" <<'PY'
|
||||||
|
import json, sys
|
||||||
|
with open(sys.argv[1], encoding="utf-8") as f:
|
||||||
|
data=json.load(f)
|
||||||
|
after=sys.argv[2]
|
||||||
|
for event in data.get("events", []):
|
||||||
|
rev=event.get("revision") or {}
|
||||||
|
if rev.get("after") == after:
|
||||||
|
print("event_id:", event.get("id"))
|
||||||
|
print("delivery_id:", event.get("delivery_id"))
|
||||||
|
print("repo_id:", rev.get("repo_id"))
|
||||||
|
print("branch:", rev.get("branch"))
|
||||||
|
print("changed_files:", rev.get("changed_files"))
|
||||||
|
PY
|
||||||
|
rm -f "$tmp"
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Core가 Gito webhook을 받고 Plane projection을 완료했는지 확인한다.
|
||||||
|
- Core log에 `POST /api/integrations/gito/webhook` status `202`가 있어야 한다.
|
||||||
|
- 같은 revision에서 대상 work item의 `gito creation sync enqueued`와 `roadmap creation sync completed`가 이어져야 한다.
|
||||||
|
- Core task result의 `next_step`은 `plane_todo_moved`, `authoring_run_state`는 `succeeded`여야 한다.
|
||||||
|
7. Plane API 또는 UI에서 work item state가 `Todo`인지 확인한다.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd "$HOME/agent-work/nomadcode-dev"
|
||||||
|
set -a; source .env.plane.local; set +a
|
||||||
|
python3 - <<'PY'
|
||||||
|
import os, json, ssl, urllib.request
|
||||||
|
wid="<plane-work-item-uuid>"
|
||||||
|
base=os.environ["PLANE_BASE_URL"].rstrip("/")
|
||||||
|
ws=os.environ.get("PLANE_WORKSPACE_SLUG", "general")
|
||||||
|
project=os.environ["PLANE_PROJECT_ID"]
|
||||||
|
token=os.environ["PLANE_TOKEN"]
|
||||||
|
todo=os.environ.get("PLANE_TODO_STATE_ID")
|
||||||
|
ctx=ssl._create_unverified_context()
|
||||||
|
req=urllib.request.Request(
|
||||||
|
f"{base}/api/v1/workspaces/{ws}/projects/{project}/work-items/{wid}",
|
||||||
|
headers={"X-Api-Key": token, "Accept": "application/json"},
|
||||||
|
)
|
||||||
|
with urllib.request.urlopen(req, context=ctx, timeout=20) as r:
|
||||||
|
item=json.load(r)
|
||||||
|
state_id=item.get("state") or item.get("state_id")
|
||||||
|
print(json.dumps({"work_item_id": wid, "state_id": state_id, "matches_todo_env": state_id == todo}, ensure_ascii=False))
|
||||||
|
PY
|
||||||
|
```
|
||||||
|
|
||||||
## 검증 항목
|
## 검증 항목
|
||||||
|
|
||||||
| 항목 | 증거 유형 | 단계 |
|
| 항목 | 증거 유형 | 단계 |
|
||||||
|
|
@ -95,6 +226,7 @@ for t in d.get('tasks', []):
|
||||||
| `webhook-auto-enqueue`: task가 별도 API 호출 없이 authoring queue 진입 | Core log 또는 status=running | 6 |
|
| `webhook-auto-enqueue`: task가 별도 API 호출 없이 authoring queue 진입 | Core log 또는 status=running | 6 |
|
||||||
| `live-creation-projection`: develop 스캔 → ledger steps → Plane Todo | Core log + Plane UI | 7→8 |
|
| `live-creation-projection`: develop 스캔 → ledger steps → Plane Todo | Core log + Plane UI | 7→8 |
|
||||||
| slot 재사용: 두 번째 smoke에서 slot available | API 응답 | 9 |
|
| slot 재사용: 두 번째 smoke에서 slot available | API 응답 | 9 |
|
||||||
|
| `forgejo-auto-delivery`: Forgejo hook task success + Gito branch.updated event | Forgejo DB + Gito API | dev 4→5 |
|
||||||
|
|
||||||
## 완료 오인 방지 기준
|
## 완료 오인 방지 기준
|
||||||
|
|
||||||
|
|
@ -104,8 +236,72 @@ for t in d.get('tasks', []):
|
||||||
- IOP queue timeout/stale: IOP `/v1/responses` 장시간 대기, queue timeout, stale monitor는 각각 task metadata에 관찰 가능한 상태로 남아야 한다. authoring 시작이나 단일 실패 로그만으로 terminal 완료/실패를 단정하지 않는다.
|
- IOP queue timeout/stale: IOP `/v1/responses` 장시간 대기, queue timeout, stale monitor는 각각 task metadata에 관찰 가능한 상태로 남아야 한다. authoring 시작이나 단일 실패 로그만으로 terminal 완료/실패를 단정하지 않는다.
|
||||||
- push-only 누락: authoring 응답 성공은 완료 근거가 아니다. push-only 요청, remote `develop` revision 확인, Gito wakeup 이후 reconcile evidence가 이어져야 다음 단계 완료로 본다.
|
- push-only 누락: authoring 응답 성공은 완료 근거가 아니다. push-only 요청, remote `develop` revision 확인, Gito wakeup 이후 reconcile evidence가 이어져야 다음 단계 완료로 본다.
|
||||||
- Gito delivery-only 성공: signed webhook 202 또는 duplicate 202는 delivery 증거일 뿐 full-cycle 완료 근거가 아니다. active Milestone slug reconcile enqueue, `roadmap_sync_steps`, Plane body/title/comment projection, `Todo` 이동까지 확인한다.
|
- Gito delivery-only 성공: signed webhook 202 또는 duplicate 202는 delivery 증거일 뿐 full-cycle 완료 근거가 아니다. active Milestone slug reconcile enqueue, `roadmap_sync_steps`, Plane body/title/comment projection, `Todo` 이동까지 확인한다.
|
||||||
|
- Forgejo 자동 경로 누락: Gito `/callbacks/forgejo/push`에 직접 POST해서 만든 event는 진단/복구 근거다. Forgejo hook task의 성공 delivery 또는 Forgejo UI/API redelivery 성공이 없으면 자동 Forgejo -> Gito 경로 통과 근거로 쓰지 않는다.
|
||||||
|
- allowlist 복구 후 재검증: `webhook can only call allowed HTTP servers`가 관찰된 run은 환경 문제 발견 근거로만 남긴다. allowlist 수정 후 새 Plane work item으로 한 번 더 자동 경로를 통과시켜야 한다.
|
||||||
- full-cycle 완료: 새 Plane `Backlog + AGENT assignee` authoring roundtrip과 Git에만 있는 active Milestone missing-create/reconcile roundtrip을 모두 secret redaction 상태로 남긴다.
|
- full-cycle 완료: 새 Plane `Backlog + AGENT assignee` authoring roundtrip과 Git에만 있는 active Milestone missing-create/reconcile roundtrip을 모두 secret redaction 상태로 남긴다.
|
||||||
|
|
||||||
|
## dev profile 트러블슈팅
|
||||||
|
|
||||||
|
### git push 후 `develop_match` 대기
|
||||||
|
|
||||||
|
증상:
|
||||||
|
|
||||||
|
- Core task metadata에 `push_request_state=succeeded`가 있는데 task가 `wait_type=develop_match` 또는 running 상태로 오래 남는다.
|
||||||
|
- Gito `/api/events`에 새 `after` SHA가 없다.
|
||||||
|
|
||||||
|
확인:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker exec -i forgejo-db sh -lc 'psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -At' <<'SQL'
|
||||||
|
select id, uuid, event_type, is_delivered, is_succeed, left(request_content, 400), left(response_content, 300)
|
||||||
|
from hook_task
|
||||||
|
order by id desc
|
||||||
|
limit 5;
|
||||||
|
SQL
|
||||||
|
```
|
||||||
|
|
||||||
|
`response_content`에 `webhook can only call allowed HTTP servers`가 있으면 Forgejo allowlist 문제다.
|
||||||
|
|
||||||
|
복구:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cfg="$HOME/docker/services/forgejo/data/volume/gitea/conf/app.ini"
|
||||||
|
cp "$cfg" "$cfg.bak-$(date +%Y%m%d%H%M%S)"
|
||||||
|
# [webhook] ALLOWED_HOST_LIST에 host.docker.internal을 추가한다.
|
||||||
|
grep -n "^ALLOWED_HOST_LIST" "$cfg"
|
||||||
|
cd "$HOME/docker/services/forgejo/compose"
|
||||||
|
docker compose restart forgejo || docker compose up -d --force-recreate forgejo
|
||||||
|
docker inspect forgejo --format '{{.State.Health.Status}}'
|
||||||
|
docker exec forgejo curl -fsS --max-time 5 http://host.docker.internal:18061/healthz
|
||||||
|
```
|
||||||
|
|
||||||
|
복구 후에는 기존 run을 수동 redelivery로 닫을 수 있지만, 자동 경로 판정은 새 Plane work item으로 다시 수행한다.
|
||||||
|
|
||||||
|
### Gito watch 또는 subscription 누락
|
||||||
|
|
||||||
|
증상:
|
||||||
|
|
||||||
|
- Forgejo hook task는 `202`를 받았는데 Gito `/api/events`에 event가 없다.
|
||||||
|
- `curl http://127.0.0.1:18061/api/listeners/branches` 또는 `/api/webhook-subscriptions`가 빈 목록이다.
|
||||||
|
|
||||||
|
복구:
|
||||||
|
|
||||||
|
- Gito 제공 계약의 branch watch와 webhook subscription bootstrap을 따른다.
|
||||||
|
- dev target은 `http://127.0.0.1:18011/api/integrations/gito/webhook`이다.
|
||||||
|
- signing secret 값은 직접 쓰지 말고 `secret_ref` 또는 Gito runtime의 env resolver를 사용한다.
|
||||||
|
|
||||||
|
### Plane Todo 미전환
|
||||||
|
|
||||||
|
증상:
|
||||||
|
|
||||||
|
- Forgejo hook task 성공, Gito event 생성, Core Gito webhook `202`까지 확인되었지만 Plane state가 Todo가 아니다.
|
||||||
|
|
||||||
|
확인:
|
||||||
|
|
||||||
|
- Core log에서 대상 work item의 `gito creation sync enqueued`, `roadmap creation sync completed`, `action`, `reason`을 확인한다.
|
||||||
|
- 생성된 milestone의 provider identity와 filename slug가 Plane work item과 맞는지 확인한다.
|
||||||
|
- Core task result의 `next_step=plane_todo_moved`가 없으면 완료로 보지 않는다.
|
||||||
|
|
||||||
## 대체 근거 (런타임 에퀄리번트)
|
## 대체 근거 (런타임 에퀄리번트)
|
||||||
|
|
||||||
reviewed commit을 현재 실행 중인 서버에 배포하지 않은 경우 아래 단계로 대체 근거를 수집한다.
|
reviewed commit을 현재 실행 중인 서버에 배포하지 않은 경우 아래 단계로 대체 근거를 수집한다.
|
||||||
|
|
|
||||||
|
|
@ -37,10 +37,43 @@ webhook dispatch trigger gate에 주입하는 non-secret env. secret(`PLANE_WEBH
|
||||||
## Webhook Smoke Baseline
|
## Webhook Smoke Baseline
|
||||||
|
|
||||||
- Webhook URL: `http://toki-labs.com:18010/api/integrations/plane/webhook`
|
- Webhook URL: `http://toki-labs.com:18010/api/integrations/plane/webhook`
|
||||||
|
- Dev profile Core endpoint on the remote host: `http://127.0.0.1:18011/api/integrations/plane/webhook`
|
||||||
- Webhook secret storage: SOPS encrypted `secrets/nomadcode.dev.sops.yaml` key `PLANE_WEBHOOK_SECRET`
|
- Webhook secret storage: SOPS encrypted `secrets/nomadcode.dev.sops.yaml` key `PLANE_WEBHOOK_SECRET`
|
||||||
- 2026-06-14 webhook-only smoke used existing Backlog items `NOMAD-10` and `NOMAD-11` by assigning AGENT.
|
- 2026-06-14 webhook-only smoke used existing Backlog items `NOMAD-10` and `NOMAD-11` by assigning AGENT.
|
||||||
- 2026-06-15 live smoke used new Backlog item `93b677f5-7913-4111-ae05-916033ae533b` (WEBHOOK_SMOKE-test-1781525263). Webhook delivery succeeded (202 Accepted) and triggered authoring run with Core Task ID `e3c92411-4056-4b76-a879-66f7904125d0`.
|
- 2026-06-15 live smoke used new Backlog item `93b677f5-7913-4111-ae05-916033ae533b` (WEBHOOK_SMOKE-test-1781525263). Webhook delivery succeeded (202 Accepted) and triggered authoring run with Core Task ID `e3c92411-4056-4b76-a879-66f7904125d0`.
|
||||||
|
|
||||||
|
## Dev Full-Cycle Baseline
|
||||||
|
|
||||||
|
2026-07-03 dev profile에서 Plane-origin milestone 생성 roundtrip을 확인했다. 이 섹션은 non-secret evidence만 기록한다.
|
||||||
|
|
||||||
|
### Primary automatic proof
|
||||||
|
|
||||||
|
- Plane work item: `982c14b6-b57f-4de9-8773-bcf00fe1d25a`
|
||||||
|
- Created title marker: `LIVE-SYNC post-allowlist auto smoke 1783057173`
|
||||||
|
- Core task: `89e40ba4-efbd-4254-b873-48e54e33ade0`
|
||||||
|
- git `origin/develop`: `42b0d1a8a5790a6fb93f84cf04925d06a0290ce7`
|
||||||
|
- commit summary: `42b0d1a docs(roadmap): post allowlist smoke 마일스톤을 추가한다`
|
||||||
|
- added milestone path: `agent-roadmap/phase/agent-ops-mcp-control-plane/milestones/post-allowlist-automatic-plane-git-gito-plane-smoke-1783057173.md`
|
||||||
|
- Forgejo provider delivery: `c77f67fe-3e18-484e-b292-9813e1c741e4`, hook task `is_succeed=t`, Gito callback status `202`
|
||||||
|
- Gito event: `event-de33bb1fc267c84a`, type `branch.updated`, repo `nomadcode`, branch `develop`
|
||||||
|
- Plane final state: `Todo` (`45ba7449-f684-4381-af6d-5854747c5e8d`)
|
||||||
|
|
||||||
|
### Diagnostic run
|
||||||
|
|
||||||
|
- Plane work item: `67706758-9555-456b-b051-547fa6b4f093`
|
||||||
|
- git `origin/develop`: `738f4b8d202e9254f7c4c8fe91bb6f5e729100f0`
|
||||||
|
- This run exposed a dev Forgejo allowlist issue before the automatic provider delivery path was fixed.
|
||||||
|
- The run was completed after Gito callback redelivery, so it is evidence for Core/Gito/Plane projection recovery but not primary proof of automatic Forgejo -> Gito delivery.
|
||||||
|
|
||||||
|
## Agent Usage Notes
|
||||||
|
|
||||||
|
- 새 full-cycle test item은 `Backlog` state와 AGENT assignee로 만든다.
|
||||||
|
- 제목/본문에는 timestamp marker를 넣어 git commit, milestone slug, Plane item을 쉽게 대조할 수 있게 한다.
|
||||||
|
- 요청 범위는 roadmap milestone 문서처럼 작은 산출물로 제한하고, 기능 코드 구현이나 contract 변경을 요구하지 않는다.
|
||||||
|
- full-cycle 통과 판정은 `agent-test/live-cycle-smoke.md`의 dev profile 자동 경로 체크리스트를 따른다.
|
||||||
|
- `Todo` 이동 확인 전에는 Plane item이 완료됐다고 보고하지 않는다.
|
||||||
|
- raw API token, webhook secret, provider credential, private key는 이 문서나 최종 응답에 기록하지 않는다.
|
||||||
|
|
||||||
## Webhook Payload Fixtures
|
## Webhook Payload Fixtures
|
||||||
|
|
||||||
`services/core/internal/http/testdata/` 아래 fixture로 payload shape를 고정한다. 모든 fixture는 PII/secret redaction 상태이며 work item id는 placeholder다.
|
`services/core/internal/http/testdata/` 아래 fixture로 payload shape를 고정한다. 모든 fixture는 PII/secret redaction 상태이며 work item id는 placeholder다.
|
||||||
|
|
@ -48,4 +81,3 @@ webhook dispatch trigger gate에 주입하는 non-secret env. secret(`PLANE_WEBH
|
||||||
- `plane_webhook_issue_assignees_updated.json`: live dev Plane assignee-update 로그 기반 redacted 샘플 (`event=issue`, `action=updated`, `activity.field=assignees`).
|
- `plane_webhook_issue_assignees_updated.json`: live dev Plane assignee-update 로그 기반 redacted 샘플 (`event=issue`, `action=updated`, `activity.field=assignees`).
|
||||||
- `plane_webhook_issue_created.json`: create 후보. live create 로그를 따로 확보하지 않아 관찰된 issue envelope 기반 synthetic candidate다 (`event=issue`, `action=created`, Backlog state).
|
- `plane_webhook_issue_created.json`: create 후보. live create 로그를 따로 확보하지 않아 관찰된 issue envelope 기반 synthetic candidate다 (`event=issue`, `action=created`, Backlog state).
|
||||||
- `plane_webhook_issue_state_updated.json`: state-change 후보. synthetic candidate다 (`event=issue`, `action=updated`, `activity.field=state`, Backlog -> Todo).
|
- `plane_webhook_issue_state_updated.json`: state-change 후보. synthetic candidate다 (`event=issue`, `action=updated`, `activity.field=state`, Backlog -> Todo).
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue