fix(model): retain resolved GGUF alignment under cancellation

Publish alignment from the parser when explicit metadata validates it, or when metadata completion establishes the default. Preserve that fact through later parsing and hashing failures.

Fixes #6579
This commit is contained in:
morluto committed 2026-10-23 18:07:45 +08:00
1 parent b6833b9f61
commit 275095a9c6
4 files changed
+197 -95

No files matched your search

+4 -1
View File
@@ -44,7 +44,10 @@ that defeats filesystem metadata checks.
GGUF reports version, byte order, alignment, typed metadata, and each tensor's
name, original type ID, dimensions, relative data offset, file offset and derived
byte length. Alignment accepts every positive UINT32 multiple of eight, including
non-powers of two. Metadata keys use ASCII lower-snake-case hierarchy components;
non-powers of two. Partial Evidence retains explicit alignment once validated;
the default alignment becomes known after metadata completes. Cancellation
during tensor parsing or hashing retains that fact without claiming finalized
digests or file identity. Metadata keys use ASCII lower-snake-case hierarchy components;
standard numeric components such as `general.base_model.0.name` are preserved.
Scalar metadata is complete. Arrays have declared element types,
counts and at most eight preview elements per array, with an explicit
+3
View File
@@ -42,6 +42,7 @@ export interface GgufProgress {
declared_tensor_count: number;
}): void;
onMetadata(row: ModelMetadata): void;
onAlignment(alignment: number): void;
onMetadataComplete(): void;
onTensorsStarted(): void;
onTensorDeclaration(row: ModelArtifactPartialTensor): void;
@@ -318,10 +319,12 @@ export class GgufHeader {
"GGUF general.alignment must be a positive UINT32 multiple of eight",
);
alignment = parsed.value;
progress?.onAlignment(alignment);
}
metadata.push(row);
progress?.onMetadata(row);
}
if (!keys.has("general.alignment")) progress?.onAlignment(alignment);
progress?.onMetadataComplete();
progress?.onTensorsStarted();
const tensors: ModelArtifactPartialTensor[] = [];
+3
View File
@@ -322,6 +322,9 @@ export class ModelArtifactProvider implements ModelArtifactPort {
partial.coverage.metadata = "partial";
},
onMetadata: (row) => partial?.metadata.push(row),
onAlignment: (alignment) => {
if (partial !== undefined) partial.alignment = alignment;
},
onMetadataComplete: () => {
if (partial !== undefined) partial.coverage.metadata = "complete";
},
@@ -7,12 +7,15 @@ import { parseEvidence } from "../../../src/domain/evidence.js";
import { projectAnalysisError } from "../../../src/domain/analysisErrorProjection.js";
import { ggufFixture } from "../../fixtures/model/model.js";
const cancelledArrayFixture = () => {
const cancelledArrayFixture = (alignment?: number) => {
const seed = ggufFixture();
const count = 200_000;
const fixture = ggufFixture({
tensors: [],
metadata: [
...(alignment === undefined
? []
: [{ key: "general.alignment", type: 4, value: seed.u32(alignment) }]),
{ key: "general.name", type: 8, value: seed.text("First row") },
{
key: "custom.bools",
@@ -28,103 +31,105 @@ const cancelledArrayFixture = () => {
return {
fixture,
count,
arrayStart:
24 +
8 +
Buffer.byteLength("general.name") +
4 +
8 +
Buffer.byteLength("First row") +
8 +
Buffer.byteLength("custom.bools") +
4 +
4 +
8,
arrayStart: fixture.header.length - count,
};
};
it("retains completed GGUF rows when cancellation interrupts a later value", async () => {
const root = await mkdtemp(join(tmpdir(), "rea-model-partial-cancel-"));
const path = join(root, "model.gguf");
const { fixture, count, arrayStart } = cancelledArrayFixture();
await writeFile(path, fixture.bytes);
const sample = await open(path, "r");
const handlePrototype = Object.getPrototypeOf(sample) as {
read: (
buffer: Buffer,
offset: number,
length: number,
position: number,
) => Promise<{ bytesRead: number }>;
};
await sample.close();
const originalRead = handlePrototype.read;
const controller = new AbortController();
const reason = { marker: "caller-selected-parser-cancel" };
let arrayBytesObserved = 0;
const readSpy = vi
.spyOn(handlePrototype, "read")
.mockImplementation(async function (
this: unknown,
buffer: Buffer,
offset: number,
length: number,
position: number,
) {
const result = await originalRead.call(
this,
buffer,
offset,
length,
position,
it.each([undefined, 64])(
"retains completed GGUF facts when cancellation interrupts a later value (alignment=%s)",
async (alignment) => {
const root = await mkdtemp(join(tmpdir(), "rea-model-partial-cancel-"));
const path = join(root, "model.gguf");
const { fixture, count, arrayStart } = cancelledArrayFixture(alignment);
await writeFile(path, fixture.bytes);
const sample = await open(path, "r");
const handlePrototype = Object.getPrototypeOf(sample) as {
read: (
buffer: Buffer,
offset: number,
length: number,
position: number,
) => Promise<{ bytesRead: number }>;
};
await sample.close();
const originalRead = handlePrototype.read;
const controller = new AbortController();
const reason = { marker: "caller-selected-parser-cancel" };
let arrayBytesObserved = 0;
const readSpy = vi
.spyOn(handlePrototype, "read")
.mockImplementation(async function (
this: unknown,
buffer: Buffer,
offset: number,
length: number,
position: number,
) {
const result = await originalRead.call(
this,
buffer,
offset,
length,
position,
);
if (position === arrayStart && result.bytesRead > 0) {
arrayBytesObserved = result.bytesRead;
controller.abort(reason);
}
return result;
});
const provider = new ModelArtifactProvider();
try {
const result = await provider.inspect(
{ path, hash: "header" },
{ signal: controller.signal },
);
if (position === arrayStart && result.bytesRead > 0) {
arrayBytesObserved = result.bytesRead;
controller.abort(reason);
}
return result;
});
const provider = new ModelArtifactProvider();
try {
const result = await provider.inspect(
{ path, hash: "header" },
{ signal: controller.signal },
);
if (result.ok) throw new Error("Expected parser cancellation");
expect(arrayBytesObserved).toBeGreaterThan(0);
expect(arrayBytesObserved).toBeLessThan(count);
expect(result.error.cause).toBe(reason);
const evidence = parseEvidence(result.error.partialObservation);
expect(evidence.subject).toBeNull();
expect(evidence.operation).toBe("inspect_model_artifact");
expect(evidence.normalized_result).toMatchObject({
kind: "model-artifact-partial",
artifact: {
path,
header_sha256: null,
sha256: null,
file_identity: "unverified",
},
coverage: {
header: "partial",
metadata: "partial",
tensors: "not-started",
},
metadata: [{ index: 0, key: "general.name", value: "First row" }],
tensors: [],
});
const projected = projectAnalysisError(result.error);
if (projected.details === undefined)
throw new Error("Projected error omitted its partial observation");
expect(parseEvidence(projected.details.partial_observation)).toEqual(
evidence,
);
} finally {
readSpy.mockRestore();
await provider.close();
await rm(root, { recursive: true, force: true });
}
});
if (result.ok) throw new Error("Expected parser cancellation");
expect(arrayBytesObserved).toBeGreaterThan(0);
expect(arrayBytesObserved).toBeLessThan(count);
expect(result.error.cause).toBe(reason);
const evidence = parseEvidence(result.error.partialObservation);
expect(evidence.subject).toBeNull();
expect(evidence.operation).toBe("inspect_model_artifact");
expect(evidence.normalized_result).toMatchObject({
kind: "model-artifact-partial",
alignment: alignment ?? null,
artifact: {
path,
header_sha256: null,
sha256: null,
file_identity: "unverified",
},
coverage: {
header: "partial",
metadata: "partial",
tensors: "not-started",
},
metadata: [
...(alignment === undefined
? []
: [{ index: 0, key: "general.alignment", value: alignment }]),
{
index: alignment === undefined ? 0 : 1,
key: "general.name",
value: "First row",
},
],
tensors: [],
});
const projected = projectAnalysisError(result.error);
if (projected.details === undefined)
throw new Error("Projected error omitted its partial observation");
expect(parseEvidence(projected.details.partial_observation)).toEqual(
evidence,
);
} finally {
readSpy.mockRestore();
await provider.close();
await rm(root, { recursive: true, force: true });
}
},
);
it("retains completed GGUF tensor declarations before later tensor bytes cancel", async () => {
const root = await mkdtemp(join(tmpdir(), "rea-model-tensor-partial-"));
@@ -210,6 +215,7 @@ it("retains completed GGUF tensor declarations before later tensor bytes cancel"
});
expect(partial.tensors).toEqual([]);
expect(partial.coverage.tensors).toBe("partial");
expect(evidence.normalized_result).toMatchObject({ alignment: 32 });
expect(partial.artifact).toMatchObject({
path,
header_sha256: null,
@@ -222,3 +228,90 @@ it("retains completed GGUF tensor declarations before later tensor bytes cancel"
await rm(root, { recursive: true, force: true });
}
});
it.each([32, 64])(
"retains resolved GGUF alignment %s when full hashing is cancelled",
async (alignment) => {
const root = await mkdtemp(join(tmpdir(), "rea-model-hash-cancel-"));
const path = join(root, "model.gguf");
const fixture = ggufFixture({
...(alignment === 32 ? {} : { alignment }),
tensors: [
{
name: "weight",
type: 0,
shape: [524288n],
offset: 0n,
bytes: 2 * 1024 * 1024,
},
],
});
await writeFile(path, fixture.bytes);
const sample = await open(path, "r");
const prototype = Object.getPrototypeOf(sample) as {
read: (
buffer: Buffer,
offset: number,
length: number,
position: number,
) => Promise<{ bytesRead: number }>;
};
await sample.close();
const originalRead = prototype.read;
const controller = new AbortController();
const reason = { marker: "cancel-during-full-model-hash" };
let payloadRead = false;
const readSpy = vi
.spyOn(prototype, "read")
.mockImplementation(async function (
this: unknown,
buffer: Buffer,
offset: number,
length: number,
position: number,
) {
const result = await originalRead.call(
this,
buffer,
offset,
length,
position,
);
if (position >= fixture.header.length && result.bytesRead > 0) {
payloadRead = true;
controller.abort(reason);
}
return result;
});
const provider = new ModelArtifactProvider();
try {
const result = await provider.inspect(
{ path, hash: "full" },
{ signal: controller.signal },
);
if (result.ok) throw new Error("Expected full-hash cancellation");
expect(payloadRead).toBe(true);
expect(result.error.cause).toBe(reason);
expect(
parseEvidence(result.error.partialObservation).normalized_result,
).toMatchObject({
kind: "model-artifact-partial",
alignment,
coverage: {
header: "complete",
metadata: "complete",
tensors: "complete",
},
artifact: {
sha256: null,
header_sha256: null,
file_identity: "unverified",
},
});
} finally {
readSpy.mockRestore();
await provider.close();
await rm(root, { recursive: true, force: true });
}
},
);