Add general constraint fallback parity
This commit is contained in:
@@ -8,12 +8,15 @@
|
|||||||
- 범위: 명령 결과, RNG 소비, 로그, 예약 턴 lifecycle, DB 영속화
|
- 범위: 명령 결과, RNG 소비, 로그, 예약 턴 lifecycle, DB 영속화
|
||||||
|
|
||||||
현재 ref MariaDB와 core memory를 잇는 공통 runner, 성공 경로 55개,
|
현재 ref MariaDB와 core memory를 잇는 공통 runner, 성공 경로 55개,
|
||||||
실행 중 확률 실패 9개가 구현됐다. 실패 9개는 내정 critical
|
실행 중 확률 실패 9개와 full constraint fallback 7개가 구현됐다.
|
||||||
|
실패 9개는 내정 critical
|
||||||
`주민선정/정착장려/상업투자/기술연구/물자조달`과 모략
|
`주민선정/정착장려/상업투자/기술연구/물자조달`과 모략
|
||||||
`화계/선동/파괴/탈취`이며 RNG 전체 trace, semantic state delta와 실패
|
`화계/선동/파괴/탈취`이며 RNG 전체 trace, semantic state delta와 실패
|
||||||
로그 본문을 비교한다. 나머지 제약 실패·값 경계·alternative와 전체
|
로그 본문을 비교한다. 제약 7개는 무소속, 방랑국, 타국 도시, 보급 단절,
|
||||||
core PostgreSQL 재조회가 완료 기준을 통과하기 전까지 55개 명령 전체의
|
금·쌀 부족과 민심 상한을 대표하며 휴식 fallback과 RNG/state delta를
|
||||||
동적 호환 상태를 `확인`으로 올리지 않는다.
|
비교한다. 나머지 명령별 제약 실패·값 경계·alternative와 전체 core
|
||||||
|
PostgreSQL 재조회가 완료 기준을 통과하기 전까지 55개 명령 전체의 동적
|
||||||
|
호환 상태를 `확인`으로 올리지 않는다.
|
||||||
|
|
||||||
## 결정 요약
|
## 결정 요약
|
||||||
|
|
||||||
|
|||||||
@@ -179,8 +179,12 @@ responses pass a separate reference trace and core resolver/API boundary.
|
|||||||
Nine general in-action failure cases now also pass the common differential:
|
Nine general in-action failure cases now also pass the common differential:
|
||||||
five domestic critical failures and four sabotage failures. They compare the
|
five domestic critical failures and four sabotage failures. They compare the
|
||||||
full command RNG trace, semantic state delta and the exact action-log body.
|
full command RNG trace, semantic state delta and the exact action-log body.
|
||||||
This is not yet a claim that the remaining constraint, clamp, alternative and
|
Seven full-constraint cases cover neutral status, wandering nation, city
|
||||||
persistence boundaries have been dynamically compared.
|
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
|
||||||
|
constraint, clamp, alternative and persistence boundary has been dynamically
|
||||||
|
compared.
|
||||||
|
|
||||||
The fixture runner also reports whether the requested legacy command reached
|
The fixture runner also reports whether the requested legacy command reached
|
||||||
its completed execution path. For multi-turn commands this is derived from the
|
its completed execution path. For multi-turn commands this is derived from the
|
||||||
|
|||||||
@@ -484,3 +484,81 @@ integration('general command in-action failure matrix', () => {
|
|||||||
120_000
|
120_000
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
type GeneralConstraintCase = {
|
||||||
|
name: string;
|
||||||
|
action: string;
|
||||||
|
args?: Record<string, unknown>;
|
||||||
|
actorPatch?: Record<string, unknown>;
|
||||||
|
fixturePatches?: FixturePatches;
|
||||||
|
};
|
||||||
|
|
||||||
|
const constraintCases: GeneralConstraintCase[] = [
|
||||||
|
{
|
||||||
|
name: 'neutral general',
|
||||||
|
action: 'che_훈련',
|
||||||
|
actorPatch: { nationId: 0, officerLevel: 0 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'wandering nation',
|
||||||
|
action: 'che_농지개간',
|
||||||
|
fixturePatches: {
|
||||||
|
nations: { 1: { level: 0, capitalCityId: 0, typeCode: 'None' } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'city not occupied by actor nation',
|
||||||
|
action: 'che_농지개간',
|
||||||
|
fixturePatches: { cities: { 3: { nationId: 2 } } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'unsupplied city',
|
||||||
|
action: 'che_농지개간',
|
||||||
|
fixturePatches: { cities: { 3: { supplyState: 0 } } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'insufficient gold',
|
||||||
|
action: 'che_상업투자',
|
||||||
|
actorPatch: { gold: 0 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'insufficient rice',
|
||||||
|
action: 'che_주민선정',
|
||||||
|
actorPatch: { rice: 0 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'maximum city trust',
|
||||||
|
action: 'che_주민선정',
|
||||||
|
fixturePatches: { cities: { 3: { trust: 100 } } },
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
integration('general command full-constraint fallback matrix', () => {
|
||||||
|
it.each(constraintCases)(
|
||||||
|
'$name: $action falls back exactly like legacy',
|
||||||
|
async ({ action, args, actorPatch, fixturePatches }) => {
|
||||||
|
const request = buildRequest(action, args, actorPatch, fixturePatches);
|
||||||
|
request.setup!.world!.hiddenSeed = `general-constraint-${action}`;
|
||||||
|
const reference = runReferenceTurnCommandTraceRequest(
|
||||||
|
workspaceRoot!,
|
||||||
|
request as unknown as Record<string, unknown>
|
||||||
|
);
|
||||||
|
const core = await runCoreTurnCommandTrace(request, reference.before);
|
||||||
|
|
||||||
|
expect(reference.execution.outcome).toMatchObject({ completed: false });
|
||||||
|
expect(core.execution.outcome).toMatchObject({
|
||||||
|
requestedAction: action,
|
||||||
|
actionKey: '휴식',
|
||||||
|
usedFallback: true,
|
||||||
|
});
|
||||||
|
expect(core.execution.outcome).toHaveProperty('blockedReason');
|
||||||
|
expect(core.rng).toEqual(reference.rng);
|
||||||
|
expect(
|
||||||
|
compareTurnSnapshotDeltas(reference.before, reference.after, core.before, core.after, {
|
||||||
|
ignoredPathPatterns: ignoredLifecyclePaths,
|
||||||
|
})
|
||||||
|
).toEqual([]);
|
||||||
|
},
|
||||||
|
120_000
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user