session types: boundary actions and captures in the step trace, a capture never precedes a slot save
Review round 1, B1 and N4. TraceBehaviour.boundaryActions records the slot saves and the rollback at the reached boundary in application order; TraceOperational.captures records each capture with the number of boundary actions before it; TransitionTrace refuses a capture taken before the boundary's slot saves. Both languages, fixtures for the rule, synthetic coordinator records both lists empty. contractDigest moves to a56e25e6.
This commit is contained in:
parent
24ba933500
commit
a6e1623698
9 changed files with 1344 additions and 49 deletions
|
|
@ -23,6 +23,25 @@ import {
|
|||
ownerToken,
|
||||
} from './scalar';
|
||||
import { MAX_AGENTS, MAX_RATE_ROLES } from './workers';
|
||||
import { MAX_SLOTS } from './extensions';
|
||||
|
||||
/** Boundary actions at the reached boundary (amendment of 2026-09-23, RT-01a). */
|
||||
export const BOUNDARY_ACTION_KINDS = ['save-slot', 'rollback'] as const;
|
||||
export type BoundaryActionKind = (typeof BOUNDARY_ACTION_KINDS)[number];
|
||||
/** Every slot at most once, plus one rollback. */
|
||||
export const MAX_BOUNDARY_ACTIONS = MAX_SLOTS + 1;
|
||||
|
||||
export interface BoundaryAction {
|
||||
kind: BoundaryActionKind;
|
||||
slotId: Id;
|
||||
stateDigest: Digest | null;
|
||||
}
|
||||
|
||||
/** A checkpoint capture at the reached boundary and how many boundary actions preceded it. */
|
||||
export interface TraceCapture {
|
||||
checkpointId: Id;
|
||||
afterActions: number;
|
||||
}
|
||||
|
||||
export interface TraceAgent {
|
||||
agentId: Id;
|
||||
|
|
@ -49,6 +68,7 @@ export interface TraceBehaviour {
|
|||
outcomeIds: Id[];
|
||||
eventIds: Id[];
|
||||
publishedBoundary: U64;
|
||||
boundaryActions: BoundaryAction[];
|
||||
}
|
||||
|
||||
export interface TraceRequest {
|
||||
|
|
@ -63,6 +83,7 @@ export interface TraceOperational {
|
|||
commitRequestIds: TraceRequest[];
|
||||
busCallIds: BusCallId[];
|
||||
deliveryIds: OwnerToken[];
|
||||
captures: TraceCapture[];
|
||||
}
|
||||
|
||||
export interface TransitionTrace {
|
||||
|
|
@ -107,7 +128,18 @@ export function readTraceBehaviour(value: unknown): TraceBehaviour {
|
|||
const outcomeIds = reader.idList('outcomeIds', 0, MAX_RATE_ROLES);
|
||||
const eventIds = reader.idList('eventIds', 0, MAX_RATE_ROLES);
|
||||
const publishedBoundary = reader.u64('publishedBoundary');
|
||||
const boundaryActions = reader.list('boundaryActions', 0, MAX_BOUNDARY_ACTIONS, (item) => {
|
||||
const action = new Reader(item, 'TraceBehaviour.boundaryActions');
|
||||
const entry: BoundaryAction = {
|
||||
kind: action.enumeration('kind', BOUNDARY_ACTION_KINDS),
|
||||
slotId: action.id('slotId'),
|
||||
stateDigest: action.value('stateDigest') === null ? null : action.digest('stateDigest'),
|
||||
};
|
||||
action.finish();
|
||||
return entry;
|
||||
});
|
||||
reader.finish();
|
||||
validateBoundaryActions(boundaryActions);
|
||||
|
||||
requireUnique(
|
||||
agents.map((agent) => agent.agentId),
|
||||
|
|
@ -141,9 +173,39 @@ export function readTraceBehaviour(value: unknown): TraceBehaviour {
|
|||
outcomeIds,
|
||||
eventIds,
|
||||
publishedBoundary,
|
||||
boundaryActions,
|
||||
};
|
||||
}
|
||||
|
||||
/** Slot saves first, each slot once with its digest; at most one rollback, last, no digest. */
|
||||
function validateBoundaryActions(actions: readonly BoundaryAction[]): void {
|
||||
let rolledBack = false;
|
||||
const saved: string[] = [];
|
||||
for (const action of actions) {
|
||||
if (rolledBack) fail('TraceBehaviour: nothing follows a rollback at the same boundary');
|
||||
if (action.kind === 'save-slot') {
|
||||
if (action.stateDigest === null) fail('TraceBehaviour: a slot save records its state digest');
|
||||
if (saved.includes(action.slotId)) {
|
||||
fail('TraceBehaviour: a slot is saved at most once per boundary');
|
||||
}
|
||||
saved.push(action.slotId);
|
||||
} else {
|
||||
if (action.stateDigest !== null) fail('TraceBehaviour: a rollback records no state digest');
|
||||
rolledBack = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** How many leading boundary actions are slot saves. */
|
||||
export function slotSaves(behaviour: TraceBehaviour): number {
|
||||
let count = 0;
|
||||
for (const action of behaviour.boundaryActions) {
|
||||
if (action.kind !== 'save-slot') break;
|
||||
count += 1;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
export function readTraceOperational(value: unknown): TraceOperational {
|
||||
const reader = new Reader(value, 'TraceOperational');
|
||||
const readRequests = (item: unknown): TraceRequest => {
|
||||
|
|
@ -162,6 +224,15 @@ export function readTraceOperational(value: unknown): TraceOperational {
|
|||
commitRequestIds: reader.list('commitRequestIds', 1, MAX_AGENTS, readRequests),
|
||||
busCallIds: reader.list('busCallIds', 0, 64, busCallId),
|
||||
deliveryIds: reader.list('deliveryIds', 0, 64, ownerToken),
|
||||
captures: reader.list('captures', 0, MAX_BOUNDARY_ACTIONS + 1, (item) => {
|
||||
const capture = new Reader(item, 'TraceOperational.captures');
|
||||
const entry: TraceCapture = {
|
||||
checkpointId: capture.id('checkpointId'),
|
||||
afterActions: capture.int('afterActions', 0, MAX_BOUNDARY_ACTIONS),
|
||||
};
|
||||
capture.finish();
|
||||
return entry;
|
||||
}),
|
||||
};
|
||||
reader.finish();
|
||||
requireUnique(
|
||||
|
|
@ -174,6 +245,17 @@ export function readTraceOperational(value: unknown): TraceOperational {
|
|||
);
|
||||
requireUnique(operational.busCallIds, 'TraceOperational.busCallIds');
|
||||
requireUnique(operational.deliveryIds, 'TraceOperational.deliveryIds');
|
||||
requireUnique(
|
||||
operational.captures.map((capture) => capture.checkpointId),
|
||||
'TraceOperational.captures',
|
||||
);
|
||||
let last = 0;
|
||||
for (const capture of operational.captures) {
|
||||
if (capture.afterActions < last) {
|
||||
fail('TraceOperational: captures are recorded in the order they were taken');
|
||||
}
|
||||
last = capture.afterActions;
|
||||
}
|
||||
return operational;
|
||||
}
|
||||
|
||||
|
|
@ -194,6 +276,20 @@ export function readTransitionTrace(value: unknown): TransitionTrace {
|
|||
}
|
||||
}
|
||||
}
|
||||
// A slot save due at a boundary completes before any capture there (legacy-gameboy-v1 16).
|
||||
const saves = slotSaves(trace.behaviour);
|
||||
for (const capture of trace.operational.captures) {
|
||||
if (capture.afterActions < saves) {
|
||||
fail(
|
||||
`TransitionTrace: capture "${capture.checkpointId}" was taken before this boundary's slot saves completed`,
|
||||
);
|
||||
}
|
||||
if (capture.afterActions > trace.behaviour.boundaryActions.length) {
|
||||
fail(
|
||||
`TransitionTrace: capture "${capture.checkpointId}" counts more boundary actions than were applied`,
|
||||
);
|
||||
}
|
||||
}
|
||||
return trace;
|
||||
}
|
||||
|
||||
|
|
@ -242,6 +338,7 @@ export function behaviourDiff(left: TransitionTrace, right: TransitionTrace): st
|
|||
}
|
||||
if (differs(a.outcomeIds, b.outcomeIds)) out.push('outcomeIds differ');
|
||||
if (differs(a.eventIds, b.eventIds)) out.push('eventIds differ');
|
||||
if (differs(a.boundaryActions, b.boundaryActions)) out.push('boundaryActions differ');
|
||||
const idsA = a.agents.map((agent) => agent.agentId);
|
||||
const idsB = b.agents.map((agent) => agent.agentId);
|
||||
if (differs(idsA, idsB)) {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"description": "contractDigest is the SHA-256 of the canonical schema set in schema-set.json.",
|
||||
"contractDigest": "f61e8f4fa9336184ebb6f0305f9d6135872707ef5536d51b9933df8943653c77",
|
||||
"contractDigest": "a56e25e6289a6f9e6720ba5f727651e9e4e2c5cf7a68990fc1f8d37fe12f2006",
|
||||
"schemaSetVersion": 1,
|
||||
"schemaSetBytes": 30184,
|
||||
"schemaSetBytes": 30711,
|
||||
"types": 60,
|
||||
"enums": 11,
|
||||
"enums": 12,
|
||||
"limits": 27
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4387,7 +4387,8 @@
|
|||
"observationBoundaries": [],
|
||||
"outcomeIds": [],
|
||||
"eventIds": [],
|
||||
"publishedBoundary": "42"
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": []
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1",
|
||||
|
|
@ -4405,7 +4406,8 @@
|
|||
}
|
||||
],
|
||||
"busCallIds": [],
|
||||
"deliveryIds": []
|
||||
"deliveryIds": [],
|
||||
"captures": []
|
||||
}
|
||||
},
|
||||
"reason": "a commit acknowledges the transition's next boundary"
|
||||
|
|
@ -5759,6 +5761,719 @@
|
|||
"flysimCompatibility": "lif-1ms-f64-v2/pokered-unique8-v6/75ba5d3536a2862fdb9f4ef1a76b96fe099a7201ac737f0cf53fe4c5ad4183f3:1657ba7716494c9db95a13b1527bc129226363f99b395774de1f76ff28571f0e:63b1acb26272edccdcfacf3c2ff58069e0cefaa84451429c989258bafaeae1d5:f567d7f07227e71c0df2ab4e6510f3a3f79e51b675095792e16d216d74b7b5b7:ece0b5e76d1884dd2f3ff6e0362bc284febe205ac1ce07fdab5009942ddffb62:b8c33144d4cec31c3ac4b6091ef1f4207f567c4f710f7c13fd2dc47c44c2b634:dbbafc044cd50aad7b792615988ff6d9991c846cc3d8b2eafc86b7c357b5eefc/fly-kc-mbon-rstdp-v2/binjgb:c60e138da5a795ebb55e56b11b7e90024e41112c/pokered:0cd19d3b877b7dc66d12c7050bed9a7f38154d4b/statefmt:199616-x86_64-unknown-linux-gnu"
|
||||
},
|
||||
"reason": "FLYSIM01 stays until RETIRE-01"
|
||||
},
|
||||
{
|
||||
"name": "a capture taken before the boundary's slot save",
|
||||
"type": "TransitionTrace",
|
||||
"value": {
|
||||
"behaviour": {
|
||||
"scope": {
|
||||
"sessionId": "demo",
|
||||
"epoch": "epoch-1",
|
||||
"step": "41"
|
||||
},
|
||||
"agents": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"profileDigest": "1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0",
|
||||
"ticksAdvanced": "17",
|
||||
"brainTicks": "2517",
|
||||
"remainder": {
|
||||
"numerator": "1000000",
|
||||
"denominator": "3"
|
||||
},
|
||||
"decisionDigest": "a62db30eb7427e2ea9ec58661e69a1eff38e67f21ec97df7d91b24015890d89b",
|
||||
"committedStep": "42"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"profileDigest": "1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0",
|
||||
"ticksAdvanced": "17",
|
||||
"brainTicks": "2550",
|
||||
"remainder": {
|
||||
"numerator": "0",
|
||||
"denominator": "1"
|
||||
},
|
||||
"decisionDigest": "ddc2e7b8b300cda681c3d91368050fcb95dd66d20fd295834c31307d3df2623e",
|
||||
"committedStep": "42"
|
||||
}
|
||||
],
|
||||
"batchId": "batch-41",
|
||||
"controlDigest": "1e2135d1b50f14d3d3d6cbe24a4294bcb9e4d5d3c28eb1ce4980ff2a17c5d3b6",
|
||||
"acknowledgedBoundary": "42",
|
||||
"observationBoundaries": [
|
||||
{
|
||||
"viewId": "screen",
|
||||
"producedStep": "42"
|
||||
}
|
||||
],
|
||||
"outcomeIds": [
|
||||
"outcome-1"
|
||||
],
|
||||
"eventIds": [
|
||||
"evt-1"
|
||||
],
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": [
|
||||
{
|
||||
"kind": "save-slot",
|
||||
"slotId": "best",
|
||||
"stateDigest": "5d41402abc4b2a76b9719d911017c592ae9d3a0c8a7a6f5d2e3d4c5b6a7f8e9d"
|
||||
}
|
||||
]
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
"prepareRequestIds": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"requestId": "req-41"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"requestId": "req-42"
|
||||
}
|
||||
],
|
||||
"advanceRequestId": "req-43",
|
||||
"commitRequestIds": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"requestId": "req-44"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"requestId": "req-45"
|
||||
}
|
||||
],
|
||||
"busCallIds": [
|
||||
"call-100",
|
||||
"call-101",
|
||||
"call-102"
|
||||
],
|
||||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
],
|
||||
"captures": [
|
||||
{
|
||||
"checkpointId": "milestone-11",
|
||||
"afterActions": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"reason": "a checkpoint must not pair the new ledger with the old slot (review round 1, B1)"
|
||||
},
|
||||
{
|
||||
"name": "a capture counting actions that were never applied",
|
||||
"type": "TransitionTrace",
|
||||
"value": {
|
||||
"behaviour": {
|
||||
"scope": {
|
||||
"sessionId": "demo",
|
||||
"epoch": "epoch-1",
|
||||
"step": "41"
|
||||
},
|
||||
"agents": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"profileDigest": "1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0",
|
||||
"ticksAdvanced": "17",
|
||||
"brainTicks": "2517",
|
||||
"remainder": {
|
||||
"numerator": "1000000",
|
||||
"denominator": "3"
|
||||
},
|
||||
"decisionDigest": "a62db30eb7427e2ea9ec58661e69a1eff38e67f21ec97df7d91b24015890d89b",
|
||||
"committedStep": "42"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"profileDigest": "1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0",
|
||||
"ticksAdvanced": "17",
|
||||
"brainTicks": "2550",
|
||||
"remainder": {
|
||||
"numerator": "0",
|
||||
"denominator": "1"
|
||||
},
|
||||
"decisionDigest": "ddc2e7b8b300cda681c3d91368050fcb95dd66d20fd295834c31307d3df2623e",
|
||||
"committedStep": "42"
|
||||
}
|
||||
],
|
||||
"batchId": "batch-41",
|
||||
"controlDigest": "1e2135d1b50f14d3d3d6cbe24a4294bcb9e4d5d3c28eb1ce4980ff2a17c5d3b6",
|
||||
"acknowledgedBoundary": "42",
|
||||
"observationBoundaries": [
|
||||
{
|
||||
"viewId": "screen",
|
||||
"producedStep": "42"
|
||||
}
|
||||
],
|
||||
"outcomeIds": [
|
||||
"outcome-1"
|
||||
],
|
||||
"eventIds": [
|
||||
"evt-1"
|
||||
],
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": [
|
||||
{
|
||||
"kind": "save-slot",
|
||||
"slotId": "best",
|
||||
"stateDigest": "5d41402abc4b2a76b9719d911017c592ae9d3a0c8a7a6f5d2e3d4c5b6a7f8e9d"
|
||||
}
|
||||
]
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
"prepareRequestIds": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"requestId": "req-41"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"requestId": "req-42"
|
||||
}
|
||||
],
|
||||
"advanceRequestId": "req-43",
|
||||
"commitRequestIds": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"requestId": "req-44"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"requestId": "req-45"
|
||||
}
|
||||
],
|
||||
"busCallIds": [
|
||||
"call-100",
|
||||
"call-101",
|
||||
"call-102"
|
||||
],
|
||||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
],
|
||||
"captures": [
|
||||
{
|
||||
"checkpointId": "milestone-11",
|
||||
"afterActions": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"reason": "afterActions <= the boundary's actions"
|
||||
},
|
||||
{
|
||||
"name": "a slot save after a rollback",
|
||||
"type": "TransitionTrace",
|
||||
"value": {
|
||||
"behaviour": {
|
||||
"scope": {
|
||||
"sessionId": "demo",
|
||||
"epoch": "epoch-1",
|
||||
"step": "41"
|
||||
},
|
||||
"agents": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"profileDigest": "1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0",
|
||||
"ticksAdvanced": "17",
|
||||
"brainTicks": "2517",
|
||||
"remainder": {
|
||||
"numerator": "1000000",
|
||||
"denominator": "3"
|
||||
},
|
||||
"decisionDigest": "a62db30eb7427e2ea9ec58661e69a1eff38e67f21ec97df7d91b24015890d89b",
|
||||
"committedStep": "42"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"profileDigest": "1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0",
|
||||
"ticksAdvanced": "17",
|
||||
"brainTicks": "2550",
|
||||
"remainder": {
|
||||
"numerator": "0",
|
||||
"denominator": "1"
|
||||
},
|
||||
"decisionDigest": "ddc2e7b8b300cda681c3d91368050fcb95dd66d20fd295834c31307d3df2623e",
|
||||
"committedStep": "42"
|
||||
}
|
||||
],
|
||||
"batchId": "batch-41",
|
||||
"controlDigest": "1e2135d1b50f14d3d3d6cbe24a4294bcb9e4d5d3c28eb1ce4980ff2a17c5d3b6",
|
||||
"acknowledgedBoundary": "42",
|
||||
"observationBoundaries": [
|
||||
{
|
||||
"viewId": "screen",
|
||||
"producedStep": "42"
|
||||
}
|
||||
],
|
||||
"outcomeIds": [
|
||||
"outcome-1"
|
||||
],
|
||||
"eventIds": [
|
||||
"evt-1"
|
||||
],
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": [
|
||||
{
|
||||
"kind": "rollback",
|
||||
"slotId": "best",
|
||||
"stateDigest": null
|
||||
},
|
||||
{
|
||||
"kind": "save-slot",
|
||||
"slotId": "best",
|
||||
"stateDigest": "5d41402abc4b2a76b9719d911017c592ae9d3a0c8a7a6f5d2e3d4c5b6a7f8e9d"
|
||||
}
|
||||
]
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
"prepareRequestIds": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"requestId": "req-41"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"requestId": "req-42"
|
||||
}
|
||||
],
|
||||
"advanceRequestId": "req-43",
|
||||
"commitRequestIds": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"requestId": "req-44"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"requestId": "req-45"
|
||||
}
|
||||
],
|
||||
"busCallIds": [
|
||||
"call-100",
|
||||
"call-101",
|
||||
"call-102"
|
||||
],
|
||||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
],
|
||||
"captures": []
|
||||
}
|
||||
},
|
||||
"reason": "nothing follows a rollback at the same boundary"
|
||||
},
|
||||
{
|
||||
"name": "a slot save without its state digest",
|
||||
"type": "TransitionTrace",
|
||||
"value": {
|
||||
"behaviour": {
|
||||
"scope": {
|
||||
"sessionId": "demo",
|
||||
"epoch": "epoch-1",
|
||||
"step": "41"
|
||||
},
|
||||
"agents": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"profileDigest": "1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0",
|
||||
"ticksAdvanced": "17",
|
||||
"brainTicks": "2517",
|
||||
"remainder": {
|
||||
"numerator": "1000000",
|
||||
"denominator": "3"
|
||||
},
|
||||
"decisionDigest": "a62db30eb7427e2ea9ec58661e69a1eff38e67f21ec97df7d91b24015890d89b",
|
||||
"committedStep": "42"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"profileDigest": "1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0",
|
||||
"ticksAdvanced": "17",
|
||||
"brainTicks": "2550",
|
||||
"remainder": {
|
||||
"numerator": "0",
|
||||
"denominator": "1"
|
||||
},
|
||||
"decisionDigest": "ddc2e7b8b300cda681c3d91368050fcb95dd66d20fd295834c31307d3df2623e",
|
||||
"committedStep": "42"
|
||||
}
|
||||
],
|
||||
"batchId": "batch-41",
|
||||
"controlDigest": "1e2135d1b50f14d3d3d6cbe24a4294bcb9e4d5d3c28eb1ce4980ff2a17c5d3b6",
|
||||
"acknowledgedBoundary": "42",
|
||||
"observationBoundaries": [
|
||||
{
|
||||
"viewId": "screen",
|
||||
"producedStep": "42"
|
||||
}
|
||||
],
|
||||
"outcomeIds": [
|
||||
"outcome-1"
|
||||
],
|
||||
"eventIds": [
|
||||
"evt-1"
|
||||
],
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": [
|
||||
{
|
||||
"kind": "save-slot",
|
||||
"slotId": "best",
|
||||
"stateDigest": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
"prepareRequestIds": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"requestId": "req-41"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"requestId": "req-42"
|
||||
}
|
||||
],
|
||||
"advanceRequestId": "req-43",
|
||||
"commitRequestIds": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"requestId": "req-44"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"requestId": "req-45"
|
||||
}
|
||||
],
|
||||
"busCallIds": [
|
||||
"call-100",
|
||||
"call-101",
|
||||
"call-102"
|
||||
],
|
||||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
],
|
||||
"captures": []
|
||||
}
|
||||
},
|
||||
"reason": "a slot save records the saved state's digest"
|
||||
},
|
||||
{
|
||||
"name": "the same slot saved twice at one boundary",
|
||||
"type": "TransitionTrace",
|
||||
"value": {
|
||||
"behaviour": {
|
||||
"scope": {
|
||||
"sessionId": "demo",
|
||||
"epoch": "epoch-1",
|
||||
"step": "41"
|
||||
},
|
||||
"agents": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"profileDigest": "1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0",
|
||||
"ticksAdvanced": "17",
|
||||
"brainTicks": "2517",
|
||||
"remainder": {
|
||||
"numerator": "1000000",
|
||||
"denominator": "3"
|
||||
},
|
||||
"decisionDigest": "a62db30eb7427e2ea9ec58661e69a1eff38e67f21ec97df7d91b24015890d89b",
|
||||
"committedStep": "42"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"profileDigest": "1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0",
|
||||
"ticksAdvanced": "17",
|
||||
"brainTicks": "2550",
|
||||
"remainder": {
|
||||
"numerator": "0",
|
||||
"denominator": "1"
|
||||
},
|
||||
"decisionDigest": "ddc2e7b8b300cda681c3d91368050fcb95dd66d20fd295834c31307d3df2623e",
|
||||
"committedStep": "42"
|
||||
}
|
||||
],
|
||||
"batchId": "batch-41",
|
||||
"controlDigest": "1e2135d1b50f14d3d3d6cbe24a4294bcb9e4d5d3c28eb1ce4980ff2a17c5d3b6",
|
||||
"acknowledgedBoundary": "42",
|
||||
"observationBoundaries": [
|
||||
{
|
||||
"viewId": "screen",
|
||||
"producedStep": "42"
|
||||
}
|
||||
],
|
||||
"outcomeIds": [
|
||||
"outcome-1"
|
||||
],
|
||||
"eventIds": [
|
||||
"evt-1"
|
||||
],
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": [
|
||||
{
|
||||
"kind": "save-slot",
|
||||
"slotId": "best",
|
||||
"stateDigest": "5d41402abc4b2a76b9719d911017c592ae9d3a0c8a7a6f5d2e3d4c5b6a7f8e9d"
|
||||
},
|
||||
{
|
||||
"kind": "save-slot",
|
||||
"slotId": "best",
|
||||
"stateDigest": "5d41402abc4b2a76b9719d911017c592ae9d3a0c8a7a6f5d2e3d4c5b6a7f8e9d"
|
||||
}
|
||||
]
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
"prepareRequestIds": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"requestId": "req-41"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"requestId": "req-42"
|
||||
}
|
||||
],
|
||||
"advanceRequestId": "req-43",
|
||||
"commitRequestIds": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"requestId": "req-44"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"requestId": "req-45"
|
||||
}
|
||||
],
|
||||
"busCallIds": [
|
||||
"call-100",
|
||||
"call-101",
|
||||
"call-102"
|
||||
],
|
||||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
],
|
||||
"captures": []
|
||||
}
|
||||
},
|
||||
"reason": "a slot is saved at most once per boundary"
|
||||
},
|
||||
{
|
||||
"name": "an unknown boundary action",
|
||||
"type": "TransitionTrace",
|
||||
"value": {
|
||||
"behaviour": {
|
||||
"scope": {
|
||||
"sessionId": "demo",
|
||||
"epoch": "epoch-1",
|
||||
"step": "41"
|
||||
},
|
||||
"agents": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"profileDigest": "1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0",
|
||||
"ticksAdvanced": "17",
|
||||
"brainTicks": "2517",
|
||||
"remainder": {
|
||||
"numerator": "1000000",
|
||||
"denominator": "3"
|
||||
},
|
||||
"decisionDigest": "a62db30eb7427e2ea9ec58661e69a1eff38e67f21ec97df7d91b24015890d89b",
|
||||
"committedStep": "42"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"profileDigest": "1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0",
|
||||
"ticksAdvanced": "17",
|
||||
"brainTicks": "2550",
|
||||
"remainder": {
|
||||
"numerator": "0",
|
||||
"denominator": "1"
|
||||
},
|
||||
"decisionDigest": "ddc2e7b8b300cda681c3d91368050fcb95dd66d20fd295834c31307d3df2623e",
|
||||
"committedStep": "42"
|
||||
}
|
||||
],
|
||||
"batchId": "batch-41",
|
||||
"controlDigest": "1e2135d1b50f14d3d3d6cbe24a4294bcb9e4d5d3c28eb1ce4980ff2a17c5d3b6",
|
||||
"acknowledgedBoundary": "42",
|
||||
"observationBoundaries": [
|
||||
{
|
||||
"viewId": "screen",
|
||||
"producedStep": "42"
|
||||
}
|
||||
],
|
||||
"outcomeIds": [
|
||||
"outcome-1"
|
||||
],
|
||||
"eventIds": [
|
||||
"evt-1"
|
||||
],
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": [
|
||||
{
|
||||
"kind": "reset",
|
||||
"slotId": "best",
|
||||
"stateDigest": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
"prepareRequestIds": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"requestId": "req-41"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"requestId": "req-42"
|
||||
}
|
||||
],
|
||||
"advanceRequestId": "req-43",
|
||||
"commitRequestIds": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"requestId": "req-44"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"requestId": "req-45"
|
||||
}
|
||||
],
|
||||
"busCallIds": [
|
||||
"call-100",
|
||||
"call-101",
|
||||
"call-102"
|
||||
],
|
||||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
],
|
||||
"captures": []
|
||||
}
|
||||
},
|
||||
"reason": "BoundaryActionKind is closed"
|
||||
},
|
||||
{
|
||||
"name": "captures recorded out of order",
|
||||
"type": "TransitionTrace",
|
||||
"value": {
|
||||
"behaviour": {
|
||||
"scope": {
|
||||
"sessionId": "demo",
|
||||
"epoch": "epoch-1",
|
||||
"step": "41"
|
||||
},
|
||||
"agents": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"profileDigest": "1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0",
|
||||
"ticksAdvanced": "17",
|
||||
"brainTicks": "2517",
|
||||
"remainder": {
|
||||
"numerator": "1000000",
|
||||
"denominator": "3"
|
||||
},
|
||||
"decisionDigest": "a62db30eb7427e2ea9ec58661e69a1eff38e67f21ec97df7d91b24015890d89b",
|
||||
"committedStep": "42"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"profileDigest": "1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0",
|
||||
"ticksAdvanced": "17",
|
||||
"brainTicks": "2550",
|
||||
"remainder": {
|
||||
"numerator": "0",
|
||||
"denominator": "1"
|
||||
},
|
||||
"decisionDigest": "ddc2e7b8b300cda681c3d91368050fcb95dd66d20fd295834c31307d3df2623e",
|
||||
"committedStep": "42"
|
||||
}
|
||||
],
|
||||
"batchId": "batch-41",
|
||||
"controlDigest": "1e2135d1b50f14d3d3d6cbe24a4294bcb9e4d5d3c28eb1ce4980ff2a17c5d3b6",
|
||||
"acknowledgedBoundary": "42",
|
||||
"observationBoundaries": [
|
||||
{
|
||||
"viewId": "screen",
|
||||
"producedStep": "42"
|
||||
}
|
||||
],
|
||||
"outcomeIds": [
|
||||
"outcome-1"
|
||||
],
|
||||
"eventIds": [
|
||||
"evt-1"
|
||||
],
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": [
|
||||
{
|
||||
"kind": "save-slot",
|
||||
"slotId": "best",
|
||||
"stateDigest": "5d41402abc4b2a76b9719d911017c592ae9d3a0c8a7a6f5d2e3d4c5b6a7f8e9d"
|
||||
},
|
||||
{
|
||||
"kind": "rollback",
|
||||
"slotId": "best",
|
||||
"stateDigest": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
"prepareRequestIds": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"requestId": "req-41"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"requestId": "req-42"
|
||||
}
|
||||
],
|
||||
"advanceRequestId": "req-43",
|
||||
"commitRequestIds": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"requestId": "req-44"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"requestId": "req-45"
|
||||
}
|
||||
],
|
||||
"busCallIds": [
|
||||
"call-100",
|
||||
"call-101",
|
||||
"call-102"
|
||||
],
|
||||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
],
|
||||
"captures": [
|
||||
{
|
||||
"checkpointId": "a",
|
||||
"afterActions": 2
|
||||
},
|
||||
{
|
||||
"checkpointId": "b",
|
||||
"afterActions": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"reason": "captures are recorded in the order taken"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -54,7 +54,8 @@
|
|||
"evt-1",
|
||||
"evt-2"
|
||||
],
|
||||
"publishedBoundary": "42"
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": []
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
|
|
@ -87,7 +88,8 @@
|
|||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
]
|
||||
],
|
||||
"captures": []
|
||||
}
|
||||
},
|
||||
"variants": [
|
||||
|
|
@ -147,7 +149,8 @@
|
|||
"evt-1",
|
||||
"evt-2"
|
||||
],
|
||||
"publishedBoundary": "42"
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": []
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
|
|
@ -180,7 +183,8 @@
|
|||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
]
|
||||
],
|
||||
"captures": []
|
||||
}
|
||||
},
|
||||
"behaviourEquals": true,
|
||||
|
|
@ -242,7 +246,8 @@
|
|||
"evt-1",
|
||||
"evt-2"
|
||||
],
|
||||
"publishedBoundary": "42"
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": []
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "9999999999",
|
||||
|
|
@ -276,7 +281,8 @@
|
|||
"deliveryIds": [
|
||||
"dlv-91",
|
||||
"own-92"
|
||||
]
|
||||
],
|
||||
"captures": []
|
||||
}
|
||||
},
|
||||
"behaviourEquals": true,
|
||||
|
|
@ -338,7 +344,8 @@
|
|||
"evt-1",
|
||||
"evt-2"
|
||||
],
|
||||
"publishedBoundary": "42"
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": []
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
|
|
@ -371,7 +378,8 @@
|
|||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
]
|
||||
],
|
||||
"captures": []
|
||||
}
|
||||
},
|
||||
"behaviourEquals": true,
|
||||
|
|
@ -433,7 +441,8 @@
|
|||
"evt-1",
|
||||
"evt-2"
|
||||
],
|
||||
"publishedBoundary": "42"
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": []
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
|
|
@ -466,7 +475,8 @@
|
|||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
]
|
||||
],
|
||||
"captures": []
|
||||
}
|
||||
},
|
||||
"behaviourEquals": false,
|
||||
|
|
@ -528,7 +538,8 @@
|
|||
"evt-1",
|
||||
"evt-2"
|
||||
],
|
||||
"publishedBoundary": "42"
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": []
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
|
|
@ -561,7 +572,8 @@
|
|||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
]
|
||||
],
|
||||
"captures": []
|
||||
}
|
||||
},
|
||||
"behaviourEquals": false,
|
||||
|
|
@ -623,7 +635,8 @@
|
|||
"evt-1",
|
||||
"evt-2"
|
||||
],
|
||||
"publishedBoundary": "42"
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": []
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
|
|
@ -656,7 +669,8 @@
|
|||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
]
|
||||
],
|
||||
"captures": []
|
||||
}
|
||||
},
|
||||
"behaviourEquals": false,
|
||||
|
|
@ -718,7 +732,8 @@
|
|||
"evt-1",
|
||||
"evt-2"
|
||||
],
|
||||
"publishedBoundary": "42"
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": []
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
|
|
@ -751,7 +766,8 @@
|
|||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
]
|
||||
],
|
||||
"captures": []
|
||||
}
|
||||
},
|
||||
"behaviourEquals": false,
|
||||
|
|
@ -813,7 +829,8 @@
|
|||
"evt-1",
|
||||
"evt-2"
|
||||
],
|
||||
"publishedBoundary": "42"
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": []
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
|
|
@ -846,7 +863,8 @@
|
|||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
]
|
||||
],
|
||||
"captures": []
|
||||
}
|
||||
},
|
||||
"behaviourEquals": false,
|
||||
|
|
@ -908,7 +926,8 @@
|
|||
"evt-1",
|
||||
"evt-2"
|
||||
],
|
||||
"publishedBoundary": "42"
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": []
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
|
|
@ -941,7 +960,8 @@
|
|||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
]
|
||||
],
|
||||
"captures": []
|
||||
}
|
||||
},
|
||||
"behaviourEquals": false,
|
||||
|
|
@ -1003,7 +1023,8 @@
|
|||
"evt-2",
|
||||
"evt-1"
|
||||
],
|
||||
"publishedBoundary": "42"
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": []
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
|
|
@ -1036,7 +1057,8 @@
|
|||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
]
|
||||
],
|
||||
"captures": []
|
||||
}
|
||||
},
|
||||
"behaviourEquals": false,
|
||||
|
|
@ -1098,7 +1120,8 @@
|
|||
"evt-1",
|
||||
"evt-2"
|
||||
],
|
||||
"publishedBoundary": "42"
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": []
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
|
|
@ -1131,7 +1154,8 @@
|
|||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
]
|
||||
],
|
||||
"captures": []
|
||||
}
|
||||
},
|
||||
"behaviourEquals": false,
|
||||
|
|
|
|||
|
|
@ -2763,7 +2763,8 @@
|
|||
"eventIds": [
|
||||
"evt-1"
|
||||
],
|
||||
"publishedBoundary": "42"
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": []
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
|
|
@ -2796,12 +2797,13 @@
|
|||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
]
|
||||
],
|
||||
"captures": []
|
||||
}
|
||||
},
|
||||
"note": "",
|
||||
"canonical": "{\"behaviour\":{\"acknowledgedBoundary\":\"42\",\"agents\":[{\"agentId\":\"fly-a\",\"brainTicks\":\"2517\",\"committedStep\":\"42\",\"decisionDigest\":\"a62db30eb7427e2ea9ec58661e69a1eff38e67f21ec97df7d91b24015890d89b\",\"profileDigest\":\"1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0\",\"remainder\":{\"denominator\":\"3\",\"numerator\":\"1000000\"},\"ticksAdvanced\":\"17\"},{\"agentId\":\"fly-b\",\"brainTicks\":\"2550\",\"committedStep\":\"42\",\"decisionDigest\":\"ddc2e7b8b300cda681c3d91368050fcb95dd66d20fd295834c31307d3df2623e\",\"profileDigest\":\"1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0\",\"remainder\":{\"denominator\":\"1\",\"numerator\":\"0\"},\"ticksAdvanced\":\"17\"}],\"batchId\":\"batch-41\",\"controlDigest\":\"1e2135d1b50f14d3d3d6cbe24a4294bcb9e4d5d3c28eb1ce4980ff2a17c5d3b6\",\"eventIds\":[\"evt-1\"],\"observationBoundaries\":[{\"producedStep\":\"42\",\"viewId\":\"screen\"}],\"outcomeIds\":[\"outcome-1\"],\"publishedBoundary\":\"42\",\"scope\":{\"epoch\":\"epoch-1\",\"sessionId\":\"demo\",\"step\":\"41\"}},\"operational\":{\"advanceRequestId\":\"req-43\",\"busCallIds\":[\"call-100\",\"call-101\",\"call-102\"],\"commitRequestIds\":[{\"agentId\":\"fly-a\",\"requestId\":\"req-44\"},{\"agentId\":\"fly-b\",\"requestId\":\"req-45\"}],\"deliveryIds\":[\"dlv-7\",\"own-9\"],\"prepareRequestIds\":[{\"agentId\":\"fly-a\",\"requestId\":\"req-41\"},{\"agentId\":\"fly-b\",\"requestId\":\"req-42\"}],\"wallTimeNs\":\"1234567890\"}}",
|
||||
"digest": "707701d6dcf5529a67cc9b1e300d5e1a273b9a7b02d91154d4a2a1978cd8e549"
|
||||
"canonical": "{\"behaviour\":{\"acknowledgedBoundary\":\"42\",\"agents\":[{\"agentId\":\"fly-a\",\"brainTicks\":\"2517\",\"committedStep\":\"42\",\"decisionDigest\":\"a62db30eb7427e2ea9ec58661e69a1eff38e67f21ec97df7d91b24015890d89b\",\"profileDigest\":\"1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0\",\"remainder\":{\"denominator\":\"3\",\"numerator\":\"1000000\"},\"ticksAdvanced\":\"17\"},{\"agentId\":\"fly-b\",\"brainTicks\":\"2550\",\"committedStep\":\"42\",\"decisionDigest\":\"ddc2e7b8b300cda681c3d91368050fcb95dd66d20fd295834c31307d3df2623e\",\"profileDigest\":\"1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0\",\"remainder\":{\"denominator\":\"1\",\"numerator\":\"0\"},\"ticksAdvanced\":\"17\"}],\"batchId\":\"batch-41\",\"boundaryActions\":[],\"controlDigest\":\"1e2135d1b50f14d3d3d6cbe24a4294bcb9e4d5d3c28eb1ce4980ff2a17c5d3b6\",\"eventIds\":[\"evt-1\"],\"observationBoundaries\":[{\"producedStep\":\"42\",\"viewId\":\"screen\"}],\"outcomeIds\":[\"outcome-1\"],\"publishedBoundary\":\"42\",\"scope\":{\"epoch\":\"epoch-1\",\"sessionId\":\"demo\",\"step\":\"41\"}},\"operational\":{\"advanceRequestId\":\"req-43\",\"busCallIds\":[\"call-100\",\"call-101\",\"call-102\"],\"captures\":[],\"commitRequestIds\":[{\"agentId\":\"fly-a\",\"requestId\":\"req-44\"},{\"agentId\":\"fly-b\",\"requestId\":\"req-45\"}],\"deliveryIds\":[\"dlv-7\",\"own-9\"],\"prepareRequestIds\":[{\"agentId\":\"fly-a\",\"requestId\":\"req-41\"},{\"agentId\":\"fly-b\",\"requestId\":\"req-42\"}],\"wallTimeNs\":\"1234567890\"}}",
|
||||
"digest": "36ecd5d39f81863c30c0fd52a12d72eb3ba71f0f3b72b2349e2c7f02a1d8e3e5"
|
||||
},
|
||||
{
|
||||
"name": "trace behaviour on its own",
|
||||
|
|
@ -2853,11 +2855,12 @@
|
|||
"eventIds": [
|
||||
"evt-1"
|
||||
],
|
||||
"publishedBoundary": "42"
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": []
|
||||
},
|
||||
"note": "the half two runs must agree on",
|
||||
"canonical": "{\"acknowledgedBoundary\":\"42\",\"agents\":[{\"agentId\":\"fly-a\",\"brainTicks\":\"2517\",\"committedStep\":\"42\",\"decisionDigest\":\"a62db30eb7427e2ea9ec58661e69a1eff38e67f21ec97df7d91b24015890d89b\",\"profileDigest\":\"1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0\",\"remainder\":{\"denominator\":\"3\",\"numerator\":\"1000000\"},\"ticksAdvanced\":\"17\"},{\"agentId\":\"fly-b\",\"brainTicks\":\"2550\",\"committedStep\":\"42\",\"decisionDigest\":\"ddc2e7b8b300cda681c3d91368050fcb95dd66d20fd295834c31307d3df2623e\",\"profileDigest\":\"1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0\",\"remainder\":{\"denominator\":\"1\",\"numerator\":\"0\"},\"ticksAdvanced\":\"17\"}],\"batchId\":\"batch-41\",\"controlDigest\":\"1e2135d1b50f14d3d3d6cbe24a4294bcb9e4d5d3c28eb1ce4980ff2a17c5d3b6\",\"eventIds\":[\"evt-1\"],\"observationBoundaries\":[{\"producedStep\":\"42\",\"viewId\":\"screen\"}],\"outcomeIds\":[\"outcome-1\"],\"publishedBoundary\":\"42\",\"scope\":{\"epoch\":\"epoch-1\",\"sessionId\":\"demo\",\"step\":\"41\"}}",
|
||||
"digest": "d938188fe3006537dbc0038fabf2a05df584e64b361b1106d79f3f965dff414a"
|
||||
"canonical": "{\"acknowledgedBoundary\":\"42\",\"agents\":[{\"agentId\":\"fly-a\",\"brainTicks\":\"2517\",\"committedStep\":\"42\",\"decisionDigest\":\"a62db30eb7427e2ea9ec58661e69a1eff38e67f21ec97df7d91b24015890d89b\",\"profileDigest\":\"1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0\",\"remainder\":{\"denominator\":\"3\",\"numerator\":\"1000000\"},\"ticksAdvanced\":\"17\"},{\"agentId\":\"fly-b\",\"brainTicks\":\"2550\",\"committedStep\":\"42\",\"decisionDigest\":\"ddc2e7b8b300cda681c3d91368050fcb95dd66d20fd295834c31307d3df2623e\",\"profileDigest\":\"1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0\",\"remainder\":{\"denominator\":\"1\",\"numerator\":\"0\"},\"ticksAdvanced\":\"17\"}],\"batchId\":\"batch-41\",\"boundaryActions\":[],\"controlDigest\":\"1e2135d1b50f14d3d3d6cbe24a4294bcb9e4d5d3c28eb1ce4980ff2a17c5d3b6\",\"eventIds\":[\"evt-1\"],\"observationBoundaries\":[{\"producedStep\":\"42\",\"viewId\":\"screen\"}],\"outcomeIds\":[\"outcome-1\"],\"publishedBoundary\":\"42\",\"scope\":{\"epoch\":\"epoch-1\",\"sessionId\":\"demo\",\"step\":\"41\"}}",
|
||||
"digest": "59ed2ef812fe44a5808d8251b253c76a642cdc6828ee964a1c90ef302b66c9e4"
|
||||
},
|
||||
{
|
||||
"name": "trace operational metadata on its own",
|
||||
|
|
@ -2893,11 +2896,12 @@
|
|||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
]
|
||||
],
|
||||
"captures": []
|
||||
},
|
||||
"note": "recorded by step-v1 section 8, excluded from its comparison",
|
||||
"canonical": "{\"advanceRequestId\":\"req-43\",\"busCallIds\":[\"call-100\",\"call-101\",\"call-102\"],\"commitRequestIds\":[{\"agentId\":\"fly-a\",\"requestId\":\"req-44\"},{\"agentId\":\"fly-b\",\"requestId\":\"req-45\"}],\"deliveryIds\":[\"dlv-7\",\"own-9\"],\"prepareRequestIds\":[{\"agentId\":\"fly-a\",\"requestId\":\"req-41\"},{\"agentId\":\"fly-b\",\"requestId\":\"req-42\"}],\"wallTimeNs\":\"1234567890\"}",
|
||||
"digest": "07c3402ab0e48b186d56f667da980a15b2a48b21381235cff37523a24ff0dfff"
|
||||
"canonical": "{\"advanceRequestId\":\"req-43\",\"busCallIds\":[\"call-100\",\"call-101\",\"call-102\"],\"captures\":[],\"commitRequestIds\":[{\"agentId\":\"fly-a\",\"requestId\":\"req-44\"},{\"agentId\":\"fly-b\",\"requestId\":\"req-45\"}],\"deliveryIds\":[\"dlv-7\",\"own-9\"],\"prepareRequestIds\":[{\"agentId\":\"fly-a\",\"requestId\":\"req-41\"},{\"agentId\":\"fly-b\",\"requestId\":\"req-42\"}],\"wallTimeNs\":\"1234567890\"}",
|
||||
"digest": "d9fd215dbea34237559ff5a5826beca16d3646340f2ce76ee62115d21f7c27d6"
|
||||
},
|
||||
{
|
||||
"name": "agent telemetry reporting a running stimulation pulse",
|
||||
|
|
@ -3338,12 +3342,39 @@
|
|||
"mode": "macros",
|
||||
"macroChannels": [
|
||||
"macro_go_objective",
|
||||
"macro_go_out",
|
||||
"macro_go_warp",
|
||||
"macro_go_route",
|
||||
"macro_go_item",
|
||||
"macro_go_npc",
|
||||
"macro_go_frontier",
|
||||
"macro_go_shop",
|
||||
"macro_go_heal",
|
||||
"macro_talk",
|
||||
"macro_menu",
|
||||
"macro_next",
|
||||
"macro_move_1"
|
||||
"macro_yes",
|
||||
"macro_no",
|
||||
"macro_close",
|
||||
"macro_confirm",
|
||||
"macro_back",
|
||||
"macro_move_1",
|
||||
"macro_move_2",
|
||||
"macro_move_3",
|
||||
"macro_move_4",
|
||||
"macro_switch",
|
||||
"macro_item",
|
||||
"macro_throw_ball",
|
||||
"macro_run",
|
||||
"macro_buy_potion",
|
||||
"macro_buy_ball",
|
||||
"macro_buy_antidote",
|
||||
"macro_buy_repel",
|
||||
"macro_heal",
|
||||
"macro_leave"
|
||||
]
|
||||
},
|
||||
"decoderConfigDigest": "5c3f2f084bef674fed492b82e5e0951e993c856ae98f5453d180cd06143dc854",
|
||||
"decoderConfigDigest": "82b6601f0390b742a67eca44ef935b49e16a73315db70f5644f1cbd21f7c8a52",
|
||||
"environment": {
|
||||
"extensions": [
|
||||
"gameboy-slots-v1"
|
||||
|
|
@ -3376,9 +3407,9 @@
|
|||
"checkpointFormatOfRecord": "FLYSIM01",
|
||||
"flysimCompatibility": "lif-1ms-f64-v2/pokered-unique8-v6/75ba5d3536a2862fdb9f4ef1a76b96fe099a7201ac737f0cf53fe4c5ad4183f3:1657ba7716494c9db95a13b1527bc129226363f99b395774de1f76ff28571f0e:63b1acb26272edccdcfacf3c2ff58069e0cefaa84451429c989258bafaeae1d5:f567d7f07227e71c0df2ab4e6510f3a3f79e51b675095792e16d216d74b7b5b7:ece0b5e76d1884dd2f3ff6e0362bc284febe205ac1ce07fdab5009942ddffb62:b8c33144d4cec31c3ac4b6091ef1f4207f567c4f710f7c13fd2dc47c44c2b634:dbbafc044cd50aad7b792615988ff6d9991c846cc3d8b2eafc86b7c357b5eefc/fly-kc-mbon-rstdp-v2/binjgb:c60e138da5a795ebb55e56b11b7e90024e41112c/pokered:0cd19d3b877b7dc66d12c7050bed9a7f38154d4b/statefmt:199616-x86_64-unknown-linux-gnu"
|
||||
},
|
||||
"note": "placeholder ROM and decoder digests",
|
||||
"canonical": "{\"checkpointFormatOfRecord\":\"FLYSIM01\",\"compositionId\":\"pokered-live\",\"decoderConfigDigest\":\"5c3f2f084bef674fed492b82e5e0951e993c856ae98f5453d180cd06143dc854\",\"environment\":{\"audio\":{\"channels\":2,\"sampleRate\":48000},\"controllerSchema\":{\"digest\":\"1bde5fa114b99824ad608fba4ea85706cb0cebc6123a778dc1e5f89791d2a05e\",\"id\":\"gameboy-joypad-v1\",\"version\":1},\"extensions\":[\"gameboy-slots-v1\"],\"inspectionSchema\":{\"digest\":\"d6cb62248bfdac2ffdf00290ffbebf9a101b1fe28f7be766d24db28ede8da3e6\",\"id\":\"gameboy-memory-inspection-v1\",\"version\":1},\"setupFrames\":1,\"slots\":[\"best\"],\"stepDuration\":{\"denominator\":\"512\",\"numerator\":\"8572265625\"}},\"episodePolicy\":\"legacy-ratchet-rollback-v1\",\"executor\":{\"adapter\":\"pokered-unique8-v6\",\"id\":\"pokered-macros-v1\",\"macroChannels\":[\"macro_go_objective\",\"macro_talk\",\"macro_next\",\"macro_move_1\"],\"mode\":\"macros\",\"rom\":{\"byteLength\":\"1048576\",\"digest\":\"c840ea493f9bf41505f26cf5b1db26815dd588e7ec91d5fd6f1ad4d363dc4f20\",\"format\":\"gb-rom\",\"id\":\"pokered-rom\"},\"symbolProvenance\":\"0cd19d3b877b7dc66d12c7050bed9a7f38154d4b\"},\"flysimCompatibility\":\"lif-1ms-f64-v2/pokered-unique8-v6/75ba5d3536a2862fdb9f4ef1a76b96fe099a7201ac737f0cf53fe4c5ad4183f3:1657ba7716494c9db95a13b1527bc129226363f99b395774de1f76ff28571f0e:63b1acb26272edccdcfacf3c2ff58069e0cefaa84451429c989258bafaeae1d5:f567d7f07227e71c0df2ab4e6510f3a3f79e51b675095792e16d216d74b7b5b7:ece0b5e76d1884dd2f3ff6e0362bc284febe205ac1ce07fdab5009942ddffb62:b8c33144d4cec31c3ac4b6091ef1f4207f567c4f710f7c13fd2dc47c44c2b634:dbbafc044cd50aad7b792615988ff6d9991c846cc3d8b2eafc86b7c357b5eefc/fly-kc-mbon-rstdp-v2/binjgb:c60e138da5a795ebb55e56b11b7e90024e41112c/pokered:0cd19d3b877b7dc66d12c7050bed9a7f38154d4b/statefmt:199616-x86_64-unknown-linux-gnu\",\"profile\":{\"byteLength\":\"1137\",\"digest\":\"41e5d1ac62ab23f1b2d7252d52faac08b269c85e6b4c9ed7a370c74032c60878\",\"format\":\"fly-profile-v1\",\"id\":\"gameboy-legacy-fafb-v783-v1\"},\"restore\":\"legacy-transient-reset\",\"scheduler\":\"lockstep-v1\"}",
|
||||
"digest": "f0142c7f09a1319453b472cdddbc1855062af5733f89d1fbc0b82c0adb52b0c7"
|
||||
"note": "placeholder ROM digest; real macros-mode decoder digest and channels",
|
||||
"canonical": "{\"checkpointFormatOfRecord\":\"FLYSIM01\",\"compositionId\":\"pokered-live\",\"decoderConfigDigest\":\"82b6601f0390b742a67eca44ef935b49e16a73315db70f5644f1cbd21f7c8a52\",\"environment\":{\"audio\":{\"channels\":2,\"sampleRate\":48000},\"controllerSchema\":{\"digest\":\"1bde5fa114b99824ad608fba4ea85706cb0cebc6123a778dc1e5f89791d2a05e\",\"id\":\"gameboy-joypad-v1\",\"version\":1},\"extensions\":[\"gameboy-slots-v1\"],\"inspectionSchema\":{\"digest\":\"d6cb62248bfdac2ffdf00290ffbebf9a101b1fe28f7be766d24db28ede8da3e6\",\"id\":\"gameboy-memory-inspection-v1\",\"version\":1},\"setupFrames\":1,\"slots\":[\"best\"],\"stepDuration\":{\"denominator\":\"512\",\"numerator\":\"8572265625\"}},\"episodePolicy\":\"legacy-ratchet-rollback-v1\",\"executor\":{\"adapter\":\"pokered-unique8-v6\",\"id\":\"pokered-macros-v1\",\"macroChannels\":[\"macro_go_objective\",\"macro_go_out\",\"macro_go_warp\",\"macro_go_route\",\"macro_go_item\",\"macro_go_npc\",\"macro_go_frontier\",\"macro_go_shop\",\"macro_go_heal\",\"macro_talk\",\"macro_menu\",\"macro_next\",\"macro_yes\",\"macro_no\",\"macro_close\",\"macro_confirm\",\"macro_back\",\"macro_move_1\",\"macro_move_2\",\"macro_move_3\",\"macro_move_4\",\"macro_switch\",\"macro_item\",\"macro_throw_ball\",\"macro_run\",\"macro_buy_potion\",\"macro_buy_ball\",\"macro_buy_antidote\",\"macro_buy_repel\",\"macro_heal\",\"macro_leave\"],\"mode\":\"macros\",\"rom\":{\"byteLength\":\"1048576\",\"digest\":\"c840ea493f9bf41505f26cf5b1db26815dd588e7ec91d5fd6f1ad4d363dc4f20\",\"format\":\"gb-rom\",\"id\":\"pokered-rom\"},\"symbolProvenance\":\"0cd19d3b877b7dc66d12c7050bed9a7f38154d4b\"},\"flysimCompatibility\":\"lif-1ms-f64-v2/pokered-unique8-v6/75ba5d3536a2862fdb9f4ef1a76b96fe099a7201ac737f0cf53fe4c5ad4183f3:1657ba7716494c9db95a13b1527bc129226363f99b395774de1f76ff28571f0e:63b1acb26272edccdcfacf3c2ff58069e0cefaa84451429c989258bafaeae1d5:f567d7f07227e71c0df2ab4e6510f3a3f79e51b675095792e16d216d74b7b5b7:ece0b5e76d1884dd2f3ff6e0362bc284febe205ac1ce07fdab5009942ddffb62:b8c33144d4cec31c3ac4b6091ef1f4207f567c4f710f7c13fd2dc47c44c2b634:dbbafc044cd50aad7b792615988ff6d9991c846cc3d8b2eafc86b7c357b5eefc/fly-kc-mbon-rstdp-v2/binjgb:c60e138da5a795ebb55e56b11b7e90024e41112c/pokered:0cd19d3b877b7dc66d12c7050bed9a7f38154d4b/statefmt:199616-x86_64-unknown-linux-gnu\",\"profile\":{\"byteLength\":\"1137\",\"digest\":\"41e5d1ac62ab23f1b2d7252d52faac08b269c85e6b4c9ed7a370c74032c60878\",\"format\":\"fly-profile-v1\",\"id\":\"gameboy-legacy-fafb-v783-v1\"},\"restore\":\"legacy-transient-reset\",\"scheduler\":\"lockstep-v1\"}",
|
||||
"digest": "77d8a88ff7fea51eb29b1ae75fc9cf8c17c184e6a1e5a585e86399f41fd9c9b0"
|
||||
},
|
||||
{
|
||||
"name": "an example legacy composition in raw mode",
|
||||
|
|
@ -3405,7 +3436,7 @@
|
|||
"mode": "raw",
|
||||
"macroChannels": []
|
||||
},
|
||||
"decoderConfigDigest": "5c3f2f084bef674fed492b82e5e0951e993c856ae98f5453d180cd06143dc854",
|
||||
"decoderConfigDigest": "6234e4a0363cfe82b8d515943c4f645a3960eda8fa5bf9465009061f80d50812",
|
||||
"environment": {
|
||||
"extensions": [
|
||||
"gameboy-slots-v1"
|
||||
|
|
@ -3439,8 +3470,225 @@
|
|||
"flysimCompatibility": "lif-1ms-f64-v2/pokered-unique8-v6/75ba5d3536a2862fdb9f4ef1a76b96fe099a7201ac737f0cf53fe4c5ad4183f3:1657ba7716494c9db95a13b1527bc129226363f99b395774de1f76ff28571f0e:63b1acb26272edccdcfacf3c2ff58069e0cefaa84451429c989258bafaeae1d5:f567d7f07227e71c0df2ab4e6510f3a3f79e51b675095792e16d216d74b7b5b7:ece0b5e76d1884dd2f3ff6e0362bc284febe205ac1ce07fdab5009942ddffb62:b8c33144d4cec31c3ac4b6091ef1f4207f567c4f710f7c13fd2dc47c44c2b634:dbbafc044cd50aad7b792615988ff6d9991c846cc3d8b2eafc86b7c357b5eefc/fly-kc-mbon-rstdp-v2/binjgb:c60e138da5a795ebb55e56b11b7e90024e41112c/pokered:0cd19d3b877b7dc66d12c7050bed9a7f38154d4b/statefmt:199616-x86_64-unknown-linux-gnu"
|
||||
},
|
||||
"note": "",
|
||||
"canonical": "{\"checkpointFormatOfRecord\":\"FLYSIM01\",\"compositionId\":\"pokered-live\",\"decoderConfigDigest\":\"5c3f2f084bef674fed492b82e5e0951e993c856ae98f5453d180cd06143dc854\",\"environment\":{\"audio\":{\"channels\":2,\"sampleRate\":48000},\"controllerSchema\":{\"digest\":\"1bde5fa114b99824ad608fba4ea85706cb0cebc6123a778dc1e5f89791d2a05e\",\"id\":\"gameboy-joypad-v1\",\"version\":1},\"extensions\":[\"gameboy-slots-v1\"],\"inspectionSchema\":{\"digest\":\"d6cb62248bfdac2ffdf00290ffbebf9a101b1fe28f7be766d24db28ede8da3e6\",\"id\":\"gameboy-memory-inspection-v1\",\"version\":1},\"setupFrames\":1,\"slots\":[\"best\"],\"stepDuration\":{\"denominator\":\"512\",\"numerator\":\"8572265625\"}},\"episodePolicy\":\"legacy-ratchet-rollback-v1\",\"executor\":{\"adapter\":\"pokered-unique8-v6\",\"id\":\"pokered-macros-v1\",\"macroChannels\":[],\"mode\":\"raw\",\"rom\":{\"byteLength\":\"1048576\",\"digest\":\"c840ea493f9bf41505f26cf5b1db26815dd588e7ec91d5fd6f1ad4d363dc4f20\",\"format\":\"gb-rom\",\"id\":\"pokered-rom\"},\"symbolProvenance\":\"0cd19d3b877b7dc66d12c7050bed9a7f38154d4b\"},\"flysimCompatibility\":\"lif-1ms-f64-v2/pokered-unique8-v6/75ba5d3536a2862fdb9f4ef1a76b96fe099a7201ac737f0cf53fe4c5ad4183f3:1657ba7716494c9db95a13b1527bc129226363f99b395774de1f76ff28571f0e:63b1acb26272edccdcfacf3c2ff58069e0cefaa84451429c989258bafaeae1d5:f567d7f07227e71c0df2ab4e6510f3a3f79e51b675095792e16d216d74b7b5b7:ece0b5e76d1884dd2f3ff6e0362bc284febe205ac1ce07fdab5009942ddffb62:b8c33144d4cec31c3ac4b6091ef1f4207f567c4f710f7c13fd2dc47c44c2b634:dbbafc044cd50aad7b792615988ff6d9991c846cc3d8b2eafc86b7c357b5eefc/fly-kc-mbon-rstdp-v2/binjgb:c60e138da5a795ebb55e56b11b7e90024e41112c/pokered:0cd19d3b877b7dc66d12c7050bed9a7f38154d4b/statefmt:199616-x86_64-unknown-linux-gnu\",\"profile\":{\"byteLength\":\"1137\",\"digest\":\"41e5d1ac62ab23f1b2d7252d52faac08b269c85e6b4c9ed7a370c74032c60878\",\"format\":\"fly-profile-v1\",\"id\":\"gameboy-legacy-fafb-v783-v1\"},\"restore\":\"legacy-transient-reset\",\"scheduler\":\"lockstep-v1\"}",
|
||||
"digest": "efd699cf8cf2485dd2ac8a84ff43c9bc3711a78181f32285ed31a2ee86e16925"
|
||||
"canonical": "{\"checkpointFormatOfRecord\":\"FLYSIM01\",\"compositionId\":\"pokered-live\",\"decoderConfigDigest\":\"6234e4a0363cfe82b8d515943c4f645a3960eda8fa5bf9465009061f80d50812\",\"environment\":{\"audio\":{\"channels\":2,\"sampleRate\":48000},\"controllerSchema\":{\"digest\":\"1bde5fa114b99824ad608fba4ea85706cb0cebc6123a778dc1e5f89791d2a05e\",\"id\":\"gameboy-joypad-v1\",\"version\":1},\"extensions\":[\"gameboy-slots-v1\"],\"inspectionSchema\":{\"digest\":\"d6cb62248bfdac2ffdf00290ffbebf9a101b1fe28f7be766d24db28ede8da3e6\",\"id\":\"gameboy-memory-inspection-v1\",\"version\":1},\"setupFrames\":1,\"slots\":[\"best\"],\"stepDuration\":{\"denominator\":\"512\",\"numerator\":\"8572265625\"}},\"episodePolicy\":\"legacy-ratchet-rollback-v1\",\"executor\":{\"adapter\":\"pokered-unique8-v6\",\"id\":\"pokered-macros-v1\",\"macroChannels\":[],\"mode\":\"raw\",\"rom\":{\"byteLength\":\"1048576\",\"digest\":\"c840ea493f9bf41505f26cf5b1db26815dd588e7ec91d5fd6f1ad4d363dc4f20\",\"format\":\"gb-rom\",\"id\":\"pokered-rom\"},\"symbolProvenance\":\"0cd19d3b877b7dc66d12c7050bed9a7f38154d4b\"},\"flysimCompatibility\":\"lif-1ms-f64-v2/pokered-unique8-v6/75ba5d3536a2862fdb9f4ef1a76b96fe099a7201ac737f0cf53fe4c5ad4183f3:1657ba7716494c9db95a13b1527bc129226363f99b395774de1f76ff28571f0e:63b1acb26272edccdcfacf3c2ff58069e0cefaa84451429c989258bafaeae1d5:f567d7f07227e71c0df2ab4e6510f3a3f79e51b675095792e16d216d74b7b5b7:ece0b5e76d1884dd2f3ff6e0362bc284febe205ac1ce07fdab5009942ddffb62:b8c33144d4cec31c3ac4b6091ef1f4207f567c4f710f7c13fd2dc47c44c2b634:dbbafc044cd50aad7b792615988ff6d9991c846cc3d8b2eafc86b7c357b5eefc/fly-kc-mbon-rstdp-v2/binjgb:c60e138da5a795ebb55e56b11b7e90024e41112c/pokered:0cd19d3b877b7dc66d12c7050bed9a7f38154d4b/statefmt:199616-x86_64-unknown-linux-gnu\",\"profile\":{\"byteLength\":\"1137\",\"digest\":\"41e5d1ac62ab23f1b2d7252d52faac08b269c85e6b4c9ed7a370c74032c60878\",\"format\":\"fly-profile-v1\",\"id\":\"gameboy-legacy-fafb-v783-v1\"},\"restore\":\"legacy-transient-reset\",\"scheduler\":\"lockstep-v1\"}",
|
||||
"digest": "ac42e702ec6c9b09482b1ee335743ef85fe599a72e2c34a4d32aea67d67d0201"
|
||||
},
|
||||
{
|
||||
"name": "a rank climb: slot saved, then the milestone capture",
|
||||
"type": "TransitionTrace",
|
||||
"value": {
|
||||
"behaviour": {
|
||||
"scope": {
|
||||
"sessionId": "demo",
|
||||
"epoch": "epoch-1",
|
||||
"step": "41"
|
||||
},
|
||||
"agents": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"profileDigest": "1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0",
|
||||
"ticksAdvanced": "17",
|
||||
"brainTicks": "2517",
|
||||
"remainder": {
|
||||
"numerator": "1000000",
|
||||
"denominator": "3"
|
||||
},
|
||||
"decisionDigest": "a62db30eb7427e2ea9ec58661e69a1eff38e67f21ec97df7d91b24015890d89b",
|
||||
"committedStep": "42"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"profileDigest": "1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0",
|
||||
"ticksAdvanced": "17",
|
||||
"brainTicks": "2550",
|
||||
"remainder": {
|
||||
"numerator": "0",
|
||||
"denominator": "1"
|
||||
},
|
||||
"decisionDigest": "ddc2e7b8b300cda681c3d91368050fcb95dd66d20fd295834c31307d3df2623e",
|
||||
"committedStep": "42"
|
||||
}
|
||||
],
|
||||
"batchId": "batch-41",
|
||||
"controlDigest": "1e2135d1b50f14d3d3d6cbe24a4294bcb9e4d5d3c28eb1ce4980ff2a17c5d3b6",
|
||||
"acknowledgedBoundary": "42",
|
||||
"observationBoundaries": [
|
||||
{
|
||||
"viewId": "screen",
|
||||
"producedStep": "42"
|
||||
}
|
||||
],
|
||||
"outcomeIds": [
|
||||
"outcome-1"
|
||||
],
|
||||
"eventIds": [
|
||||
"evt-1"
|
||||
],
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": [
|
||||
{
|
||||
"kind": "save-slot",
|
||||
"slotId": "best",
|
||||
"stateDigest": "5d41402abc4b2a76b9719d911017c592ae9d3a0c8a7a6f5d2e3d4c5b6a7f8e9d"
|
||||
}
|
||||
]
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
"prepareRequestIds": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"requestId": "req-41"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"requestId": "req-42"
|
||||
}
|
||||
],
|
||||
"advanceRequestId": "req-43",
|
||||
"commitRequestIds": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"requestId": "req-44"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"requestId": "req-45"
|
||||
}
|
||||
],
|
||||
"busCallIds": [
|
||||
"call-100",
|
||||
"call-101",
|
||||
"call-102"
|
||||
],
|
||||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
],
|
||||
"captures": [
|
||||
{
|
||||
"checkpointId": "milestone-11",
|
||||
"afterActions": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"note": "legacy-gameboy-v1 section 16: a slot save due at a boundary completes before any capture there",
|
||||
"canonical": "{\"behaviour\":{\"acknowledgedBoundary\":\"42\",\"agents\":[{\"agentId\":\"fly-a\",\"brainTicks\":\"2517\",\"committedStep\":\"42\",\"decisionDigest\":\"a62db30eb7427e2ea9ec58661e69a1eff38e67f21ec97df7d91b24015890d89b\",\"profileDigest\":\"1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0\",\"remainder\":{\"denominator\":\"3\",\"numerator\":\"1000000\"},\"ticksAdvanced\":\"17\"},{\"agentId\":\"fly-b\",\"brainTicks\":\"2550\",\"committedStep\":\"42\",\"decisionDigest\":\"ddc2e7b8b300cda681c3d91368050fcb95dd66d20fd295834c31307d3df2623e\",\"profileDigest\":\"1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0\",\"remainder\":{\"denominator\":\"1\",\"numerator\":\"0\"},\"ticksAdvanced\":\"17\"}],\"batchId\":\"batch-41\",\"boundaryActions\":[{\"kind\":\"save-slot\",\"slotId\":\"best\",\"stateDigest\":\"5d41402abc4b2a76b9719d911017c592ae9d3a0c8a7a6f5d2e3d4c5b6a7f8e9d\"}],\"controlDigest\":\"1e2135d1b50f14d3d3d6cbe24a4294bcb9e4d5d3c28eb1ce4980ff2a17c5d3b6\",\"eventIds\":[\"evt-1\"],\"observationBoundaries\":[{\"producedStep\":\"42\",\"viewId\":\"screen\"}],\"outcomeIds\":[\"outcome-1\"],\"publishedBoundary\":\"42\",\"scope\":{\"epoch\":\"epoch-1\",\"sessionId\":\"demo\",\"step\":\"41\"}},\"operational\":{\"advanceRequestId\":\"req-43\",\"busCallIds\":[\"call-100\",\"call-101\",\"call-102\"],\"captures\":[{\"afterActions\":1,\"checkpointId\":\"milestone-11\"}],\"commitRequestIds\":[{\"agentId\":\"fly-a\",\"requestId\":\"req-44\"},{\"agentId\":\"fly-b\",\"requestId\":\"req-45\"}],\"deliveryIds\":[\"dlv-7\",\"own-9\"],\"prepareRequestIds\":[{\"agentId\":\"fly-a\",\"requestId\":\"req-41\"},{\"agentId\":\"fly-b\",\"requestId\":\"req-42\"}],\"wallTimeNs\":\"1234567890\"}}",
|
||||
"digest": "68c6f1e21cc6f63c36e69b73dbd5c11313b2a76e57f1e5e8468984516a6f96d5"
|
||||
},
|
||||
{
|
||||
"name": "save, capture, rollback, capture at one boundary",
|
||||
"type": "TransitionTrace",
|
||||
"value": {
|
||||
"behaviour": {
|
||||
"scope": {
|
||||
"sessionId": "demo",
|
||||
"epoch": "epoch-1",
|
||||
"step": "41"
|
||||
},
|
||||
"agents": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"profileDigest": "1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0",
|
||||
"ticksAdvanced": "17",
|
||||
"brainTicks": "2517",
|
||||
"remainder": {
|
||||
"numerator": "1000000",
|
||||
"denominator": "3"
|
||||
},
|
||||
"decisionDigest": "a62db30eb7427e2ea9ec58661e69a1eff38e67f21ec97df7d91b24015890d89b",
|
||||
"committedStep": "42"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"profileDigest": "1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0",
|
||||
"ticksAdvanced": "17",
|
||||
"brainTicks": "2550",
|
||||
"remainder": {
|
||||
"numerator": "0",
|
||||
"denominator": "1"
|
||||
},
|
||||
"decisionDigest": "ddc2e7b8b300cda681c3d91368050fcb95dd66d20fd295834c31307d3df2623e",
|
||||
"committedStep": "42"
|
||||
}
|
||||
],
|
||||
"batchId": "batch-41",
|
||||
"controlDigest": "1e2135d1b50f14d3d3d6cbe24a4294bcb9e4d5d3c28eb1ce4980ff2a17c5d3b6",
|
||||
"acknowledgedBoundary": "42",
|
||||
"observationBoundaries": [
|
||||
{
|
||||
"viewId": "screen",
|
||||
"producedStep": "42"
|
||||
}
|
||||
],
|
||||
"outcomeIds": [
|
||||
"outcome-1"
|
||||
],
|
||||
"eventIds": [
|
||||
"evt-1"
|
||||
],
|
||||
"publishedBoundary": "42",
|
||||
"boundaryActions": [
|
||||
{
|
||||
"kind": "save-slot",
|
||||
"slotId": "best",
|
||||
"stateDigest": "5d41402abc4b2a76b9719d911017c592ae9d3a0c8a7a6f5d2e3d4c5b6a7f8e9d"
|
||||
},
|
||||
{
|
||||
"kind": "rollback",
|
||||
"slotId": "best",
|
||||
"stateDigest": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"operational": {
|
||||
"wallTimeNs": "1234567890",
|
||||
"prepareRequestIds": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"requestId": "req-41"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"requestId": "req-42"
|
||||
}
|
||||
],
|
||||
"advanceRequestId": "req-43",
|
||||
"commitRequestIds": [
|
||||
{
|
||||
"agentId": "fly-a",
|
||||
"requestId": "req-44"
|
||||
},
|
||||
{
|
||||
"agentId": "fly-b",
|
||||
"requestId": "req-45"
|
||||
}
|
||||
],
|
||||
"busCallIds": [
|
||||
"call-100",
|
||||
"call-101",
|
||||
"call-102"
|
||||
],
|
||||
"deliveryIds": [
|
||||
"dlv-7",
|
||||
"own-9"
|
||||
],
|
||||
"captures": [
|
||||
{
|
||||
"checkpointId": "periodic-7",
|
||||
"afterActions": 1
|
||||
},
|
||||
{
|
||||
"checkpointId": "after-rollback-7",
|
||||
"afterActions": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"note": "a durable save follows the rollback, as the legacy loop checkpoints after a recovery",
|
||||
"canonical": "{\"behaviour\":{\"acknowledgedBoundary\":\"42\",\"agents\":[{\"agentId\":\"fly-a\",\"brainTicks\":\"2517\",\"committedStep\":\"42\",\"decisionDigest\":\"a62db30eb7427e2ea9ec58661e69a1eff38e67f21ec97df7d91b24015890d89b\",\"profileDigest\":\"1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0\",\"remainder\":{\"denominator\":\"3\",\"numerator\":\"1000000\"},\"ticksAdvanced\":\"17\"},{\"agentId\":\"fly-b\",\"brainTicks\":\"2550\",\"committedStep\":\"42\",\"decisionDigest\":\"ddc2e7b8b300cda681c3d91368050fcb95dd66d20fd295834c31307d3df2623e\",\"profileDigest\":\"1900eab6c028483d7126599ee6f50de0d27907b5c65fa90524580b4b0f9852b0\",\"remainder\":{\"denominator\":\"1\",\"numerator\":\"0\"},\"ticksAdvanced\":\"17\"}],\"batchId\":\"batch-41\",\"boundaryActions\":[{\"kind\":\"save-slot\",\"slotId\":\"best\",\"stateDigest\":\"5d41402abc4b2a76b9719d911017c592ae9d3a0c8a7a6f5d2e3d4c5b6a7f8e9d\"},{\"kind\":\"rollback\",\"slotId\":\"best\",\"stateDigest\":null}],\"controlDigest\":\"1e2135d1b50f14d3d3d6cbe24a4294bcb9e4d5d3c28eb1ce4980ff2a17c5d3b6\",\"eventIds\":[\"evt-1\"],\"observationBoundaries\":[{\"producedStep\":\"42\",\"viewId\":\"screen\"}],\"outcomeIds\":[\"outcome-1\"],\"publishedBoundary\":\"42\",\"scope\":{\"epoch\":\"epoch-1\",\"sessionId\":\"demo\",\"step\":\"41\"}},\"operational\":{\"advanceRequestId\":\"req-43\",\"busCallIds\":[\"call-100\",\"call-101\",\"call-102\"],\"captures\":[{\"afterActions\":1,\"checkpointId\":\"periodic-7\"},{\"afterActions\":2,\"checkpointId\":\"after-rollback-7\"}],\"commitRequestIds\":[{\"agentId\":\"fly-a\",\"requestId\":\"req-44\"},{\"agentId\":\"fly-b\",\"requestId\":\"req-45\"}],\"deliveryIds\":[\"dlv-7\",\"own-9\"],\"prepareRequestIds\":[{\"agentId\":\"fly-a\",\"requestId\":\"req-41\"},{\"agentId\":\"fly-b\",\"requestId\":\"req-42\"}],\"wallTimeNs\":\"1234567890\"}}",
|
||||
"digest": "ae22a2c5e3eb5e65c6ca82c27b2f5242bd94983fca4b11978d7067dc4389d0bb"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,6 +126,11 @@ pub const ENUMS: &[EnumSchema] = &[
|
|||
source: "publishing-v1 3",
|
||||
members: &["lockstep-v1"],
|
||||
},
|
||||
EnumSchema {
|
||||
name: "BoundaryActionKind",
|
||||
source: "step-v1 8",
|
||||
members: crate::trace::BoundaryActionKind::ALL,
|
||||
},
|
||||
EnumSchema {
|
||||
name: "EpisodeRequestKind",
|
||||
source: "workers-v1 4",
|
||||
|
|
@ -1070,6 +1075,11 @@ pub const SCHEMAS: &[TypeSchema] = &[
|
|||
req("outcomeIds", "array<Id>", "task outcome ids in task order"),
|
||||
req("eventIds", "array<Id>", "task event ids in task order"),
|
||||
req("publishedBoundary", "U64", ""),
|
||||
req(
|
||||
"boundaryActions",
|
||||
"array<{kind:BoundaryActionKind,slotId:Id,stateDigest:Digest|null}>",
|
||||
"<= 5, application order: slot saves first (each slot once, digest set), then at most one rollback (no digest)",
|
||||
),
|
||||
],
|
||||
},
|
||||
TypeSchema {
|
||||
|
|
@ -1103,6 +1113,11 @@ pub const SCHEMAS: &[TypeSchema] = &[
|
|||
),
|
||||
req("busCallIds", "array<BusCallId>", "call-<U64>"),
|
||||
req("deliveryIds", "array<OwnerToken>", "dlv-<U64> or own-<U64>"),
|
||||
req(
|
||||
"captures",
|
||||
"array<{checkpointId:Id,afterActions:int}>",
|
||||
"taken order, unique checkpointId; afterActions >= the boundary's slot saves and <= its actions",
|
||||
),
|
||||
],
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -44,6 +44,42 @@ pub struct TraceObservation {
|
|||
pub produced_step: u64,
|
||||
}
|
||||
|
||||
/// The kind of an action taken at the boundary a transition reached, after all of its commits
|
||||
/// (amendment of 2026-09-23, RT-01a).
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum BoundaryActionKind {
|
||||
SaveSlot,
|
||||
Rollback,
|
||||
}
|
||||
|
||||
impl BoundaryActionKind {
|
||||
pub const ALL: &'static [&'static str] = &["save-slot", "rollback"];
|
||||
|
||||
pub fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
BoundaryActionKind::SaveSlot => "save-slot",
|
||||
BoundaryActionKind::Rollback => "rollback",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(s: &str) -> Result<BoundaryActionKind> {
|
||||
match s {
|
||||
"save-slot" => Ok(BoundaryActionKind::SaveSlot),
|
||||
"rollback" => Ok(BoundaryActionKind::Rollback),
|
||||
_ => err("boundary action kind must be save-slot or rollback"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// One boundary action, in the order the coordinator applied it: an `Environment.SaveSlot`
|
||||
/// (with the saved state's digest) or a rollback to a slot (no digest).
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct BoundaryAction {
|
||||
pub kind: BoundaryActionKind,
|
||||
pub slot_id: String,
|
||||
pub state_digest: Option<String>,
|
||||
}
|
||||
|
||||
/// The fields two runs of the same transition must agree on.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct TraceBehaviour {
|
||||
|
|
@ -60,6 +96,9 @@ pub struct TraceBehaviour {
|
|||
/// Task event ids in task order.
|
||||
pub event_ids: Vec<String>,
|
||||
pub published_boundary: u64,
|
||||
/// Slot saves and a rollback at the reached boundary, in application order. Empty for a
|
||||
/// composition without them.
|
||||
pub boundary_actions: Vec<BoundaryAction>,
|
||||
}
|
||||
|
||||
impl TraceBehaviour {
|
||||
|
|
@ -126,6 +165,22 @@ impl DomainType for TraceBehaviour {
|
|||
let outcome_ids = crate::scalar::id_list(&mut f, "outcomeIds", 0, MAX_RATE_ROLES)?;
|
||||
let event_ids = crate::scalar::id_list(&mut f, "eventIds", 0, MAX_RATE_ROLES)?;
|
||||
let published_boundary = f.u64_string("publishedBoundary")?;
|
||||
let boundary_actions = list(&mut f, "boundaryActions", 0, MAX_BOUNDARY_ACTIONS, |v| {
|
||||
let mut a = Fields::new(v, "TraceBehaviour.boundaryActions")?;
|
||||
let kind = BoundaryActionKind::parse(a.string("kind")?)?;
|
||||
let slot_id = a.id("slotId")?;
|
||||
let state_digest = match a.value("stateDigest")? {
|
||||
Value::Null => None,
|
||||
Value::String(d) => Some(d.clone()),
|
||||
_ => return err("stateDigest must be null or a digest"),
|
||||
};
|
||||
a.finish()?;
|
||||
Ok(BoundaryAction {
|
||||
kind,
|
||||
slot_id,
|
||||
state_digest,
|
||||
})
|
||||
})?;
|
||||
f.finish()?;
|
||||
let b = TraceBehaviour {
|
||||
scope,
|
||||
|
|
@ -137,6 +192,7 @@ impl DomainType for TraceBehaviour {
|
|||
outcome_ids,
|
||||
event_ids,
|
||||
published_boundary,
|
||||
boundary_actions,
|
||||
};
|
||||
b.validate()?;
|
||||
Ok(b)
|
||||
|
|
@ -190,6 +246,24 @@ impl DomainType for TraceBehaviour {
|
|||
Value::Array(self.event_ids.iter().map(|i| i.clone().into()).collect()),
|
||||
),
|
||||
("publishedBoundary", u64_json(self.published_boundary)),
|
||||
(
|
||||
"boundaryActions",
|
||||
Value::Array(
|
||||
self.boundary_actions
|
||||
.iter()
|
||||
.map(|a| {
|
||||
obj(vec![
|
||||
("kind", a.kind.as_str().into()),
|
||||
("slotId", a.slot_id.clone().into()),
|
||||
(
|
||||
"stateDigest",
|
||||
a.state_digest.clone().map_or(Value::Null, Value::String),
|
||||
),
|
||||
])
|
||||
})
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
])
|
||||
}
|
||||
|
||||
|
|
@ -244,8 +318,55 @@ impl DomainType for TraceBehaviour {
|
|||
self.outcome_ids.iter().map(String::as_str),
|
||||
"TraceBehaviour.outcomeIds",
|
||||
)?;
|
||||
self.validate_boundary_actions()
|
||||
}
|
||||
}
|
||||
|
||||
/// Boundary actions per transition: every slot at most once, plus one rollback.
|
||||
pub const MAX_BOUNDARY_ACTIONS: usize = crate::extensions::MAX_SLOTS + 1;
|
||||
|
||||
impl TraceBehaviour {
|
||||
/// Slot saves come first, each slot at most once, with the saved state's digest; at most
|
||||
/// one rollback, last, naming a slot and no digest (step-v1 section 6 amendment).
|
||||
fn validate_boundary_actions(&self) -> Result<()> {
|
||||
let mut rolled_back = false;
|
||||
let mut saved: Vec<&str> = Vec::new();
|
||||
for action in &self.boundary_actions {
|
||||
if !is_id(&action.slot_id) {
|
||||
return err("TraceBehaviour: boundary action slotId is not a valid id");
|
||||
}
|
||||
if rolled_back {
|
||||
return err("TraceBehaviour: nothing follows a rollback at the same boundary");
|
||||
}
|
||||
match action.kind {
|
||||
BoundaryActionKind::SaveSlot => {
|
||||
match &action.state_digest {
|
||||
Some(d) if is_digest(d) => {}
|
||||
_ => return err("TraceBehaviour: a slot save records its state digest"),
|
||||
}
|
||||
if saved.contains(&action.slot_id.as_str()) {
|
||||
return err("TraceBehaviour: a slot is saved at most once per boundary");
|
||||
}
|
||||
saved.push(&action.slot_id);
|
||||
}
|
||||
BoundaryActionKind::Rollback => {
|
||||
if action.state_digest.is_some() {
|
||||
return err("TraceBehaviour: a rollback records no state digest");
|
||||
}
|
||||
rolled_back = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// How many leading boundary actions are slot saves.
|
||||
pub fn slot_saves(&self) -> usize {
|
||||
self.boundary_actions
|
||||
.iter()
|
||||
.take_while(|a| a.kind == BoundaryActionKind::SaveSlot)
|
||||
.count()
|
||||
}
|
||||
}
|
||||
|
||||
/// One agent's domain request id for one phase.
|
||||
|
|
@ -267,6 +388,18 @@ pub struct TraceOperational {
|
|||
/// these and nothing in [`TraceBehaviour`].
|
||||
pub bus_call_ids: Vec<BusCallId>,
|
||||
pub delivery_ids: Vec<OwnerToken>,
|
||||
/// Checkpoint captures (and FLYSIM01 exports) taken at the reached boundary, each with the
|
||||
/// number of boundary actions already applied when it was taken. Operational because a
|
||||
/// capture's schedule is wall-clock policy; the ordering rule against slot saves is checked
|
||||
/// by [`TransitionTrace`] (amendment of 2026-09-23, legacy-gameboy-v1 section 16).
|
||||
pub captures: Vec<TraceCapture>,
|
||||
}
|
||||
|
||||
/// One checkpoint capture at the reached boundary.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct TraceCapture {
|
||||
pub checkpoint_id: String,
|
||||
pub after_actions: u64,
|
||||
}
|
||||
|
||||
impl DomainType for TraceOperational {
|
||||
|
|
@ -296,6 +429,16 @@ impl DomainType for TraceOperational {
|
|||
Some(s) => OwnerToken::parse(s),
|
||||
None => err("every deliveryId must be a string"),
|
||||
})?;
|
||||
let captures = list(&mut f, "captures", 0, MAX_BOUNDARY_ACTIONS + 1, |v| {
|
||||
let mut c = Fields::new(v, "TraceOperational.captures")?;
|
||||
let checkpoint_id = c.id("checkpointId")?;
|
||||
let after_actions = c.int("afterActions", 0, MAX_BOUNDARY_ACTIONS as u64)?;
|
||||
c.finish()?;
|
||||
Ok(TraceCapture {
|
||||
checkpoint_id,
|
||||
after_actions,
|
||||
})
|
||||
})?;
|
||||
f.finish()?;
|
||||
let o = TraceOperational {
|
||||
wall_time_ns,
|
||||
|
|
@ -304,6 +447,7 @@ impl DomainType for TraceOperational {
|
|||
commit_request_ids,
|
||||
bus_call_ids,
|
||||
delivery_ids,
|
||||
captures,
|
||||
};
|
||||
o.validate()?;
|
||||
Ok(o)
|
||||
|
|
@ -341,6 +485,20 @@ impl DomainType for TraceOperational {
|
|||
.collect(),
|
||||
),
|
||||
),
|
||||
(
|
||||
"captures",
|
||||
Value::Array(
|
||||
self.captures
|
||||
.iter()
|
||||
.map(|c| {
|
||||
obj(vec![
|
||||
("checkpointId", c.checkpoint_id.clone().into()),
|
||||
("afterActions", Value::from(c.after_actions)),
|
||||
])
|
||||
})
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
])
|
||||
}
|
||||
|
||||
|
|
@ -361,6 +519,17 @@ impl DomainType for TraceOperational {
|
|||
self.delivery_ids.iter().map(OwnerToken::as_str),
|
||||
"TraceOperational.deliveryIds",
|
||||
)?;
|
||||
require_unique(
|
||||
self.captures.iter().map(|c| c.checkpoint_id.as_str()),
|
||||
"TraceOperational.captures",
|
||||
)?;
|
||||
let mut last = 0;
|
||||
for capture in &self.captures {
|
||||
if capture.after_actions < last {
|
||||
return err("TraceOperational: captures are recorded in the order they were taken");
|
||||
}
|
||||
last = capture.after_actions;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -412,6 +581,9 @@ impl TransitionTrace {
|
|||
if a.event_ids != b.event_ids {
|
||||
out.push("eventIds differ".to_owned());
|
||||
}
|
||||
if a.boundary_actions != b.boundary_actions {
|
||||
out.push("boundaryActions differ".to_owned());
|
||||
}
|
||||
let ids_a: Vec<&str> = a.agents.iter().map(|x| x.agent_id.as_str()).collect();
|
||||
let ids_b: Vec<&str> = b.agents.iter().map(|x| x.agent_id.as_str()).collect();
|
||||
if ids_a != ids_b {
|
||||
|
|
@ -481,6 +653,25 @@ impl DomainType for TransitionTrace {
|
|||
}
|
||||
}
|
||||
}
|
||||
// A slot save due at a boundary completes before any capture at that boundary, so a
|
||||
// checkpoint never pairs a task ledger that names the new slot with the old slot
|
||||
// contents (legacy-gameboy-v1 section 16, review round 1 of 2026-09-23).
|
||||
let saves = self.behaviour.slot_saves() as u64;
|
||||
let actions = self.behaviour.boundary_actions.len() as u64;
|
||||
for capture in &self.operational.captures {
|
||||
if capture.after_actions < saves {
|
||||
return err(format!(
|
||||
"TransitionTrace: capture {:?} was taken before this boundary's slot saves completed",
|
||||
capture.checkpoint_id
|
||||
));
|
||||
}
|
||||
if capture.after_actions > actions {
|
||||
return err(format!(
|
||||
"TransitionTrace: capture {:?} counts more boundary actions than were applied",
|
||||
capture.checkpoint_id
|
||||
));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2659,6 +2659,8 @@ impl Coordinator {
|
|||
outcome_ids,
|
||||
event_ids: event_ids.to_vec(),
|
||||
published_boundary: k + 1,
|
||||
// The synthetic composition takes no boundary actions (step-v1 section 8 amendment).
|
||||
boundary_actions: Vec::new(),
|
||||
};
|
||||
let operational = TraceOperational {
|
||||
// Wall time is for pacing, health and presentation only.
|
||||
|
|
@ -2673,6 +2675,9 @@ impl Coordinator {
|
|||
// and nothing in the behaviour above.
|
||||
bus_call_ids: Vec::new(),
|
||||
delivery_ids: Vec::new(),
|
||||
// Captures are recorded by the store path, not by the transition that reached the
|
||||
// boundary; the synthetic trace records none.
|
||||
captures: Vec::new(),
|
||||
};
|
||||
self.trace.transition(TransitionTrace { behaviour, operational });
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue