Files
core2026/AGENTS.md
T

359 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# core2026 작업 지침
## 적용 범위와 목표
이 파일은 `core2026/` 전체에 적용됩니다. 하위 디렉터리에 더 가까운
`AGENTS.md`가 생기면 사용자 지시, 가까운 파일, 이 파일, 상위 작업공간
지침 순으로 적용합니다.
목표는 `../ref/sam`의 PHP 서비스를 TypeScript 런타임으로 호환 이관하는
것입니다. 내부 구조를 더 깔끔하게 만드는 일보다 기존 결과, 상태 전이, 권한,
화면과 운영 경계를 보존하는 일이 우선입니다.
## 현재 기준과 저장소 경계
- `core2026/`은 제품 구현 저장소입니다. gateway/game frontend·API, game engine,
공통 package, Prisma와 검증 도구가 실제로 존재합니다.
- PHP 기준 구현은 이 저장소 내부 `legacy/`가 아니라 `../ref/sam`입니다.
`devel`은 변경하지 않는 기준선이고 비교 fixture·계측은 `ng_compare`에만
두어 주세요.
- 아키텍처 매핑과 보고서는 별도 상위 저장소의
`../docs/ref-core2026-mapping.md`, `../report/`에 있습니다. 두 Git 경계의
commit과 상태를 혼동하지 말아 주세요.
- 이미지의 운영 소유자는 외부 Caddy의 `/image/*`입니다. 제품 저장소에 무단
복제하거나 앱 경로로 rewrite하지 말아 주세요.
작업 시작과 종료에 최소한 다음을 확인해 주세요.
```sh
git status --short --branch
git remote -v
git rev-parse HEAD
```
상위 매핑/보고서를 바꾸면 상위 저장소에서도 같은 검사를 별도로 수행해 주세요.
dirty 파일은 사용자의 변경일 수 있으므로 관련 없는 수정, 정리, stage,
commit 또는 삭제를 하지 말아 주세요.
## 완료 상태를 해석하는 법
2026-07-27의 백엔드 누락 감사에서는 현재 `main`에서 재현 가능한 구체적
미구현·미병합 항목을 찾지 못했습니다. 이를 “이관 전체 완료”로 해석하지 말아 주세요.
- 새 차등 fixture가 mismatch를 드러내면 다시 제품 결함으로 분류해 주세요.
- green unit test는 ref 호환, 실제 DB transaction, Chromium geometry 또는
운영 장애 복구를 자동으로 증명하지 않습니다.
- 환경 변수가 없는 기본 test에서 skip된 integration은 실행된 검증이 아닙니다.
- local/mock prefix E2E와 실제 외부 Caddy·host/firewall 검증은 별도입니다.
- report 제목의 `완료`보다 현재 코드, Git ancestry, 실행 경로와 재현 결과를
우선합니다.
기능 작업 전에 관련 매핑 항목과 최신 report를 읽고, 오래된 결론은 현재
코드와 commit으로 다시 확인해 주세요.
## 실제 구조와 책임
- `app/gateway-frontend`: 가입·로그인, 로비, 계정, 관리자 운영 UI
- `app/gateway-api`: 계정·세션·profile 정책, operation queue와 PM2
orchestration
- `app/game-frontend`: profile별 게임 SPA와 ref 호환 UI
- `app/game-api`: tRPC/SSE, 조회·입력 API와 battle/auction/tournament worker
- `app/game-engine`: turn daemon, scheduler, 월간 lifecycle와 DB flush
- `packages/common`: 타입, 직렬화, RNG와 공통 유틸리티
- `packages/logic`: 전투·명령·월간 action 등 도메인 로직
- `packages/infra`: gateway/game Prisma schema, migration과 client
- `tools/integration-tests`: PostgreSQL/Redis 및 ref↔core 차등
- `tools/frontend-legacy-parity`: 실제 Chromium 비교
- `tools/legacy-db-migration`: 장기보존 데이터 CLI 이관
`tools/build-scripts/build-server.mjs`는 현재 profile resource 복사
placeholder입니다. 이를 완성된 배포 bundle이나 검증된 profile build로 설명하지
않습니다. 운영 build/reset/open은 gateway operation, commit별 worktree와
orchestrator 실행 경로를 조사해 주세요.
## 레거시 매핑과 비교
기능을 변경하기 전에 다음을 end-to-end로 연결해 주세요.
1. ref entry point와 호출 순서
2. PHP domain class, SQL read/write, template/CSS/JS와 사용자 출력
3. core service/router/action/loader/flush와 frontend 호출부
4. session/auth, validation, transaction, 비동기 경계와 오류 복구
5. RNG 생성·소비와 persistence 순서
`../docs/ref-core2026-mapping.md`에는 1:1 대응을 억지로 만들지 말고 1:N/N:1
소유권과 변환 지점을 기록해 주세요. `확인`, `부분 확인`, `가설`, `미구현`,
`의도적 차이`를 근거와 함께 사용해 주세요. 문서와 코드가 다르면 먼저 양쪽 기준
commit과 실제 실행을 확인하고 사실관계를 고쳐 주세요.
ref 계측이 필요하면 다음을 지켜 주세요.
- `devel`에 test, endpoint, fixture나 debug 코드를 commit하지 말아 주세요.
- 기존 `ng_compare` 이력과 분기 기준을 조사하고 reset/overwrite하지 말아 주세요.
- 계측은 최소·deterministic·가능하면 read-only로 두고 test 환경 guard를
사용해 주세요.
- 계측 유무가 결과, RNG 소비, DB mutation과 출력 순서를 바꾸지 않는지
확인해 주세요.
- ref와 core 변경은 서로 다른 저장소와 commit으로 관리해 주세요.
## 호환성 우선순위
1. 전투 결과, 계산식, 판정·반올림·정렬과 RNG 소비 순서
2. 턴/명령 조건, 자원 변화, DB 상태 전이와 권한
3. API 요청·응답·오류, session과 인증
4. 문구, 로그, 화면 흐름과 룩앤필
5. 내부 구현 세부사항
레거시의 이상해 보이는 동작도 계약일 수 있습니다. 보안 또는 데이터 손상 위험이
아니면 우선 같은 동작을 재현하고 개선 제안은 분리해 주세요. 허용하는 차이는
사용자 경험, 저장 상태와 후속 턴 결과에 영향이 없다는 근거를 mapping/report에
남겨 주세요.
## 인증과 권한
- actor, general과 archive owner는 인증 session/token에서 서버가 결정합니다.
client가 보낸 user ID, general ID, owner, role을 권한 근거로 신뢰하지 말아 주세요.
- game token의 profile, role, sanction과 장수 생성 정책을 world mutation보다
먼저 확인해 주세요.
- 새 browser flow는 `x-session-token` 또는 현재 session transport를 사용하고
token을 query string이나 로그에 노출하지 말아 주세요.
- 실패한 logout에서 client token을 먼저 버려 서버 revoke 실패를 숨기지 말아 주세요.
- 비밀번호 원문·OAuth credential·global salt·private key·session token을
Git, CLI argument, build log, report 또는 screenshot에 넣지 말아 주세요.
- `VITE_*`는 공개값입니다. 비밀값은 Git 제외 파일이나 `/run/secrets/...`
사용해 주세요.
API를 변경하면 성공뿐 아니라 무인증, 다른 사용자, sanction/role, 잘못된
입력과 경계값을 검사해 주세요. 권한 테스트는 router mock만으로 끝내지 않고 위험도에
따라 실제 HTTP transport까지 확인해 주세요.
## 턴, transaction과 RNG
현재 gameplay mutation의 내구성 기준은 PostgreSQL `input_event`입니다.
```text
API request
-> input_event accept/idempotency
-> daemon claim + lease/fencing 확인
-> in-memory action/turn/monthly handlers
-> world/log/queue/result flush
-> input_event 완료를 같은 transaction으로 commit
-> realtime 알림
```
- Redis pub/sub은 best-effort fan-out이며 mutation commit의 source of truth가
아닙니다.
- daemon lease/fencing을 우회하거나 이전 owner의 stale transaction을
commit 가능하게 만들지 말아 주세요.
- 예약 queue의 revision/CAS, repeat/bulk 직렬화와 API/daemon race를 보존해 주세요.
- 새 persistence field는 Prisma schema, 새 migration, domain/model type,
loader, in-memory dirty state, transaction flush와 reload test까지 연결해 주세요.
- 기존 migration 파일이나 checksum을 수정하지 말아 주세요.
- 전투·명령·월간 action의 호출, state patch, 로그와 RNG 소비 순서를
리팩터링 편의로 바꾸지 말아 주세요.
게임 난수는 기존 `packages/common/src/util/LiteHashDRBG.ts`, `RNG.ts`,
`RandUtil.ts` 흐름을 사용해 주세요. `Math.random()` 같은 임의 경로를 gameplay에
추가하지 말아 주세요. 후보가 하나뿐인 선택, 실패 분기, fallback에서도 ref가
소비하는 RNG call을 생략하지 말아 주세요.
전투/RNG 변경에는 fixed seed 결과뿐 아니라 RNG trace, 로그, 전체 state
side effect와 실패 경로의 ref 비교가 필요합니다. comparator ignore를 늘리기
전에 canonical snapshot에서 누락된 field가 없는지 확인해 주세요.
## 프론트엔드와 룩앤필
새 디자인 시스템이나 현대적 재해석을 임의로 도입하지 말아 주세요. 보존 범위는
layout, font, line-height, 줄바꿈, 색상, texture, border, shadow, opacity,
이미지 natural size/aspect ratio/object-fit과 표시 순서입니다.
- gateway `/gateway/`, game `/che/``/hwe/` prefix에서 direct navigation,
refresh, tRPC, SSE와 asset URL을 확인해 주세요.
- `kwe`, `twe`, `nya`, `pya`, `pwe`가 코드에 있어도 외부 route가 활성화된
것으로 가정하지 말아 주세요.
- `/image/*`를 frontend build artifact로 가져오거나 root 배포 URL로
하드코딩하지 말아 주세요.
- 공통화는 동일한 렌더링 계약이 확인된 token/shell에 한합니다. `.error`,
`.stack`처럼 이름만 같은 page selector를 전역화하지 말아 주세요.
- `v-html`은 입력 source와 sanitization/allowlist를 확인해 주세요. 기존 warning을
일괄 disable하지 말아 주세요.
UI를 변경하면 실제 Chromium을 사용해 주세요.
- ref와 core에 같은 Chromium, viewport, device scale, zoom, locale, font,
image와 로그인/test data를 사용해 주세요.
- 전체·영역 screenshot과 `getBoundingClientRect()`,
`getComputedStyle()`을 수집해 주세요.
- `hover()`, focus, pointer down/up, checked/selected/disabled, dropdown,
modal과 transition 상태를 실제 interaction으로 만들어 주세요.
- pixel diff mask는 시간·난수 등 불가피한 영역만 최소화하고 이유를 기록해 주세요.
- auth redirect만 확인하고 visual parity라고 주장하지 말아 주세요.
- 민감정보가 보이는 artifact는 저장하거나 report에 넣지 말아 주세요.
CSS layer와 selector 경계는 `docs/frontend-css-architecture.md`, 비교 실행은
`docs/frontend-legacy-parity.md`를 따라 주세요.
## DB와 레거시 데이터 이관
Gateway는 기본 `public`, game은 profile별 PostgreSQL schema를 사용합니다.
schema 변경 후 최소한 다음을 위험도에 맞게 확인해 주세요.
- 빈 DB migration 전체 적용
- 두 번째 deploy가 no-op인지
- 기존 설치에서 증분 적용되는지
- unique/FK/index와 runtime query 일치
- rollback 또는 backup/restore 경로
`prisma db push`는 격리된 fixture에서 scoped schema 확인용으로만 사용하고
정식 migration chain을 대신하지 말아 주세요.
레거시 DB 이관은 `tools/legacy-db-migration` CLI만 사용해 주세요.
- dry-run이 기본이며 실제 쓰기는 명시적 `--apply`가 필요합니다.
- DB URL과 secret은 환경/secret file로 전달해 주세요.
- PostgreSQL advisory lock, stable legacy key와 idempotent upsert를 보존해 주세요.
- 현 시즌 `general/city/nation`, queue, message, market, log와 seasonal
storage를 장기보존 이관에 섞지 말아 주세요.
- 운영 apply 전 backup, maintenance mode, source/target count와 rollback
절차를 다시 확인해 주세요.
- dump에 우연히 있는 table이 아니라 ref schema와 사용자 범위를 기준으로
삼아 주세요.
## 환경과 배포
`.env` 또는 secret key를 추가하기 전에 `.gitignore``.env.example`
함께 갱신해 주세요. example은 모든 필수 key와 명백한 placeholder를 포함하되 실제
비밀을 담지 말아 주세요.
전체 작업공간의 개발 PostgreSQL/Redis는
`../docker_compose_files/development/`에서 worktree별로 격리할 수 있습니다.
통합 fixture는 schema truncate와 Redis 초기화를 수행할 수 있으므로 병렬
worktree가 같은 instance를 공유하지 않도록 해 주세요. volume 삭제 명령은 사용자가
명시적으로 데이터 폐기를 요청하지 않으면 실행하지 말아 주세요.
현재 외부 호스트 계약은 `0.0.0.0` bind와 `/gateway/`, `/che/`, `/hwe/`
prefix입니다. Caddy는 외부 인프라로 취급하고 요청 없이 설정 변경을 전제하지
않습니다. local preview/mock 성공을 외부 HTTPS 성공으로 보고하지 말아 주세요.
Gateway preview를 검증할 때 최소 계약은 다음과 같습니다.
```sh
VITE_APP_BASE_PATH=/gateway \
VITE_GATEWAY_API_URL=/gateway/api/trpc \
VITE_GAME_API_URL_TEMPLATE='/{profile}/api/trpc' \
VITE_GAME_WEB_URL_TEMPLATE='/{profile}/' \
pnpm --filter @sammo-ts/gateway-frontend build
```
profile별 정확한 포트와 game frontend/API 변수는
`docs/e2e-caddy-routing.md`에서 확인하고 현재 인프라와 대조해 주세요.
## 개발과 검증 절차
1. 현재 branch/status/remote, 사용자 변경과 가까운 지침을 확인해 주세요.
2. 관련 mapping/report와 ref/core 호출 경로를 조사해 주세요.
3. 보존할 계약, 허용할 차이와 검증 범위를 먼저 정합니다.
4. 코드와 함께 type/schema/migration/fixture/mapping을 갱신해 주세요.
5. 좁은 단위 test → typecheck/lint/build → DB integration → ref 차등 →
Chromium E2E 순으로 위험에 맞게 넓혀 주세요.
6. 명령, 결과, skip/미검증과 baseline failure를 분리해 report에 기록해 주세요.
7. 양쪽 Git diff/status와 필요한 ancestry를 다시 확인해 주세요.
기본 정적 검사는 실제 루트 script를 사용해 주세요.
```sh
CI=1 pnpm typecheck
pnpm lint
pnpm test
pnpm build
```
- 모든 코드 변경 후 `CI=1 pnpm typecheck`를 실행해 주세요.
- `pnpm test`의 skip 수를 pass처럼 보고하지 말아 주세요.
- Vitest file/name filter는 package script 뒤에 불필요한 `--`를 넣지 말아 주세요.
예: `pnpm --filter @sammo-ts/game-engine test monthlyCoreEventHandler.test.ts`
- frontend package의 `test` placeholder를 실제 UI 검증으로 오해하지 말아 주세요.
해당 Playwright script 또는 legacy parity suite를 사용해 주세요.
- 전체 lint/test의 기존 실패가 있으면 targeted 결과와 baseline 재현 결과를
구분하고, 관련 없는 기대값을 완화해 숨기지 말아 주세요.
외부 서비스 없는 기본 integration:
```sh
pnpm test:integration
```
전용 PostgreSQL/Redis를 준비한 조건부 전체 경계:
```sh
pnpm test:integration:conditional
```
ref 명령과 UI entry point:
```sh
pnpm check:legacy:general
pnpm check:legacy:nation
pnpm test:e2e:frontend-legacy
```
각 command가 요구하는 ref checkout, Docker, DB URL, secret과 fixture는 관련
docs에서 확인해 주세요. 존재하지 않는 명령을 오래된 report나 제안 문서만 보고
실행하지 말아 주세요.
## 코드 스타일
- TypeScript는 workspace 전체에서 정확히 `6.0.2`를 사용해 주세요. package-local
다른 버전을 추가하지 말아 주세요.
- TypeScript/JSON/Vue SFC는 기존 4-space 스타일을 유지해 주세요.
- public API는 명시적 타입을 사용하고 `any`, 불필요하게 넓은 `unknown`,
`as unknown as` 우회를 피해 주세요.
- Vue component는 PascalCase, composable은 `useX`, 변수/함수는 camelCase,
type/class는 PascalCase를 사용해 주세요.
- 한국어 domain identifier와 설명은 의미가 더 명확할 때 유지해 주세요.
- action/command/전투 코드에는 한국 독자가 side effect와 ref 근거를 이해할
수 있는 주석을 남기되 코드의 반복 설명은 피해 주세요.
- 기능 이관과 무관한 대규모 formatting/refactor를 같은 변경에 섞지 말아 주세요.
## 문서와 보고서
기능·운영·호환성에 의미 있는 변경은 코드와 같은 작업에서 다음을 갱신해 주세요.
- `README.md`: 사용자가 알아야 할 현재 구조, 시작점과 운영 경계
-`AGENTS.md`: 반복 작업 규칙과 검증 계약
- `docs/*`: core2026 내부 구현·운영 상세
- `../docs/ref-core2026-mapping.md`: ref↔core 근거와 상태
- `../report/YYYY-MM-DD-간결한-작업명.md`: 재현 가능한 인수인계
보고서에는 목적/범위, 조사한 ref, 변경 파일, 보존 계약, 명령과 결과,
skip/미검증, 알려진 차이, 후속 작업과 저장소별 commit을 포함합니다. commit
전이면 `커밋 전`으로 기록하고 서로 다른 저장소의 hash를 명확히 구분해 주세요.
## Git, worktree와 commit
- 중·장기 작업은 전용 branch/worktree와 고유 DB/Redis instance에서 합니다.
- 최신 `main`을 통합하고 회귀를 확인한 뒤 요청된 범위에 따라 local `main`
병합해 주세요. 원격 push는 별도 요청 없이는 하지 말아 주세요.
- 관련 없는 사용자 변경을 stage/commit/revert하지 말아 주세요.
- ref 비교 변경과 core 제품 변경, 상위 mapping/report 변경은 각 Git
저장소에서 별도 commit해 주세요.
- 생성물, `.env`, DB volume, log, coverage, screenshot, test-results와
secret을 commit하지 말아 주세요.
- worktree 정리는 clean status와
`git merge-base --is-ancestor HEAD <baseline>`을 모두 확인한 뒤 non-force
제거해 주세요. 이름, 나이 또는 uncommitted 여부만으로 삭제하지 말아 주세요.
- 사용자가 commit을 요청하지 않은 일반 작업은 diff와 권장 commit 경계를
준비하되 임의로 commit하지 말아 주세요.
## Qwen 보조 분석
Qwen은 대규모 파일 목록, diff·로그 분류, 반복 추출과 누락 후보 재검색에만
사용해 주세요. 필요한 최소 발췌만 전달하고 secret, 개인정보와 환경 파일 값을
보내지 말아 주세요.
- 아키텍처·보안·DB mutation·전투/RNG 판단과 최종 검증을 위임하지 말아 주세요.
- 결과는 파일, Git, test 또는 실제 trace로 독립 검증해 주세요.
- 응답 budget은 1284096 token 범위로 제한해 주세요.
- 실패하면 health 확인 후 일시 오류일 때 한 번만 재시도하고, 선택적 작업이면
로컬 분석을 계속해 주세요.