// Task 469 — section.properties reserved-key strip.
//
// `section.properties` is an unconstrained Zod record. The writer spreads it
// onto every node it creates, with `baseProps` stamped on top. Any writer-
// owned key the agent puts into `properties` would land verbatim on the node
// UNLESS `baseProps` also carries that key. The most attractive smuggle slot
// is `summary` — `:Section.summary` is the operator-visible compressed view.
//
// These tests cover the strip helper directly (mirrors the Task 465 pattern
// where deriveDocumentBodies is exported and tested in isolation).
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
import { stripReservedSectionProperties, RESERVED_SECTION_PROPERTY_KEYS, } from "../memory-ingest.js";
describe("stripReservedSectionProperties", () => {
    let logSpy;
    beforeEach(() => {
        logSpy = vi.spyOn(console, "error").mockImplementation(() => { });
    });
    afterEach(() => {
        logSpy.mockRestore();
    });
    it("strips properties.summary and logs the smuggle attempt", () => {
        const result = stripReservedSectionProperties({ summary: "SMUGGLED PARAPHRASE", customTag: "keep" }, { kind: "Chapter", identity: "attachmentId=att-1" });
        expect(result).toEqual({ customTag: "keep" });
        expect(result.summary).toBeUndefined();
        expect(logSpy).toHaveBeenCalledTimes(1);
        expect(logSpy.mock.calls[0][0]).toContain("reserved-property-keys-stripped");
        expect(logSpy.mock.calls[0][0]).toContain("kind=Chapter");
        expect(logSpy.mock.calls[0][0]).toContain("keys=summary");
        expect(logSpy.mock.calls[0][0]).toContain("attachmentId=att-1");
    });
    it("passes non-reserved keys through and emits no log when nothing is stripped", () => {
        const result = stripReservedSectionProperties({ startedAt: "2026-01-01", endedAt: "2026-05-01", role: "Engineer" }, { kind: "Position", identity: "attachmentId=att-2" });
        expect(result).toEqual({
            startedAt: "2026-01-01",
            endedAt: "2026-05-01",
            role: "Engineer",
        });
        expect(logSpy).not.toHaveBeenCalled();
    });
    it("strips every reserved key in one pass and lists them all in the log", () => {
        const smuggle = {
            summary: "x",
            title: "x",
            body: "x",
            embedding: [0.1],
            accountId: "x",
            source: "x",
            keep: "yes",
        };
        const result = stripReservedSectionProperties(smuggle, {
            kind: "Other",
            identity: "conversationIdentity=conv-1 archiveSha256=abc",
        });
        expect(result).toEqual({ keep: "yes" });
        expect(logSpy).toHaveBeenCalledTimes(1);
        const logLine = logSpy.mock.calls[0][0];
        for (const k of ["summary", "title", "body", "embedding", "accountId", "source"]) {
            expect(logLine).toContain(k);
        }
        expect(logLine).toContain("conversationIdentity=conv-1");
        expect(logLine).toContain("archiveSha256=abc");
    });
    it("does not mutate the input object", () => {
        const input = { summary: "smuggle", keep: "yes" };
        stripReservedSectionProperties(input, {
            kind: "Chapter",
            identity: "attachmentId=att-3",
        });
        expect(input).toEqual({ summary: "smuggle", keep: "yes" });
    });
    it("handles an empty properties bag", () => {
        const result = stripReservedSectionProperties({}, { kind: "Chapter", identity: "attachmentId=att-4" });
        expect(result).toEqual({});
        expect(logSpy).not.toHaveBeenCalled();
    });
    it("reserved set covers every writer-owned key named in the Task 469 brief", () => {
        // The brief enumerates the 17 keys baseProps stamps across both paths.
        // If a key is added to baseProps later and not added here, that key
        // becomes a new smuggle channel.
        const brief = [
            "accountId",
            "title",
            "body",
            "bodyPreview",
            "summary",
            "embedding",
            "position",
            "scope",
            "createdAt",
            "updatedAt",
            "createdByAgent",
            "createdBySource",
            "createdBySession",
            "source",
            "sourceDocumentId",
            "archiveSha256",
            "archiveSourceFile",
        ];
        for (const k of brief) {
            expect(RESERVED_SECTION_PROPERTY_KEYS.has(k)).toBe(true);
        }
    });
});
//# sourceMappingURL=memory-ingest-section-properties-strip.test.js.map