fix(evidence): enforce the combined record limit
This commit is contained in:
commit
c7918024bc
|
|
@ -62,7 +62,12 @@ export class EvidenceLedger {
|
|||
? ok("duplicate")
|
||||
: err(new EvidenceIntegrityError("Conflicting evidence record"));
|
||||
}
|
||||
if (this.#records.size >= this.limits.maxRecords)
|
||||
if (
|
||||
this.#exceedsRecordLimit(
|
||||
this.#records.size + 1,
|
||||
this.#unknownRevisions.size,
|
||||
)
|
||||
)
|
||||
return err(new EvidenceLimitError("records", this.limits.maxRecords));
|
||||
const bytes = serializedBytes(evidence);
|
||||
if (this.#bytes + bytes > this.limits.maxBytes)
|
||||
|
|
@ -344,7 +349,7 @@ export class EvidenceLedger {
|
|||
number,
|
||||
EvidenceIntegrityError | EvidenceLimitError | UnknownRegistryError
|
||||
> {
|
||||
if (records.size + unknowns.size > this.limits.maxRecords)
|
||||
if (this.#exceedsRecordLimit(records.size, unknowns.size))
|
||||
return err(new EvidenceLimitError("records", this.limits.maxRecords));
|
||||
const bytes =
|
||||
[...records.values()].reduce(
|
||||
|
|
@ -367,6 +372,10 @@ export class EvidenceLedger {
|
|||
return ok(bytes);
|
||||
}
|
||||
|
||||
#exceedsRecordLimit(recordCount: number, unknownCount: number): boolean {
|
||||
return recordCount + unknownCount > this.limits.maxRecords;
|
||||
}
|
||||
|
||||
#commit(
|
||||
records: ReadonlyMap<string, Evidence>,
|
||||
unknowns: ReadonlyMap<string, ResidualUnknown>,
|
||||
|
|
|
|||
|
|
@ -204,6 +204,47 @@ describe("analysis evidence", () => {
|
|||
expect(byteBound.export().records).toEqual([]);
|
||||
});
|
||||
|
||||
it("counts unknown revisions when enforcing direct record limits", () => {
|
||||
const ledger = new EvidenceLedger({
|
||||
maxRecords: 2,
|
||||
maxBytes: 1_000_000,
|
||||
});
|
||||
const mutation = createEvidence(undefined, PROVIDER, {
|
||||
predicateType: "rea.residual-unknown-mutation/v1",
|
||||
operation: "record_unknown",
|
||||
parameters: {},
|
||||
result: { action: "record" },
|
||||
});
|
||||
const unknown = recordUnknownInputSchema.parse({
|
||||
approved: true,
|
||||
question: "What remains unresolved?",
|
||||
severity: "high",
|
||||
domain: "record-limit-test",
|
||||
supporting_evidence_ids: [],
|
||||
contradicting_evidence_ids: [],
|
||||
required_authority: "shipped-artifact",
|
||||
required_confidence: "observed",
|
||||
required_environment: null,
|
||||
recommended_probes: [],
|
||||
relationships: [],
|
||||
});
|
||||
expect(ledger.recordUnknown(unknown, mutation).ok).toBe(true);
|
||||
|
||||
const direct = createEvidence(TARGET, PROVIDER, {
|
||||
operation: "health",
|
||||
parameters: {},
|
||||
result: true,
|
||||
});
|
||||
expect(ledger.record(direct)).toMatchObject({
|
||||
ok: false,
|
||||
error: { _tag: "EvidenceLimitError", limit: "records", maximum: 2 },
|
||||
});
|
||||
expect(ledger.export()).toMatchObject({
|
||||
records: [mutation],
|
||||
unknowns: [expect.objectContaining({ domain: "record-limit-test" })],
|
||||
});
|
||||
});
|
||||
|
||||
it("derives byte-stable manifests independent of record insertion order", () => {
|
||||
const artifactEvidence = createEvidence(TARGET, PROVIDER, {
|
||||
operation: "health",
|
||||
|
|
|
|||
Loading…
Reference in New Issue