/*
RFC-0715/RFC-0871: unit tests for nachweis.key.ensure, nachweis.sign, nachweis.timestamp, nachweis.verify-signature, and N3 gate in nachweis.approve.
- Not a contract source of truth — the module under test owns the authoritative behavior; fixtures are minimal scaffolding only.
- RFC-0715: initial N3 crypto verification unit tests.
- RFC-0871: add tests for timestamp assurance, legacy projection, and qualification evidence validation.
*/
import { test, expect, beforeEach, afterEach } from "vitest";
import fs from "node:fs/promises";
import { existsSync, mkdirSync } from "node:fs";
import path from "node:path";
import os from "node:os";
import { canonicalBytes } from "@warpgogol/werkstatt-engine/signing";
import { getPublicKey } from "@warpgogol/werkstatt-engine/signing";
import type { KernelCommandInput, KernelRuntimeContext } from "@warpgogol/werkstatt-engine/kernel";
import type { BordbuchEntry } from "@warpgogol/werkstatt-engine/schemas";
import { computeEntryHash } from "../bordbuch/bordbuch-io.ts";
import { runNachweisKeyEnsure, ensureNachweisKey } from "./nachweis-key-ensure.ts";
import { runNachweisSign } from "./nachweis-sign.ts";
import { runNachweisTimestamp } from "./nachweis-timestamp.ts";
import { runNachweisVerifySignature } from "./nachweis-verify-signature.ts";
import { runNachweisApprove } from "./nachweis-approve.ts";
import { createDefaultIO } from "@warpgogol/werkstatt-shared/kernel/workspace-io";
let tmpDir: string;
const systemId = "test-system";
function mockContext(workspaceRoot: string): KernelRuntimeContext {
return {
io: createDefaultIO().io,
workspaceRoot,
logger: {
info: () => {},
success: () => {},
error: () => {},
warn: () => {},
event: () => {},
getEvents: () => [],
},
} as unknown as KernelRuntimeContext;
}
function makeInput(flags: Record): KernelCommandInput {
return {
commandName: "nachweis.test",
flags,
} as unknown as KernelCommandInput;
}
function makeEntry(
overrides: Partial &
Pick,
prevHash: string | null,
): BordbuchEntry {
const base: Omit = {
schemaVersion: "1.0.0",
id: overrides.id,
systemId,
occurredAt: overrides.occurredAt,
kind: overrides.kind,
status: "done",
missionId: overrides.missionId,
releaseId: null,
actor: "agent",
summary: overrides.summary,
previousHash: prevHash,
metadata: overrides.metadata,
};
const hash = computeEntryHash(base);
return { ...base, hash };
}
async function writeBordbuch(entries: BordbuchEntry[]): Promise {
const cacheDir = path.join(tmpDir, "..", "systems-cache", systemId);
const bordbuchDir = path.join(cacheDir, "bordbuch");
if (!existsSync(bordbuchDir)) mkdirSync(bordbuchDir, { recursive: true });
const ndjson = entries.map((e) => JSON.stringify(e)).join("\n") + "\n";
await fs.writeFile(path.join(bordbuchDir, "events.ndjson"), ndjson, "utf8");
}
async function readBordbuchFile(): Promise {
const filePath = path.join(tmpDir, "..", "systems-cache", systemId, "bordbuch", "events.ndjson");
if (!existsSync(filePath)) return [];
const raw = await fs.readFile(filePath, "utf8");
const lines = raw.split("\n").filter((l) => l.trim().length > 0);
return lines.map((l) => JSON.parse(l) as BordbuchEntry);
}
async function writeEntitlements(): Promise {
const cacheDir = path.join(tmpDir, "..", "systems-cache", systemId);
const srcDir = path.join(cacheDir, "src");
if (!existsSync(srcDir)) mkdirSync(srcDir, { recursive: true });
const { stringify: yamlStringify } = await import("yaml");
await fs.writeFile(
path.join(srcDir, "entitlements.generated.yaml"),
yamlStringify({ features: ["nachweis"] }),
"utf8",
);
}
async function writeEvidenceSource(
slug: string,
overrides: Record = {},
): Promise {
const cacheDir = path.join(tmpDir, "..", "systems-cache", systemId);
const evidenceDir = path.join(
cacheDir,
"src",
"content",
"business-profile",
"de",
"trust",
"evidence",
);
if (!existsSync(evidenceDir)) mkdirSync(evidenceDir, { recursive: true });
const frontmatter = {
recordId: `nr_${slug}`,
slug,
kind: "client-statement",
name: `Test Evidence ${slug}`,
items: {
source: { sha256: "sha256:abc123", storage: "public" },
},
...overrides,
};
const md = `---\n${Object.entries(frontmatter)
.map(([k, v]) => `${k}: ${typeof v === "object" ? JSON.stringify(v) : v}`)
.join("\n")}\n---\n\nTest evidence content.\n`;
await fs.writeFile(path.join(evidenceDir, `${slug}.md`), md, "utf8");
}
async function writeSystemMd(): Promise {
const cacheDir = path.join(tmpDir, "..", "systems-cache", systemId);
const contentDir = path.join(cacheDir, "src", "content");
if (!existsSync(contentDir)) mkdirSync(contentDir, { recursive: true });
const systemMd =
"---\napp: test-app\nversion: 1.0.0\nidentity:\n systemStar: test\n biome: default\ni18n:\n default: de\n supported:\n de: true\n---\n\n# Test System\n";
await fs.writeFile(path.join(contentDir, "system.md"), systemMd, "utf8");
}
let testRoot: string;
beforeEach(async () => {
testRoot = await fs.mkdtemp(path.join(os.tmpdir(), "nachweis-n3-test-"));
tmpDir = path.join(testRoot, "workspace");
await fs.mkdir(tmpDir, { recursive: true });
await writeEntitlements();
await writeSystemMd();
});
afterEach(async () => {
await fs.rm(testRoot, { recursive: true, force: true });
});
// ---------------------------------------------------------------------------
// nachweis.key.ensure
// ---------------------------------------------------------------------------
test("nachweis.key.ensure generates an Ed25519 keypair and writes private + public key files", async () => {
const keyFile = path.join(tmpDir, "test-signing.key");
const result = await runNachweisKeyEnsure(
makeInput({ "key-file": keyFile }),
mockContext(tmpDir),
);
expect(result.exitCode).toBe(0);
expect(result.data!.publicKeyHex).toMatch(/^[0-9a-f]{64}$/);
expect(result.data!.keyId).toMatch(/^[0-9a-f]{64}$/);
expect(existsSync(keyFile)).toBe(true);
expect(existsSync(`${keyFile}.pub`)).toBe(true);
const privKeyHex = (await fs.readFile(keyFile, "utf8")).trim();
expect(privKeyHex).toMatch(/^[0-9a-f]{64}$/);
const pubKeyHex = (await fs.readFile(`${keyFile}.pub`, "utf8")).trim();
expect(pubKeyHex).toBe(result.data!.publicKeyHex);
});
test("nachweis.key.ensure refuses to overwrite existing key without --force", async () => {
const keyFile = path.join(tmpDir, "test-signing.key");
await fs.writeFile(keyFile, "existing", "utf8");
await expect(
runNachweisKeyEnsure(makeInput({ "key-file": keyFile }), mockContext(tmpDir)),
).rejects.toThrow("KEY_FILE_EXISTS");
});
test("nachweis.key.ensure overwrites with --force", async () => {
const keyFile = path.join(tmpDir, "test-signing.key");
await fs.writeFile(keyFile, "existing", "utf8");
const result = await runNachweisKeyEnsure(
makeInput({ "key-file": keyFile, force: true }),
mockContext(tmpDir),
);
expect(result.exitCode).toBe(0);
const privKeyHex = (await fs.readFile(keyFile, "utf8")).trim();
expect(privKeyHex).toMatch(/^[0-9a-f]{64}$/);
});
test("ensureNachweisKey produces a valid Ed25519 keypair", async () => {
const keyFile = path.join(tmpDir, "test-signing.key");
const result = await ensureNachweisKey(keyFile, false);
const privKeyHex = (await fs.readFile(keyFile, "utf8")).trim();
const privKeyBytes = new Uint8Array(Buffer.from(privKeyHex, "hex"));
const pubKeyBytes = await getPublicKey(privKeyBytes);
const pubKeyHex = Buffer.from(pubKeyBytes).toString("hex");
expect(pubKeyHex).toBe(result.publicKeyHex);
});
// ---------------------------------------------------------------------------
// nachweis.sign
// ---------------------------------------------------------------------------
test("nachweis.sign signs a record and appends nachweis-signed Bordbuch entry", async () => {
const slug = "test-evidence";
await writeEvidenceSource(slug);
const keyFile = path.join(tmpDir, "test-signing.key");
await ensureNachweisKey(keyFile, false);
const result = await runNachweisSign(
makeInput({ system: systemId, slug, "key-file": keyFile }),
mockContext(tmpDir),
);
expect(result.exitCode).toBe(0);
expect(result.data!.slug).toBe(slug);
expect(result.data!.signatureHex).toMatch(/^[0-9a-f]{128}$/);
expect(result.data!.publicKeyHex).toMatch(/^[0-9a-f]{64}$/);
expect(result.data!.bordbuchEventId).not.toBeNull();
expect(result.data!.idempotent).toBe(false);
const entries = await readBordbuchFile();
const signedEntry = entries.find((e) => e.kind === "nachweis-signed");
expect(signedEntry).toBeDefined();
expect(signedEntry!.metadata?.slug).toBe(slug);
expect(signedEntry!.metadata?.signatureHex).toBe(result.data!.signatureHex);
});
test("nachweis.sign is idempotent — re-running returns the same bordbuch event", async () => {
const slug = "test-evidence";
await writeEvidenceSource(slug);
const keyFile = path.join(tmpDir, "test-signing.key");
await ensureNachweisKey(keyFile, false);
const input = makeInput({ system: systemId, slug, "key-file": keyFile });
const result1 = await runNachweisSign(input, mockContext(tmpDir));
const result2 = await runNachweisSign(input, mockContext(tmpDir));
expect(result2.data!.idempotent).toBe(true);
expect(result2.data!.bordbuchEventId).toBe(result1.data!.bordbuchEventId);
});
test("nachweis.sign fails when key file does not exist", async () => {
const slug = "test-evidence";
await writeEvidenceSource(slug);
await expect(
runNachweisSign(
makeInput({ system: systemId, slug, "key-file": "/nonexistent/key" }),
mockContext(tmpDir),
),
).rejects.toThrow("KEY_NOT_FOUND");
});
test("nachweis.sign fails when evidence-source not found", async () => {
const keyFile = path.join(tmpDir, "test-signing.key");
await ensureNachweisKey(keyFile, false);
await expect(
runNachweisSign(
makeInput({ system: systemId, slug: "nonexistent", "key-file": keyFile }),
mockContext(tmpDir),
),
).rejects.toThrow("NOT_FOUND");
});
test("canonicalBytes is deterministic", () => {
const payload = {
recordId: "nr_test_20260101",
slug: "test",
kind: "client-statement",
name: "Test",
items: { a: 1, b: 2 },
};
const bytes1 = canonicalBytes(payload);
const bytes2 = canonicalBytes({ ...payload, items: { b: 2, a: 1 } });
expect(Buffer.from(bytes1).toString("hex")).toBe(Buffer.from(bytes2).toString("hex"));
});
// ---------------------------------------------------------------------------
// nachweis.timestamp
// ---------------------------------------------------------------------------
test("nachweis.timestamp fails with SIGNATURE_NOT_FOUND when no nachweis-signed entry exists", async () => {
const slug = "test-evidence";
await writeEvidenceSource(slug);
await expect(
runNachweisTimestamp(makeInput({ system: systemId, slug }), mockContext(tmpDir)),
).rejects.toThrow("SIGNATURE_NOT_FOUND");
});
test("nachweis.timestamp dry-run returns TSA URL without querying", async () => {
const slug = "test-evidence";
await writeEvidenceSource(slug);
const keyFile = path.join(tmpDir, "test-signing.key");
await ensureNachweisKey(keyFile, false);
await runNachweisSign(
makeInput({ system: systemId, slug, "key-file": keyFile }),
mockContext(tmpDir),
);
const result = await runNachweisTimestamp(
makeInput({ system: systemId, slug, "dry-run": true }),
mockContext(tmpDir),
);
expect(result.exitCode).toBe(0);
expect(result.data!.tsaUrl).toBe("https://freetsa.org/tsr");
expect(result.data!.timestampTokenBase64).toBe("");
expect(result.data!.idempotent).toBe(false);
});
// ---------------------------------------------------------------------------
// nachweis.verify-signature
// ---------------------------------------------------------------------------
test("nachweis.verify-signature validates a correct signature", async () => {
const slug = "test-evidence";
await writeEvidenceSource(slug);
const keyFile = path.join(tmpDir, "test-signing.key");
await ensureNachweisKey(keyFile, false);
await runNachweisSign(
makeInput({ system: systemId, slug, "key-file": keyFile }),
mockContext(tmpDir),
);
const result = await runNachweisVerifySignature(
makeInput({ system: systemId, slug }),
mockContext(tmpDir),
);
expect(result.exitCode).toBe(0);
expect(result.data!.signatureValid).toBe(true);
expect(result.data!.timestampVerified).toBe(false);
expect(result.data!.publicKeyHex).toMatch(/^[0-9a-f]{64}$/);
});
test("nachweis.verify-signature fails when no signature exists", async () => {
const slug = "test-evidence";
await writeEvidenceSource(slug);
const result = await runNachweisVerifySignature(
makeInput({ system: systemId, slug }),
mockContext(tmpDir),
);
expect(result.exitCode).toBe(1);
expect(result.data!.signatureValid).toBe(false);
expect(result.data!.details).toContain("No nachweis-signed");
});
test("nachweis.verify-signature detects tampered evidence", async () => {
const slug = "test-evidence";
await writeEvidenceSource(slug);
const keyFile = path.join(tmpDir, "test-signing.key");
await ensureNachweisKey(keyFile, false);
await runNachweisSign(
makeInput({ system: systemId, slug, "key-file": keyFile }),
mockContext(tmpDir),
);
// Tamper with the evidence source after signing
await writeEvidenceSource(slug, { name: "Tampered Name" });
const result = await runNachweisVerifySignature(
makeInput({ system: systemId, slug }),
mockContext(tmpDir),
);
expect(result.exitCode).toBe(1);
expect(result.data!.signatureValid).toBe(false);
});
// ---------------------------------------------------------------------------
// N3 gate in nachweis.approve
// ---------------------------------------------------------------------------
test("nachweis.approve --verification-level N3 fails with N3_GATE_FAILED when signature is missing", async () => {
const slug = "test-evidence";
await writeEvidenceSource(slug);
const result = await runNachweisApprove(
makeInput({
system: systemId,
slug,
"verification-level": "N3",
"legal-content-check": "passed",
}),
mockContext(tmpDir),
);
expect(result.exitCode).toBe(1);
expect(result.summary).toContain("N3_GATE_FAILED");
expect(result.summary).toContain("nachweis-signed");
expect(result.summary).toContain("nachweis-timestamped");
});
test("nachweis.approve --verification-level N3 fails when signature exists but timestamp is missing", async () => {
const slug = "test-evidence";
await writeEvidenceSource(slug);
const keyFile = path.join(tmpDir, "test-signing.key");
await ensureNachweisKey(keyFile, false);
await runNachweisSign(
makeInput({ system: systemId, slug, "key-file": keyFile }),
mockContext(tmpDir),
);
const result = await runNachweisApprove(
makeInput({
system: systemId,
slug,
"verification-level": "N3",
"legal-content-check": "passed",
}),
mockContext(tmpDir),
);
expect(result.exitCode).toBe(1);
expect(result.summary).toContain("N3_GATE_FAILED");
expect(result.summary).toContain("nachweis-timestamped");
expect(result.summary).not.toContain("nachweis-signed");
});
test("nachweis.approve --verification-level N3 succeeds when both signature and timestamp entries exist", async () => {
const slug = "test-evidence";
await writeEvidenceSource(slug);
const keyFile = path.join(tmpDir, "test-signing.key");
await ensureNachweisKey(keyFile, false);
await runNachweisSign(
makeInput({ system: systemId, slug, "key-file": keyFile }),
mockContext(tmpDir),
);
// Manually write a nachweis-timestamped entry
const entries = await readBordbuchFile();
const lastHash = entries.length > 0 ? entries[entries.length - 1].hash : null;
const tsEntry = makeEntry(
{
id: `event-${String(entries.length + 1).padStart(6, "0")}`,
kind: "nachweis-timestamped" as BordbuchEntry["kind"],
missionId: null,
occurredAt: new Date().toISOString(),
summary: `Record '${slug}' timestamped via FreeTSA`,
metadata: { slug, timestampTokenBase64: "dGVzdA==", tsaUrl: "https://freetsa.org/tsr" },
},
lastHash,
);
await writeBordbuch([...entries, tsEntry]);
const result = await runNachweisApprove(
makeInput({
system: systemId,
slug,
"verification-level": "N3",
"legal-content-check": "passed",
}),
mockContext(tmpDir),
);
expect(result.exitCode).toBe(0);
expect(result.data!.verificationLevel).toBe("N3");
expect(result.data!.bordbuchEventId).not.toBeNull();
});
test("nachweis.approve --verification-level N2 is unchanged (no N3 gate)", async () => {
const slug = "test-evidence";
await writeEvidenceSource(slug);
const result = await runNachweisApprove(
makeInput({
system: systemId,
slug,
"verification-level": "N2",
"legal-content-check": "passed",
}),
mockContext(tmpDir),
);
expect(result.exitCode).toBe(0);
expect(result.data!.verificationLevel).toBe("N2");
});
// ---------------------------------------------------------------------------
// RFC-0871: Timestamp assurance
// ---------------------------------------------------------------------------
test("RFC-0871: nachweis.timestamp dry-run defaults to rfc3161 assurance", async () => {
const slug = "test-evidence";
await writeEvidenceSource(slug);
const keyFile = path.join(tmpDir, "test-signing.key");
await ensureNachweisKey(keyFile, false);
await runNachweisSign(
makeInput({ system: systemId, slug, "key-file": keyFile }),
mockContext(tmpDir),
);
const result = await runNachweisTimestamp(
makeInput({ system: systemId, slug, "dry-run": true }),
mockContext(tmpDir),
);
expect(result.exitCode).toBe(0);
expect(result.data!.timestampAssurance).toBe("rfc3161");
expect(result.data!.qualificationEvidenceRef).toBeUndefined();
});
test("RFC-0871: nachweis.timestamp dry-run accepts eidas-qualified with qualification-evidence-ref", async () => {
const slug = "test-evidence";
await writeEvidenceSource(slug);
const keyFile = path.join(tmpDir, "test-signing.key");
await ensureNachweisKey(keyFile, false);
await runNachweisSign(
makeInput({ system: systemId, slug, "key-file": keyFile }),
mockContext(tmpDir),
);
const evidenceRef = "https://example.eu/tl/qtsp-entry.json";
const result = await runNachweisTimestamp(
makeInput({
system: systemId,
slug,
"dry-run": true,
"timestamp-assurance": "eidas-qualified",
"qualification-evidence-ref": evidenceRef,
}),
mockContext(tmpDir),
);
expect(result.exitCode).toBe(0);
expect(result.data!.timestampAssurance).toBe("eidas-qualified");
expect(result.data!.qualificationEvidenceRef).toBe(evidenceRef);
});
test("RFC-0871: nachweis.timestamp fails when eidas-qualified without qualification-evidence-ref", async () => {
const slug = "test-evidence";
await writeEvidenceSource(slug);
const keyFile = path.join(tmpDir, "test-signing.key");
await ensureNachweisKey(keyFile, false);
await runNachweisSign(
makeInput({ system: systemId, slug, "key-file": keyFile }),
mockContext(tmpDir),
);
await expect(
runNachweisTimestamp(
makeInput({
system: systemId,
slug,
"dry-run": true,
"timestamp-assurance": "eidas-qualified",
}),
mockContext(tmpDir),
),
).rejects.toThrow("TIMESTAMP_QUALIFICATION_EVIDENCE_REQUIRED");
});
test("RFC-0871: nachweis.timestamp fails with invalid assurance value", async () => {
const slug = "test-evidence";
await writeEvidenceSource(slug);
const keyFile = path.join(tmpDir, "test-signing.key");
await ensureNachweisKey(keyFile, false);
await runNachweisSign(
makeInput({ system: systemId, slug, "key-file": keyFile }),
mockContext(tmpDir),
);
await expect(
runNachweisTimestamp(
makeInput({
system: systemId,
slug,
"dry-run": true,
"timestamp-assurance": "invalid",
}),
mockContext(tmpDir),
),
).rejects.toThrow("INVALID_ASSURANCE");
});
test("RFC-0871: nachweis.verify-signature reports rfc3161 for legacy entries without timestampAssurance metadata", async () => {
const slug = "test-evidence";
await writeEvidenceSource(slug);
const keyFile = path.join(tmpDir, "test-signing.key");
await ensureNachweisKey(keyFile, false);
await runNachweisSign(
makeInput({ system: systemId, slug, "key-file": keyFile }),
mockContext(tmpDir),
);
// Manually write a legacy nachweis-timestamped entry WITHOUT timestampAssurance
const entries = await readBordbuchFile();
const lastHash = entries.length > 0 ? entries[entries.length - 1].hash : null;
const tsEntry = makeEntry(
{
id: `event-${String(entries.length + 1).padStart(6, "0")}`,
kind: "nachweis-timestamped" as BordbuchEntry["kind"],
missionId: null,
occurredAt: new Date().toISOString(),
summary: `Record '${slug}' timestamped via FreeTSA`,
metadata: { slug, timestampTokenBase64: "dGVzdA==", tsaUrl: "https://freetsa.org/tsr" },
},
lastHash,
);
await writeBordbuch([...entries, tsEntry]);
const result = await runNachweisVerifySignature(
makeInput({ system: systemId, slug }),
mockContext(tmpDir),
);
expect(result.exitCode).toBe(0);
expect(result.data!.timestampVerified).toBe(true);
expect(result.data!.timestampAssurance).toBe("rfc3161");
expect(result.data!.qualificationEvidenceRef).toBeUndefined();
});
test("RFC-0871: nachweis.verify-signature reports eidas-qualified when metadata present", async () => {
const slug = "test-evidence";
await writeEvidenceSource(slug);
const keyFile = path.join(tmpDir, "test-signing.key");
await ensureNachweisKey(keyFile, false);
await runNachweisSign(
makeInput({ system: systemId, slug, "key-file": keyFile }),
mockContext(tmpDir),
);
// Write a nachweis-timestamped entry with eidas-qualified assurance
const entries = await readBordbuchFile();
const lastHash = entries.length > 0 ? entries[entries.length - 1].hash : null;
const evidenceRef = "https://example.eu/tl/qtsp-entry.json";
const tsEntry = makeEntry(
{
id: `event-${String(entries.length + 1).padStart(6, "0")}`,
kind: "nachweis-timestamped" as BordbuchEntry["kind"],
missionId: null,
occurredAt: new Date().toISOString(),
summary: `Record '${slug}' timestamped via QTSP`,
metadata: {
slug,
timestampTokenBase64: "dGVzdA==",
tsaUrl: "https://qtsp.example.eu/tsr",
timestampAssurance: "eidas-qualified",
qualificationEvidenceRef: evidenceRef,
},
},
lastHash,
);
await writeBordbuch([...entries, tsEntry]);
const result = await runNachweisVerifySignature(
makeInput({ system: systemId, slug }),
mockContext(tmpDir),
);
expect(result.exitCode).toBe(0);
expect(result.data!.timestampVerified).toBe(true);
expect(result.data!.timestampAssurance).toBe("eidas-qualified");
expect(result.data!.qualificationEvidenceRef).toBe(evidenceRef);
expect(result.data!.details).toContain("eIDAS qualified timestamp");
});
test("RFC-0871: nachweis.verify-signature details mention RFC 3161 for rfc3161 assurance", async () => {
const slug = "test-evidence";
await writeEvidenceSource(slug);
const keyFile = path.join(tmpDir, "test-signing.key");
await ensureNachweisKey(keyFile, false);
await runNachweisSign(
makeInput({ system: systemId, slug, "key-file": keyFile }),
mockContext(tmpDir),
);
// Write a nachweis-timestamped entry with rfc3161 assurance
const entries = await readBordbuchFile();
const lastHash = entries.length > 0 ? entries[entries.length - 1].hash : null;
const tsEntry = makeEntry(
{
id: `event-${String(entries.length + 1).padStart(6, "0")}`,
kind: "nachweis-timestamped" as BordbuchEntry["kind"],
missionId: null,
occurredAt: new Date().toISOString(),
summary: `Record '${slug}' timestamped via FreeTSA`,
metadata: {
slug,
timestampTokenBase64: "dGVzdA==",
tsaUrl: "https://freetsa.org/tsr",
timestampAssurance: "rfc3161",
},
},
lastHash,
);
await writeBordbuch([...entries, tsEntry]);
const result = await runNachweisVerifySignature(
makeInput({ system: systemId, slug }),
mockContext(tmpDir),
);
expect(result.exitCode).toBe(0);
expect(result.data!.timestampAssurance).toBe("rfc3161");
expect(result.data!.details).toContain("RFC 3161 timestamp");
});