282 lines
26 KiB
Markdown
282 lines
26 KiB
Markdown
---
|
|
schema_version: 2
|
|
session_id: 20260618-104034
|
|
resumed_from: null
|
|
started_at: 2026-06-18T10:40:34+09:00
|
|
ended_at: 2026-06-18T13:20:00+09:00
|
|
user_request: |
|
|
W3-2 댓글/리뷰 분리 기능을 설계·구현한다.
|
|
- game_comments 로그인 연동 전환 + content 200자 제한
|
|
- game_reviews 신규 (게임당 1회, 별점 5점 + 서술 평가)
|
|
- 댓글 수정/삭제 권한: 작성자 본인 + 운영자
|
|
- 리뷰 수정: 가능 + 이력 보존, 노출은 "수정됨" 마커만
|
|
- 보안: CSRF 검증, XSS escape, 작성자 권한 체크
|
|
- 자율 진행: 미결은 안전 기본값으로 진행 + 이월 기록. 데이터 손실/하류 파손 결정만 사용자 확인.
|
|
- 프론트는 /frontend-design 스킬 사용.
|
|
acceptance criteria:
|
|
- 로그인 사용자 댓글 작성/수정/삭제, 비작성자 불가(운영자 예외)
|
|
- 리뷰 게임당 1회, 수정 시 "수정됨" 마커 + 이력 보존
|
|
- 댓글 201자 이상 거부
|
|
- CSRF 토큰 없는 상태변경 실패
|
|
- XSS payload 미실행
|
|
- 새로고침/브라우저 변경 후 영속
|
|
---
|
|
|
|
# Summary
|
|
W3-2 댓글/리뷰 분리 기능을 설계·구현했다. research 가 작업 브리프의 seed 가정 2건을 뒤집었다(① 댓글·좋아요가 서버 미연동 localStorage 전용이고 서버 매퍼는 orphan, ② 운영자 role 이 코드에 부재—USER만 발급). §2.7-5 plan gate 로 사용자 확정 후, 댓글을 서버 영속화(fetch API + user_id 귀속 + 200자) + game_reviews 도메인 신설(게임당 1회 partial UNIQUE, 별점 1~5, 수정됨=updated_at>created_at in-row, 휴면 운영자 경로)로 진행했다.
|
|
|
|
백엔드 14파일(DDL 3종 + POJO/Mapper/Controller 신규·변경 + 테스트 2), 프론트(game-detail.jsp 댓글 서버화 + 리뷰 UI·별점 위젯·수정됨 마커, /frontend-design 스킬)를 구현했다. 검증 1차에서 BibimbapApplicationTests.contextLoads 회귀(신규 매퍼 @MockBean 누락) 1건이 잡혀 §2.6 backward re-dispatch 로 발원(implementation 테스트 scaffolding)을 진단·전수재검 후 2개 @MockBean 추가로 해소. 최종 L1 31 테스트 PASS + AGG 전수 PASS. L3(브라우저 XSS·영속·cascade DB)는 needs_user_verification. DDL 미적용(§6 게이트 — 사용자 DB 적용 대기).
|
|
|
|
# Advisor Invocation Decision Log
|
|
# 각 advisor 호출/스킵 판단 즉시 1줄 append
|
|
- advisor: requirements-advisor
|
|
decision: skip
|
|
rationale: '요청에 FR/in/out/이월 기본값/AC 가 전부 명시됨. 단 옵션 공간 판정은 design 산출 이후로 보류(프로토콜 §1).'
|
|
checked_at: 2026-06-18T10:40:34+09:00
|
|
- advisor: graphify-lookup-advisor
|
|
decision: call
|
|
rationale: '코드 구조 조사 1차 진입점. game_comments/games/로그인·세션/CSRF/JSP 댓글/DDL 적용방식 결합점 확인 필요.'
|
|
checked_at: 2026-06-18T10:41:00+09:00
|
|
result: 'src scope graph.json 미생성(no-graph). docs scope만 hit(DDL/스키마 부트스트랩). 코드 포인트 7/7 miss → research 필요.'
|
|
- advisor: research-advisor
|
|
decision: call
|
|
rationale: 'lookup 7/7 miss. 댓글 CRUD·게임상세·로그인세션·CSRF·DDL적용·RecruitController·GameLikes 코드 결합점 직접 조사 필요. parallel-explorer 병렬.'
|
|
checked_at: 2026-06-18T10:45:00+09:00
|
|
- advisor: graphify-update-advisor (src scope 재생성)
|
|
decision: defer
|
|
rationale: '구현으로 src 변경 예정 → 지금 재생성하면 이중 작업. 세션 종료 전 graph-refresh 단계에서 일괄 재생성(no-defer 정책은 그 시점 처리로 충족).'
|
|
checked_at: 2026-06-18T10:45:00+09:00
|
|
- advisor: research-advisor
|
|
decision: re-call
|
|
rationale: '1차 호출이 async worker 6개 spawn 후 취합 전 rest 복귀 — code-coupling.md 미산출. SendMessage 미제공으로 재개 불가. 강한 블로킹 지시로 재호출(worker TaskOutput 대기 + 파일 디스크 기록 후에만 반환).'
|
|
checked_at: 2026-06-18T10:52:00+09:00
|
|
|
|
# Invocations
|
|
- id: inv-000
|
|
layer: orchestrator
|
|
name: orchestrator
|
|
parent_invocation_id: null
|
|
started_at: 2026-06-18T10:40:34+09:00
|
|
input_digest: 'W3-2 댓글/리뷰 분리 설계·구현 요청 (자율 진행 모드)'
|
|
output_digest: 'init 가드 통과, atp:migrate 마커 없음(skip), work-session 생성, 프로토콜 로드'
|
|
artifacts: ['.atp/work-session/20260618-104034/report.md']
|
|
concerns: []
|
|
- id: inv-001
|
|
layer: advisor
|
|
name: graphify-lookup-advisor
|
|
parent_invocation_id: inv-000
|
|
input_digest: '코드 구조 7포인트 graph 인덱스 조회'
|
|
output_digest: 'src scope graph 미생성(no-graph), docs만 hit, 7/7 miss → research 필요'
|
|
artifacts: []
|
|
model_choice: { phase: graphify-exec, dispatch_size: direct, tier: small, effort: low, resolved_model: haiku, capped: false, rationale: '인덱스 조회 기계적 판단' }
|
|
- id: inv-002
|
|
layer: advisor
|
|
name: research-advisor
|
|
parent_invocation_id: inv-000
|
|
input_digest: '11개 코드 결합점 정밀 조사(file:line)'
|
|
output_digest: 'research/code-coupling.md — 댓글/좋아요 서버미연동 발견, CSRF/세션 인프라 재사용 가능, 운영자 role 부재'
|
|
artifacts: ['research/code-coupling.md']
|
|
model_choice: { phase: analyze, dispatch_size: l-batch, tier: large, effort: high, resolved_model: opus, capped: false, escalation_reason: '탐색적 코드 조사 + 다파일 교차', rationale: '결합점 정확도가 설계 좌우' }
|
|
notes: '1차 호출(a2177)이 async worker 취합 전 조기복귀 → 강한 블로킹 지시로 재호출(a4873) 성공. 두 호출 모두 동일 결론.'
|
|
- id: inv-003
|
|
layer: advisor
|
|
name: design-advisor
|
|
parent_invocation_id: inv-000
|
|
input_digest: 'research + plan gate 결정 → 구현가능 설계'
|
|
output_digest: 'design.md — DDL 3종/9 API/권한모델/cascade/AC 13(기능10+전수3)'
|
|
artifacts: ['design.md']
|
|
model_choice: { phase: design, dispatch_size: l-batch, tier: large, effort: high, resolved_model: opus, capped: false, escalation_reason: '보안·인증·권한 §5.2 자동상승', rationale: 'trade-off 빈번' }
|
|
- id: inv-004
|
|
layer: advisor
|
|
name: implementation-advisor
|
|
parent_invocation_id: inv-000
|
|
input_digest: 'design.md 권위 명세 → 백엔드 구현 + 마이그레이션 파일'
|
|
output_digest: '14파일(DDL3+POJO+Mapper+Controller+test2). test-compile BUILD SUCCESS. workers_spawned=0(직접). implementation/ownership.md'
|
|
artifacts: ['implementation/ownership.md']
|
|
model_choice: { phase: code-implementation, dispatch_size: l-batch, tier: large, effort: high, resolved_model: opus, capped: false, escalation_reason: '보안/권한 코드', rationale: '다파일 강결합 직접 작성' }
|
|
planned_workers: 0
|
|
actual_workers: 0
|
|
- id: inv-005
|
|
layer: orchestrator
|
|
name: orchestrator (frontend via /frontend-design)
|
|
parent_invocation_id: inv-000
|
|
input_digest: 'game-detail.jsp 댓글 서버화 + 리뷰 UI (브리프 지정 /frontend-design 스킬, §1 사용자명시 예외)'
|
|
output_digest: 'GameController 모델 노출(currentUserId/userRole) + game-detail.jsp HTML/CSS/JS(별점위젯·수정됨·로그인게이트, textContent XSS안전). test-compile SUCCESS'
|
|
artifacts: ['src/main/webapp/WEB-INF/views/game-detail.jsp']
|
|
model_choice: { phase: code-implementation, dispatch_size: direct, tier: large, effort: high, resolved_model: inherit, capped: false, rationale: 'orchestrator 본 모델 직접(스킬 가이드)' }
|
|
- id: inv-006
|
|
layer: advisor
|
|
name: verification-advisor
|
|
parent_invocation_id: inv-000
|
|
input_digest: 'AC 13 + 실행명령(설계/diff 비접근)'
|
|
output_digest: '1차 fail(contextLoads 회귀 blocker). 수정 후 재실행 31 PASS + AGG 전수 PASS'
|
|
artifacts: ['verification.md']
|
|
model_choice: { phase: validation-static, dispatch_size: s-batch, tier: medium, effort: medium, resolved_model: sonnet, capped: false, rationale: '결정적 테스트/grep 판정' }
|
|
- id: inv-007
|
|
layer: orchestrator
|
|
name: orchestrator (regression fix §2.6)
|
|
parent_invocation_id: inv-000
|
|
input_digest: 'contextLoads blocker — 신규 매퍼 @MockBean 누락'
|
|
output_digest: 'BibimbapApplicationTests 에 GameCommentsMapper/GameReviewsMapper @MockBean 2개 추가(기존 4개 패턴 미러). 재실행 31 PASS'
|
|
artifacts: ['src/test/java/com/pandoli365/bibimbap/BibimbapApplicationTests.java']
|
|
model_choice: { phase: code-implementation, dispatch_size: direct, tier: large, effort: low, resolved_model: inherit, capped: false, rationale: '결정적 2줄 마이크로 편집 §1 예외' }
|
|
|
|
# Decisions
|
|
- by: research-advisor + user (plan gate §2.7-5)
|
|
at: 2026-06-18T11:10:00+09:00
|
|
decision: '댓글/좋아요 서버 미연동(localStorage 전용) seed 반전 확인. 댓글 완전 서버화 채택(Q1=Recommended).'
|
|
rationale: 'AC "브라우저 변경 후 영속"이 서버화를 강제. localStorage JS→fetch 교체 포함. 기존 localStorage 댓글 비마이그레이션(보안 [hold] 정합).'
|
|
related_invocations: [inv-002]
|
|
- by: user (plan gate §2.7-5)
|
|
at: 2026-06-18T11:10:00+09:00
|
|
decision: '운영자 예외 = 휴면 운영자 경로(Q2=Recommended). 권한체크 "작성자 OR 운영자급 role", ADMIN 상수 정의, 부여자 없음(W1 연결).'
|
|
rationale: '브리프 "W1 완료 시 교체 가능 설계"와 정합. 단위테스트로 운영자 분기 검증, prod 무영향.'
|
|
related_invocations: [inv-002]
|
|
- by: orchestrator (브리프 이월 기본값)
|
|
at: 2026-06-18T11:10:00+09:00
|
|
decision: '별점 5점 단일 확정(다축 컬럼 확장여지). 댓글/리뷰 2 테이블 분리(game_comments 변경 + game_reviews 신규). 좋아요 범위밖 localStorage 유지. W2-3 집계계약 이월(평점 컬럼만 확정). QG-2 비파괴(user_id nullable + 레거시 표시) — 테이블 사실상 빈 상태 추정.'
|
|
rationale: '브리프 이월 기본값 + research 결합점. 되돌릴 수 있어 carry-over 안전.'
|
|
related_invocations: [inv-001, inv-002]
|
|
|
|
# Conflicts
|
|
(없음 — 단일 design-advisor, concerns 4건 모두 동결영역 비침범 자가확인. 충돌 중재 불요.)
|
|
|
|
# Regression
|
|
- surfaced_at_stage: verification (L1 전체 테스트)
|
|
source_stage: implementation (테스트 scaffolding)
|
|
defect: 'BibimbapApplicationTests.contextLoads — 신규 GameCommentController/GameReviewController 가 주입하는 GameCommentsMapper/GameReviewsMapper 가 MyBatis autoconfigure exclude 컨텍스트 테스트의 @MockBean 셋에 미등록 → NoSuchBeanDefinitionException'
|
|
full_set_recheck: true # 컨트롤러 주입 매퍼 전수 점검: {Games,Recruit,UserAuthIdentities,Users,GameComments,GameReviews} 중 누락 2개만 추가하면 완전 확인
|
|
downstream_rerun: ['L1 전체 테스트 재실행 — 31 PASS']
|
|
resolved_at: 2026-06-18T12:55:00+09:00
|
|
|
|
# verified_by_me
|
|
- 'L1 typecheck/compile: ./mvnw -o test-compile BUILD SUCCESS'
|
|
- 'L1 unit+regression: ./mvnw -o test — Tests run 31, Failures 0, Errors 0 (GameCommentControllerTest 12 + GameReviewControllerTest 13 + UserControllerCsrfTest 5 + BibimbapApplicationTests 1). 회귀 0.'
|
|
- 'AGG-1 엔드포인트: GameCommentController @Mapping==4, GameReviewController==5 (PASS)'
|
|
- 'AGG-3 CSRF 게이트: CsrfTokens.isValid 합 6 (mutation 6개 전수, PASS)'
|
|
- 'AGG-2 DDL 3종: schema.sql game_reviews CREATE + game_comments user_id, docs/game-reviews-ddl.sql 존재 + 멱등 ALTER (PASS)'
|
|
- 'L2: skipped — no-external-dependency (커스텀 세션/CSRF, mock 기반 단위)'
|
|
|
|
# needs_user_verification
|
|
- 'L3 실 톰캣+DB 스모크: 게임 상세 페이지에서 (a) 로그인 후 댓글 작성/수정/삭제, (b) 리뷰 작성→게임당 1회(2번째 409)→수정 시 "수정됨" 표시, (c) <script> payload 입력 후 스크립트 미실행(textContent escape), (d) 새로고침/다른 브라우저에서 영속 확인, (e) 게임 삭제 후 댓글·리뷰 정리 확인.'
|
|
- 'DDL 적용: [완료 — 로컬 dev] 사용자 승인 후 orchestrator 가 docs/game-reviews-ddl.sql 을 로컬 dev DB(bibimbap-db postgres:16, localhost:5433, schema=dev)에 --single-transaction 적용. game_reviews(컬럼9/제약4/인덱스2) + game_comments.user_id 생성 검증, 멱등 재실행 error 0. **잔여: live 스키마는 배포 시 동일 적용 필요**(현 적용은 dev 한정).'
|
|
|
|
# Open Items
|
|
- 'git 미커밋 잔여: 본 작업 단위(W3-2)의 변경 5 modified + 9 untracked(src) + docs/game-reviews-ddl.sql. 프로젝트 커밋 정책(사용자 요청 시 커밋)에 따라 커밋 대기 — 사용자 확인 후 진행.'
|
|
- '이월: W2-3 평점 집계 계약(game_reviews 는 평점 공급원까지만, 집계 컬럼/뷰 미생성). W2-6 시상 집계는 후속 SELECT AVG/COUNT 로 소비.'
|
|
- '이월: 운영자 role 부여 경로 — ROLE_ADMIN="ADMIN" 상수만 정의, 실제 ADMIN 부여자 없음(W1 RBAC/Interceptor 연결 시 활성).'
|
|
- '이월: 다축(육각형) 평점 — 현재 단일 rating, 향후 game_review_axes 분리 여지(주석).'
|
|
- '이월: 리뷰 이력 열람 — 현재 in-row(수정됨 마커만), history 테이블은 열람권한 확정 시 후속.'
|
|
- '범위밖: 좋아요 영속화(여전히 localStorage) — 보안 체크리스트 별도 항목.'
|
|
- '범위밖: GameCatalog 정적 폴백 게임(DB 미존재)은 댓글/리뷰 mutation 시 404(게임존재 검증). 실 게임만 기능 동작.'
|
|
|
|
# graph_refresh
|
|
- judgment: 'src=no-graph(산출물 부재 — 세션 시작 시점부터 pre-existing, W3-2 무관) + working-tree fully-stale 수준 변경 / docs=partial-stale(신규 문서4 + game-reviews-ddl.sql 미반영)'
|
|
handling: '커밋 시점 처리(no-defer 정책 — 미래 세션 이월 아님). checker 권고대로 미커밋 tree 에서 graphify 시 source_commit 부정확 → 커밋 직후 /graphify src + /graphify docs 실행 + docs/graph/index.md frontmatter·Scopes 표 갱신. 커밋이 사용자 요청 대기 중이므로 graph 재생성도 커밋 단계에 동반.'
|
|
|
|
# Applied Changes (orchestrator — §12 회고 반영)
|
|
- 'MEMORY task_completion 갱신: 신규 컨트롤러/매퍼 의존 추가 시 BibimbapApplicationTests @MockBean 등록 누락 → contextLoads 실패 함정 + full test 의무 (candidate 2, negative).'
|
|
- 'docs_sync: docs/development/verification-strategies.md 에 "신규 컨트롤러/매퍼 의존 변경 시 full test 의무" 규칙 추가 (candidate 2 docs_sync_target).'
|
|
- 'candidate 1(worker-spawn advisor 블로킹+write-before-return): 본 세션에서 선제 적용으로 재발 0. protocol_feedback 로 surface(아래).'
|
|
- 'candidate 3(plan-gate 마일스톤): changes/2026-06-18 문서가 이미 기록 — 별도 MEMORY 미작성.'
|
|
- 'protocol_feedback 2건(structural)은 atp 플러그인 `agent-team-protocol.md`(= ~/.claude/ 전역설정) 수정 제안 → §6 전역설정 수정 금지로 orchestrator 가 직접 적용하지 않음. 사용자에게 surface(플러그인 유지자 결정 영역). (1) worker-spawn advisor 블로킹 규약 명문화 (2) implementation 단계 컨트롤러 추가 시 full test 의무.'
|
|
|
|
# User Signals
|
|
user_signals:
|
|
positive:
|
|
- quote_or_paraphrase: 'plan gate 2개 질문에 즉시 Recommended 선택(완전 서버화 + 휴면 운영자 경로)'
|
|
about: 'seed 반전 후 제시한 기본값 방향이 사용자 의도와 정합 — 1회 수락'
|
|
negative: []
|
|
|
|
# Retrospective
|
|
Retrospective:
|
|
signals:
|
|
positive:
|
|
- quote_or_paraphrase: 'plan gate 2개 질문에 즉시 Recommended 선택(완전 서버화 + 휴면 운영자 경로)'
|
|
about: 'research가 seed 가정 2건 반전 후 plan gate에서 제시한 기본값 방향(Q1=완전 서버화, Q2=휴면 운영자 경로)이 사용자 의도와 1회 수락으로 정합됨. 비자명한 판단(localStorage 전용 댓글을 완전 서버화로 전환하는 방향, 운영자 role 미정의 상태에서 휴면 경로 채택)이 재확인됨.'
|
|
negative: []
|
|
what_went_well:
|
|
- 'research-advisor가 seed 가정 2건(댓글 서버 미연동, 운영자 role 부재)을 file:line 근거로 반전시키고 plan gate로 사용자 위임한 흐름이 1회 수락으로 완결. 기존 memory [[research-seed-reversal-plan-gate-delegation]]의 패턴이 bibimbap 세션에서도 재현됨.'
|
|
- 'implementation-advisor가 worker 0(advisor 직접 작성)을 선택한 판단이 옳았음. 파일 12개이나 POJO→Mapper→Controller→Test 강결합으로 분산 시 계약 동기화 비용 > 병렬 이득. 기존 memory [[implementation-advisor-direct-execution-threshold]] 패턴과 일치.'
|
|
- 'verification-advisor가 §2.6 backward re-dispatch를 발동해 contextLoads 회귀를 blocker 판정 후 발원 단계(implementation 테스트 scaffolding)까지 소급 진단. 컨트롤러 주입 매퍼 전수 재검 후 누락 2개만 정확히 식별.'
|
|
- 'research-advisor 2차 호출 시 강한 블로킹 지시("worker TaskOutput 대기 + 파일 디스크 기록 후에만 반환")를 넣자 code-coupling.md 정상 산출. 이후 implementation/verification 호출에 같은 지시를 선제 적용해 재발 0.'
|
|
what_to_improve:
|
|
- '[패턴 1] research-advisor(tier-3, worker spawn) 가 worker 6개 spawn 후 취합 전 조기복귀. code-coupling.md 미산출 → orchestrator가 SendMessage 없이 재호출. 호출 비용 이중 발생 + 세션 지연. 블로킹 지시가 없으면 advisor가 async spawn 후 결과 대기 없이 반환하는 것이 기본 동작인 것으로 보임. → 프로토콜 수준 대응 필요(protocol_feedback 참조).'
|
|
- '[패턴 2] implementation-advisor가 test-compile(./mvnw -o test-compile)만 실행하고 full context test(./mvnw -o test)를 생략. BibimbabApplicationTests.contextLoads 회귀 미탐지 → verification에서 뒤늦게 발견. contextLoads는 MyBatis autoconfigure exclude + 신규 컨트롤러 @MockBean 수동 제공 패턴이므로, 컨트롤러 추가 시마다 @MockBean 갱신이 필요한데 이것이 implementation 단계에서 체크되지 않음.'
|
|
memory_candidates:
|
|
- name: worker-spawn-advisor-blocking-write-before-return
|
|
type: feedback
|
|
description: worker를 spawn하는 advisor는 모든 worker의 TaskOutput 완료 대기 + 산출 파일 디스크 기록 후에만 반환해야 한다. 블로킹 지시 없이 호출하면 async spawn 후 조기복귀 → 산출물 미생성 재호출 비용 발생.
|
|
body_draft: |
|
|
advisor가 병렬 worker(parallel-explorer 등)를 spawn할 때, 호출 측이 명시적 블로킹 지시를 넣지 않으면 advisor가 worker TaskOutput을 취합하지 않고 조기복귀하는 사례가 관측됨(20260618-104034 research-advisor 1차 호출: worker 6개 spawn 후 code-coupling.md 미산출 복귀).
|
|
|
|
**Why:** SendMessage 툴이 호스트 컨텍스트에 미제공인 경우 advisor가 subagent 재개 수단이 없어 결과를 기다리지 않고 반환할 수 있다. 강한 블로킹 지시를 명시하면 advisor가 tool 반환값(TaskOutput)을 동기적으로 기다리게 된다.
|
|
|
|
**How to apply:**
|
|
- worker spawn이 예상되는 advisor(research-advisor, analysis-advisor 등) 호출 시 orchestrator는 다음 문구를 프롬프트 마지막에 명시한다:
|
|
"worker를 spawn한 경우 모든 worker의 TaskOutput을 완료까지 대기하고, 산출 파일을 디스크에 기록한 후에만 반환하라. 결과 취합 전 반환 금지."
|
|
- 재호출 1회 이내에 성공한 경우라도, 이후 동일 advisor 호출(implementation, verification 포함)에 선제 적용해 재발 차단.
|
|
- 산출 파일 존재 여부는 orchestrator가 advisor 반환 직후 Glob/Read로 확인 가능.
|
|
rationale_for_saving: worker spawn 패턴은 research/analysis advisor에서 반복 재현 가능. SendMessage 미제공 환경에서는 구조적으로 재발한다. 코드/커밋으로 유도 불가한 호출 규약 지식.
|
|
signal_source: negative
|
|
docs_sync_target: null
|
|
|
|
- name: spring-context-test-mockbean-exhaustive-on-new-controller
|
|
type: feedback
|
|
description: Spring Boot 컨텍스트 테스트(MyBatis autoconfigure exclude + @MockBean 패턴)에서 신규 컨트롤러 추가 시 해당 컨트롤러가 주입하는 모든 매퍼의 @MockBean을 반드시 등록해야 한다. implementation 단계에서 full context test(./mvnw -o test)를 실행해야 누락 탐지 가능.
|
|
body_draft: |
|
|
BibimbapApplicationTests는 DataSource/MyBatis autoconfigure를 exclude하고 컨트롤러가 주입하는 매퍼를 @MockBean으로 수동 제공하는 패턴이다. 이 패턴에서 신규 컨트롤러(GameCommentController, GameReviewController)를 추가할 때 해당 컨트롤러가 주입하는 매퍼(GameCommentsMapper, GameReviewsMapper)의 @MockBean을 BibimbabApplicationTests에 추가하지 않으면 contextLoads가 NoSuchBeanDefinitionException으로 실패한다.
|
|
|
|
**Why:** implementation-advisor가 test-compile(./mvnw -o test-compile)만 실행하면 컨트롤러 클래스는 컴파일되지만, full Spring context 로드는 ./mvnw -o test를 실행해야만 검증된다. 컴파일 성공 ≠ contextLoads 통과. 세션 20260618-104034에서 이 미탐지로 verification 단계에서 blocker가 발생했다.
|
|
|
|
**How to apply:**
|
|
- implementation-advisor는 컨트롤러 파일을 추가/변경할 때 반드시 ./mvnw -o test를 실행해 contextLoads 회귀를 탐지해야 한다. test-compile만으로는 불충분.
|
|
- 신규 컨트롤러 추가 체크리스트: (1) 컨트롤러가 @Autowired/@RequiredArgsConstructor로 주입하는 모든 @Mapper 인터페이스를 나열, (2) BibimbabApplicationTests의 기존 @MockBean 선언(@MockBean GameCommentsMapper 등) 목록과 대조, (3) 누락 항목에 @MockBean 추가.
|
|
- 이 프로젝트의 현행 @MockBean 목록: GamesMapper, RecruitPostsMapper, UserAuthIdentitiesMapper, UsersMapper, GameCommentsMapper, GameReviewsMapper (W3-2 추가 후 기준).
|
|
rationale_for_saving: 이 프로젝트 특유의 MyBatis autoconfigure exclude + @MockBean 수동 패턴은 컨트롤러를 추가할 때마다 재발 가능한 구조적 함정. 코드/커밋에서 유도 불가(테스트 파일을 직접 읽어야만 파악 가능). 후속 W3-x, W4-x 세션에서 컨트롤러 추가가 예상되므로 재현성 높음.
|
|
signal_source: negative
|
|
docs_sync_target: /Users/wemadeplay/workspace/stz/bibimbap/docs/development/verification-strategies.md
|
|
|
|
- name: bibimbap-plan-gate-seed-reversal-two-q-accepted
|
|
type: project
|
|
description: W3-2 세션에서 research가 seed 가정 2건 반전 후 plan gate 2질문 즉시 수락. 기본값 방향(완전 서버화 + 휴면 운영자 경로)이 사용자 의도와 정합 확인됨.
|
|
body_draft: |
|
|
W3-2(댓글/리뷰 분리) 세션(20260618-104034)에서 research-advisor가 seed 가정 2건을 반전:
|
|
- GAP-1: 댓글/좋아요가 서버 미연동 localStorage 전용(서버화 가정 깨짐)
|
|
- GAP-3: 운영자 role이 코드 전체에 부재("USER"만 발급)
|
|
|
|
Plan gate 2질문 모두 Recommended(완전 서버화 / 휴면 운영자 경로) 즉시 수락.
|
|
|
|
**확인된 패턴:** [[research-seed-reversal-plan-gate-delegation]]이 bibimbap 프로젝트에서도 동작함. seed 반전 + Recommended 기본값 방향 제시 조합이 사용자 의사결정 비용을 최소화한 케이스로 기록.
|
|
rationale_for_saving: bibimbap 프로젝트 히스토리 마일스톤. W3 진행 중 댓글/좋아요가 localStorage 전용이었다는 사실은 후속 W3-x/W4-x 세션에서 참고 필요. 또한 운영자 경로(ROLE_ADMIN="ADMIN" 상수 정의, 부여자 미구현)가 W1 RBAC 연결 전 휴면 상태라는 결정 이력.
|
|
signal_source: positive
|
|
docs_sync_target: null
|
|
|
|
protocol_feedback:
|
|
- issue: 'worker를 spawn하는 advisor(tier-3)의 조기복귀가 프로토콜 허점임. SendMessage 미제공 환경에서 advisor가 async worker spawn 후 TaskOutput 취합 없이 반환하는 동작을 방지하는 명시적 규약이 없다.'
|
|
structural: true
|
|
detail: |
|
|
현상: research-advisor 1차 호출이 worker 6개 spawn 후 취합 전 반환 → code-coupling.md 미산출 → 재호출 비용.
|
|
근본 원인: 프로토콜에 "worker spawn 후 반환 조건"이 없음. 개별 호출 시 orchestrator가 블로킹 지시를 매번 수동으로 포함해야 해결됨 — 즉 규약이 아니라 ad-hoc 대응.
|
|
proposed_fix: |
|
|
agent-team-protocol.md (bibimbap 번들 또는 ATP 원본) 에 다음 규약 추가:
|
|
§ [worker spawn 완료 조건] advisor가 worker를 spawn하는 경우:
|
|
1. 모든 worker의 TaskOutput이 도달할 때까지 반환하지 않는다 (blocking-wait).
|
|
2. 약속된 산출 파일을 디스크에 기록 완료한 것을 확인 후 반환한다.
|
|
3. orchestrator는 advisor 반환 직후 산출 파일 존재 여부를 Glob/Read로 확인한다. 미존재 시 즉시 블로킹 지시 추가 후 재호출한다.
|
|
[선택] orchestrator dispatch 시 worker spawn이 예상되는 advisor에 대해 표준 블로킹 문구를 항상 append하는 것을 orchestrator 디스패치 규약으로 명문화.
|
|
docs_target: docs/development/agent-team-protocol.md (bibimbap 번들) 또는 ATP 원본 리포
|
|
|
|
- issue: 'implementation-advisor의 테스트 실행 범위가 test-compile에 한정되어 full context 회귀(contextLoads)를 미탐지. verification 단계에서 blocker로 발견되어 §2.6 backward re-dispatch 비용 발생.'
|
|
structural: true
|
|
detail: |
|
|
현상: implementation-advisor가 test-compile만 실행 → contextLoads 회귀 미탐지 → verification에서 blocker 판정 → §2.6 backward re-dispatch.
|
|
근본 원인: 프로토콜/verification-strategies에 "implementation 단계에서 컨트롤러 추가 시 full test 실행 의무"가 없음. 컴파일 성공을 단위 검증 완료로 간주하는 암묵적 관행.
|
|
proposed_fix: |
|
|
verification-strategies.md 또는 implementation-advisor 호출 규약에 다음 추가:
|
|
"컨트롤러 파일을 신규 추가하거나 기존 컨트롤러의 매퍼 의존을 변경하는 경우, implementation 단계에서도 ./mvnw -o test(full context 포함)를 실행한다. test-compile만으로는 Spring ApplicationContext 로드 실패를 탐지할 수 없다."
|
|
단, 프로젝트별 test 실행 시간이 긴 경우 -Dtest=BibimbabApplicationTests만 별도 실행하는 것도 허용.
|
|
docs_target: /Users/wemadeplay/workspace/stz/bibimbap/docs/development/verification-strategies.md (신규 섹션 "컨트롤러 추가 시 검증 의무")
|
|
|
|
applied_changes: []
|