시간 도메인과 정지 중 메시지·베팅 경계 정리

This commit is contained in:
2026-09-03 16:01:19 +00:00
parent 10cddbb565
commit abceee8315
108 changed files with 3504 additions and 1473 deletions
@@ -310,7 +310,7 @@ export const resolveOwnerDisplayName = (rawMeta: unknown): string => {
return '알수없음';
};
export const executeInheritanceAction = async (options: {
const executeInheritanceActionMutation = async (options: {
db: GamePrisma.TransactionClient;
world: InMemoryTurnWorld;
command: InheritanceActionCommand;
@@ -668,3 +668,59 @@ export const executeInheritanceAction = async (options: {
});
return { type: 'inheritanceAction', ok: true, action, generalId: general.id, remainPoint: previousPoint - cost };
};
/**
* Persists the WALL_TIME inheritance receipt in the same transaction as the
* point debit, game mutation, and input-event completion. The input_event row
* is the durable retry/failure record and owns the authoritative GAME clock
* coordinate; an immediate effect does not invent a separate applied tick.
*/
export const executeInheritanceAction = async (options: {
db: GamePrisma.TransactionClient;
world: InMemoryTurnWorld;
command: InheritanceActionCommand;
gameNow: Date;
}): Promise<InheritanceActionResult> => {
const result = await executeInheritanceActionMutation(options);
if (!result.ok || !options.command.requestId) return result;
const event = await options.db.inputEvent.findUnique({
where: { requestId: options.command.requestId },
select: {
actorUserId: true,
target: true,
eventType: true,
createdAt: true,
processingClockRevision: true,
processingDeadlineGeneration: true,
},
});
if (
!event ||
event.actorUserId !== options.command.userId ||
event.target !== 'ENGINE' ||
event.eventType !== 'inheritanceAction' ||
event.processingClockRevision === null ||
event.processingDeadlineGeneration === null
) {
throw new Error('Inheritance ledger requires the authoritative ENGINE input-event clock fence.');
}
const previousPoint = await lockPreviousPoint(options.db, options.command.userId);
const cost = previousPoint - result.remainPoint;
if (!Number.isFinite(cost) || cost < 0) {
throw new Error(`Inheritance ledger calculated an invalid cost: ${cost}.`);
}
await options.db.inheritanceLedger.create({
data: {
requestId: options.command.requestId,
userId: options.command.userId,
action: result.action,
cost,
status: 'APPLIED',
requestedAtWall: event.createdAt,
appliedClockRevision: event.processingClockRevision,
appliedDeadlineGeneration: event.processingDeadlineGeneration,
},
});
return result;
};