Merge branch 'main' into feature/survey-unique-parity

This commit is contained in:
2026-07-26 04:18:00 +00:00
20 changed files with 1973 additions and 608 deletions
@@ -8,12 +8,21 @@
- 범위: 명령 결과, RNG 소비, 로그, 예약 턴 lifecycle, DB 영속화
현재 ref MariaDB와 core memory를 잇는 공통 runner, 성공 경로 55개,
실행 중 확률 실패 9개 full constraint fallback 7개가 구현됐다.
실행 중 확률 실패 9개, full constraint fallback 12개와 모략 확률 clamp
8개, 모략 결과값 경계 5개, 부상 경계 3개가 구현됐다.
실패 9개는 내정 critical
`주민선정/정착장려/상업투자/기술연구/물자조달`과 모략
`화계/선동/파괴/탈취`이며 RNG 전체 trace, semantic state delta와 실패
로그 본문을 비교한다. 제약 7개는 무소속, 방랑국, 타국 도시, 보급 단절,
금·쌀 부족과 민심 상한을 대표하며 휴식 fallback과 RNG/state delta를
로그 본문을 비교한다. 공통 제약 7개는 무소속, 방랑국, 타국 도시, 보급
단절, 금·쌀 부족과 민심 상한을 대표한다. 모략 제약 5개는 동일 도시,
중립 도시, 불가침국, 계략 비용 금·쌀 부족을 고정한다. 모두 휴식
fallback과 RNG/state delta를 비교한다. clamp 8개는
`화계/선동/파괴/탈취` 각각의 계산 확률 0과
0.5 경계에서 성공 판정 RNG의 무소비 또는 `nextBits(1)` 소비와 전체
state delta를 비교한다. 결과값 5개는 화계 농업·상업, 선동 치안·민심,
파괴 수비·성벽의 0 바닥과 탈취의 대상 국가 자원 상한·미보급 도시 최종
저장 상태를 비교한다. 부상 3개는 화계·선동·파괴의 대상 장수별 판정,
부상도 80 상한, 병력·훈련·사기 0.98 정수 저장과 대상 장수 로그를
비교한다. 나머지 명령별 제약 실패·값 경계·alternative와 전체 core
PostgreSQL 재조회가 완료 기준을 통과하기 전까지 55개 명령 전체의 동적
호환 상태를 `확인`으로 올리지 않는다.
@@ -578,9 +587,23 @@ fixture가 명시한 필드만 비교하면 예상하지 못한 side effect를
| `damage-clamp` | 낮은 농업·상업에서 0 미만 방지 |
| `constraint-denied` | 중립/같은 도시/자원/보급/불가침 제약과 queue fallback |
`success-basic`은 현재의 `City.meta.state``City.state` 혼동을 반드시
실패로 검출해야 한다. fixture가 해당 production line을 고의로 잘못
바꿨을 때 실패하고 복구하면 통과하는 것을 mutation audit에 기록한다.
`success-basic`과 확률 상한 fixture는 `City.meta.state``City.state`
혼동을 검출한다. 상한 fixture에서 실제로 이 결함을 발견해 화계 성공 시
물리 `City.state=32`를 저장하도록 수정했다. 같은 fixture 묶음에서 선동의
전체 city spread가 불필요한 front 재계산을 일으키는 문제와 MariaDB
`city.trust FLOAT` 재조회 정밀도 차이도 발견해 부분 patch와 6자리
유효숫자 저장 경계로 바로잡았다.
결과값 경계 fixture에서는 파괴의 전체 city spread도 선동과 같이
불필요한 front 재계산을 일으키는 문제를 발견해 수비·성벽·state 부분
patch로 좁혔다. 미보급 탈취는 레거시가 자원 감소 update 뒤 원본
`destCity.agri/comm`을 다시 저장하므로 관찰 가능한 최종 자원은 변하지
않는다. 버그로 보이지만 호환 계약으로 보존하고 `state=32`만 남긴다.
부상 경계 fixture에서는 화계의 `계략로 인해` 조사를 레거시
`계략으로 인해`로 수정하고, 선동·파괴에 누락된 대상 장수 부상 로그를
추가했다. 병력·훈련·사기의 0.98 감소는 ref 정수 DB 저장처럼 내림이 아닌
반올림을 적용한다.
## 55개 명령 coverage manifest
@@ -179,10 +179,27 @@ responses pass a separate reference trace and core resolver/API boundary.
Nine general in-action failure cases now also pass the common differential:
five domestic critical failures and four sabotage failures. They compare the
full command RNG trace, semantic state delta and the exact action-log body.
Seven full-constraint cases cover neutral status, wandering nation, city
ownership, supply, gold, rice and trust-cap rejection. Both engines replace
the denied command with rest, consume the same RNG and produce the same
semantic delta. This is not yet a claim that every command-specific
Seven common full-constraint cases cover neutral status, wandering nation,
city ownership, supply, gold, rice and trust-cap rejection. Five sabotage
constraint cases add the occupied-city target, neutral target, non-aggression
status and insufficient sabotage gold or rice. Both engines replace the denied
command with rest, consume the same RNG and produce the same semantic delta.
Eight sabotage clamp cases cover probability zero and 0.5 for
fire attack, agitation, destruction and seizure. The zero boundary skips the
success RNG primitive, while exactly 0.5 consumes `nextBits(1)`; the complete
RNG trace and semantic delta match. These cases also fixed fire-attack city
state persistence and agitation front/trust persistence differences.
Five sabotage value-boundary cases cover zero floors for fire-attack,
agitation and destruction city values, the supplied-nation resource cap for
seizure, and the legacy final state of unsupplied seizure. They also remove
destruction's unintended front recalculation and preserve the legacy
unsupplied-seizure overwrite that leaves city resources unchanged.
Three sabotage injury-boundary cases cover per-defender rolls, the injury cap
of 80, integer persistence after multiplying crew/train/atmosphere by 0.98,
and the target-general injury log for fire attack, agitation and destruction.
They restore the legacy Korean particle in the log, add the two missing logs,
and round rather than floor the integer fields.
This is not yet a claim that every command-specific
constraint, clamp, alternative and persistence boundary has been dynamically
compared.