Make large G-code loading and execution robust

This commit is contained in:
2026-08-30 17:42:54 +08:00
parent 1a92d3b5b8
commit c015709d26
4 changed files with 19 additions and 6 deletions

View File

@@ -56,7 +56,13 @@ export class OperationLedger {
entry.phase = "verified";
entry.status = response?.payload?.status === "error" || response?.kind === "ERROR" ? "failed" : "verified";
entry.result_hash = fnv1a64(response?.payload ?? {});
entry.response = clone(response);
const payload = response?.payload;
// High-frequency fixed-tick responses are deltas. Keep only the compact
// operation evidence in the ledger; the full delta is already delivered
// to the client and retained by the frontend trace window.
entry.response = payload?.snapshot_mode === "motion_delta"
? { ...response, payload: { status: payload.status, snapshot_mode: payload.snapshot_mode, simulation_tick: response.simulation_tick ?? null, program: payload.program ? { current_line: payload.program.current_line, program_status: payload.program.program_status, state_hash: payload.program.state_hash } : null } }
: clone(response);
return clone(entry);
}

View File

@@ -45,11 +45,13 @@ export class XyzacCommandLedger extends OperationLedger {
return { status: "reconcile_required", operation_id: operationId, retry_allowed: false, reconciliation };
}
audit({ includeResponses = true } = {}) {
audit({ includeResponses = true, maxEntries = Number.POSITIVE_INFINITY } = {}) {
const exported = super.export();
const pending = this.pending();
const entries = includeResponses ? exported.entries : exported.entries.map((entry) => { const { response, ...summary } = entry; return summary; });
const unsigned = { schema: XYZAC_COMMAND_LEDGER_SCHEMA, operation_schema: LEDGER_SCHEMA, phases: [...LEDGER_PHASES], scope: this.scope, entries, pending_count: pending.length };
const totalEntries = exported.entries.length;
const windowed = Number.isFinite(maxEntries) && maxEntries >= 0 ? exported.entries.slice(-Math.floor(maxEntries)) : exported.entries;
const entries = includeResponses ? windowed : windowed.map((entry) => { const { response, ...summary } = entry; return summary; });
const unsigned = { schema: XYZAC_COMMAND_LEDGER_SCHEMA, operation_schema: LEDGER_SCHEMA, phases: [...LEDGER_PHASES], scope: this.scope, entries, entry_count: totalEntries, truncated: entries.length < totalEntries, pending_count: pending.length };
return { ...unsigned, state_hash: fnv1a64(unsigned) };
}
}

View File

@@ -34,7 +34,7 @@ export class XyzacSession extends SimSession {
// every previous response inside the stored response object.
const payload = { ...response.payload };
payload.xyzac_session = this.authority();
payload.xyzac_ledger = this.ledger.audit({ includeResponses: input.kind !== "SIM_STEP" });
payload.xyzac_ledger = this.ledger.audit({ includeResponses: input.kind !== "SIM_STEP", maxEntries: input.kind === "SIM_STEP" ? 32 : 2048 });
payload.xyzac_scheduler = this.scheduler.export();
return { ...response, payload };
}