import fs from "node:fs/promises"; import path from "node:path"; import type { LettaCodeClientSessionOptions, LettaCodeSession, LettaConversation, AnyAgentTool, ListMessagesResult, SDKMessage, SendMessage, } from "@letta-ai/letta-agent-sdk"; import { afterEach, describe, expect, test } from "vitest"; import { FilesystemConnector } from "../src/connectors/filesystem.js"; import { LettaAgentSdkRunner, lettaDocumentConversationBindingId, lettaDocumentConversationRemoteMarker, lettaTurnKey, type LettaAgentSdkClient, } from "../src/agents/letta-agent-sdk.js"; import { PUBLIC_KNOWLEDGE_PROPOSED_DIFF_OUTPUT_CONTRACT, publicKnowledgeProposedDiffOutputSchema, type PublicKnowledgeProposedDiffOutput, } from "../src/agents/output-contracts.js"; import { ThoughtAgentRuntime } from "../src/agents/runtime.js"; import type { AgentOutput, AgentRunInput, AgentRunner, RunnerTrace, ThoughtAgentDeclaration, } from "../src/agents/types.js"; import { buildPublicKnowledgeContextPacket, PublicKnowledgeEligibilitySkip, validatePublicKnowledgeProposedDiffAgainstContext, } from "../src/public-knowledge/context.js"; import { PUBLIC_KNOWLEDGE_PROPOSED_DIFF_EVENT_TYPE } from "../src/public-knowledge/types.js"; import { PUBLIC_KNOWLEDGE_PROPOSAL_TOOL_NAME } from "../src/public-knowledge/proposal-tool.js"; import type { ThoughtEvent } from "../src/events/types.js"; import type { JazzThoughtStore } from "../src/jazz/store.js"; import { temporaryProject, testStore } from "./helpers.js"; const stores: JazzThoughtStore[] = []; const roots: string[] = []; afterEach(async () => { await Promise.all(stores.splice(0).map((store) => store.close())); await Promise.all(roots.splice(0).map((root) => fs.rm(root, { recursive: true, force: true }))); }); describe("Coil Public Knowledge consumer", () => { test("loads one exact eligible document and a bounded relevant public target while blocking journal content before inference", async () => { const fixture = await fixtureWorkspace(); const declaration = publicKnowledgeDeclaration(); const scan = await fixture.connector.scan(fixture.store); const lesson = scan.events.find((event) => event.payload.path === "lessons/eligible.md")!; const journal = scan.events.find((event) => event.payload.path === "journal/private.md")!; const packet = await buildPublicKnowledgeContextPacket(fixture.store, declaration, lesson, fixture.contextOptions); expect(packet.text).toContain("# Eligible source"); expect(packet.text).toContain("agent-memory"); expect(packet.text).toContain("PUBLIC ADMITTED TARGET BODY"); expect(packet.text).not.toContain("UNRELATED PUBLIC BODY MUST STAY OUT"); expect(packet.manifest).toMatchObject({ truncated: false, publicKnowledge: { documentId: lesson.payload.documentId, versionId: lesson.payload.versionId, sourceSha256: lesson.payload.sha256, catalogSlugs: ["agent-memory", "unrelated-entry"], catalogTargets: [{ slug: "agent-memory", sha256: expect.stringMatching(/^[a-f0-9]{64}$/) }], }, }); await expect(buildPublicKnowledgeContextPacket( fixture.store, declaration, journal, fixture.contextOptions, )).rejects.toMatchObject({ code: "blocked-path" } satisfies Partial); let blockedContentReads = 0; const contentTrap = { getDocumentVersion: async () => { blockedContentReads += 1; throw new Error("blocked content must not be read"); }, } as unknown as JazzThoughtStore; await expect(buildPublicKnowledgeContextPacket( contentTrap, declaration, journal, fixture.contextOptions, )).rejects.toMatchObject({ code: "blocked-path" }); expect(blockedContentReads).toBe(0); }); test("settles blocked files as skipped before runner calls or inference accounting", async () => { const fixture = await fixtureWorkspace(); const scan = await fixture.connector.scan(fixture.store); const declaration = publicKnowledgeDeclaration(); const runner = new ProposedDiffProbe(); const runtime = new ThoughtAgentRuntime(fixture.store, [runner], { publicKnowledgeContext: fixture.contextOptions, }); const results = await runtime.consumeBacklog([declaration]); expect(results).toHaveLength(scan.events.length); expect(runner.calls).toBe(1); const runs = await fixture.store.listRuns(); expect(runs.map((run) => run.status).sort()).toEqual(["completed", "skipped"]); const skipped = runs.find((run) => run.status === "skipped")!; expect(skipped.contextManifest).toMatchObject({ skip: { code: "blocked-path" } }); expect((await fixture.store.listInferenceAccounting({ agentId: declaration.id }))).toHaveLength(1); expect((await fixture.store.listEvents({ types: ["stream.thought.agent.run.skipped"] }))).toHaveLength(1); expect((await fixture.store.listEvents({ types: [PUBLIC_KNOWLEDGE_PROPOSED_DIFF_EVENT_TYPE], }))).toEqual([expect.objectContaining({ privacy: "sensitive", payload: expect.objectContaining({ structuredOutput: expect.objectContaining({ proposalState: "agent-proposed", publicationEligible: false, }), }), })]); }); test("binds one output-only local confined Co conversation to a stable document across path changes", async () => { const fixture = await fixtureWorkspace(); const [event] = (await fixture.connector.scan(fixture.store)).events.filter((candidate) => ( candidate.payload.path === "lessons/eligible.md" )); const declaration = publicKnowledgeDeclaration(); const context = await buildPublicKnowledgeContextPacket(fixture.store, declaration, event!, fixture.contextOptions); const client = new FakeConversationClient(validProposedDiff(context)); const runner = new LettaAgentSdkRunner({ client, conversationStore: fixture.store, environment: { THOUGHTSTREAM_LETTA_CO_MEMORY_DIR: "/tmp/co-memory" }, reconciliationDelayMs: 0, }); const traces: RunnerTrace[] = []; const first = await runner.run( { runId: "thought-run-first", declaration, event: event!, context }, async (trace) => { traces.push(trace); }, ); const renamed: ThoughtEvent = { ...event!, id: "event-renamed-fixture", sourceSequence: event!.sourceSequence + 1, type: "stream.thought.source.file.renamed", payload: { ...event!.payload, path: "lessons/renamed.md", previousPath: "lessons/eligible.md" }, }; await runner.run({ runId: "thought-run-second", declaration, event: renamed, context }, async () => {}); const upgradedDeclaration: ThoughtAgentDeclaration = { ...declaration, version: declaration.version + 1 }; const upgradedEvent: ThoughtEvent = { ...renamed, id: "event-upgraded-declaration-fixture", sourceSequence: renamed.sourceSequence + 1, }; await runner.run({ runId: "thought-run-third", declaration: upgradedDeclaration, event: upgradedEvent, context, }, async () => {}); expect(first).toMatchObject({ decision: "revise-existing", proposal: { target: { kind: "replacement", slug: "agent-memory" } }, publicationEligible: false, }); expect(client.created).toHaveLength(1); expect(client.resumedIds).toEqual([client.created[0]!.id, client.created[0]!.id, client.created[0]!.id]); expect(client.sessionOptions[0]).toMatchObject({ permissionMode: "strict", skillSources: [], allowedTools: [PUBLIC_KNOWLEDGE_PROPOSAL_TOOL_NAME], tools: [expect.objectContaining({ name: PUBLIC_KNOWLEDGE_PROPOSAL_TOOL_NAME })], cwd: "/tmp/co-memory", env: { MEMORY_DIR: "/tmp/co-memory" }, filesystemConfinement: "memory", model: "chatgpt-plus-pro/gpt-5.6-luna", }); const canUseTool = client.sessionOptions[0]?.canUseTool; expect(canUseTool).toBeTypeOf("function"); await expect(canUseTool!(PUBLIC_KNOWLEDGE_PROPOSAL_TOOL_NAME, {}, undefined)).resolves.toMatchObject({ behavior: "allow", }); await expect(canUseTool!("Patch", {}, undefined)).resolves.toMatchObject({ behavior: "deny", interrupt: false, }); expect(traces.filter((trace) => trace.kind === "letta.tool_call")).toEqual([ expect.objectContaining({ data: expect.objectContaining({ toolName: PUBLIC_KNOWLEDGE_PROPOSAL_TOOL_NAME }) }), ]); expect(traces.filter((trace) => trace.kind === "letta.tool_result")).toHaveLength(1); expect(JSON.stringify(traces)).not.toContain("/tmp/co-memory"); expect(JSON.stringify(traces)).not.toContain("Durable memory depends on explicit context custody"); expect(client.sessions.flatMap((session) => session.sent).join("\n")).not.toContain("/tmp/co-memory"); const [binding] = await fixture.store.listLettaConversationBindings(); expect(binding).toMatchObject({ agentId: "agent-co-fixture", source: "filesystem:coil", scopeType: "document", scopeKey: event!.payload.documentId, conversationId: client.created[0]!.id, currentPath: "lessons/renamed.md", declarationVersion: upgradedDeclaration.version, }); expect(binding!.remoteMarker).toBe(lettaDocumentConversationRemoteMarker( lettaDocumentConversationBindingId(declaration, event!), )); }); test("recovers a summary-marked remote conversation and fails closed on duplicate markers", async () => { const fixture = await fixtureWorkspace(); const event = (await fixture.connector.scan(fixture.store)).events.find((candidate) => ( candidate.payload.path === "lessons/eligible.md" ))!; const declaration = publicKnowledgeDeclaration(); const context = await buildPublicKnowledgeContextPacket(fixture.store, declaration, event, fixture.contextOptions); const marker = lettaDocumentConversationRemoteMarker(lettaDocumentConversationBindingId(declaration, event)); const existing = conversation("conv-recovered", marker); const client = new FakeConversationClient(validProposedDiff(context), [existing]); const runner = new LettaAgentSdkRunner({ client, conversationStore: fixture.store, environment: { THOUGHTSTREAM_LETTA_CO_MEMORY_DIR: "/tmp/co-memory" }, reconciliationDelayMs: 0, }); await runner.run({ runId: "thought-run-recover", declaration, event, context }, async () => {}); expect(client.created).toHaveLength(0); expect(client.resumedIds).toEqual([existing.id]); expect((await fixture.store.listLettaConversationBindings())[0]?.conversationId).toBe(existing.id); const duplicateRoot = await temporaryProject("thoughtstream-pk-duplicate-"); roots.push(duplicateRoot); const duplicateStore = await testStore(duplicateRoot); stores.push(duplicateStore); const duplicateClient = new FakeConversationClient(validProposedDiff(context), [ conversation("conv-duplicate-a", marker), conversation("conv-duplicate-b", marker), ]); const duplicateRunner = new LettaAgentSdkRunner({ client: duplicateClient, conversationStore: duplicateStore, environment: { THOUGHTSTREAM_LETTA_CO_MEMORY_DIR: "/tmp/co-memory" }, reconciliationDelayMs: 0, }); await expect(duplicateRunner.run({ runId: "thought-run-duplicate", declaration, event, context, }, async () => {})).rejects.toMatchObject({ diagnostic: { code: "letta-conversation-marker-ambiguous" }, }); expect(duplicateClient.resumedIds).toHaveLength(0); }); test("recovers one validated proposal tool call from durable conversation history without resending", async () => { const fixture = await fixtureWorkspace(); const event = (await fixture.connector.scan(fixture.store)).events.find((candidate) => ( candidate.payload.path === "lessons/eligible.md" ))!; const declaration = publicKnowledgeDeclaration(); const context = await buildPublicKnowledgeContextPacket(fixture.store, declaration, event, fixture.contextOptions); const proposal = validProposedDiff(context); const marker = lettaDocumentConversationRemoteMarker(lettaDocumentConversationBindingId(declaration, event)); const existing = conversation("conv-history-recovery", marker); const turnKey = lettaTurnKey(declaration, event.id); const history = [ { id: "assistant", message_type: "assistant_message", content: "PROPOSAL_CAPTURED" }, { id: "tool-return", message_type: "tool_return_message", tool_call_id: "proposal-call", status: "success", tool_return: "{\"accepted\":true}", }, { id: "tool-call", message_type: "tool_call_message", tool_call: { tool_call_id: "proposal-call", name: PUBLIC_KNOWLEDGE_PROPOSAL_TOOL_NAME, arguments: JSON.stringify({ raw: JSON.stringify(proposal) }), }, }, { id: "user", message_type: "user_message", content: `trusted marker ${turnKey}` }, ]; const client = new FakeConversationClient(proposal, [existing], "none", history); const runner = new LettaAgentSdkRunner({ client, conversationStore: fixture.store, environment: { THOUGHTSTREAM_LETTA_CO_MEMORY_DIR: "/tmp/co-memory" }, reconciliationDelayMs: 0, }); const output = await runner.run({ runId: "thought-run-history-recovery", declaration, event, context }, async () => {}); expect(output).toMatchObject({ decision: "revise-existing", proposal: { target: { slug: "agent-memory" } }, publicationEligible: false, }); expect(client.sessions[0]?.sent).toHaveLength(0); expect(client.sessions[0]?.streamCalls).toBe(0); }); test("rejects context-invalid targets, hashes, links, and privacy claims after schema validation", async () => { const fixture = await fixtureWorkspace("# Eligible source\n\nA memory architecture note.\n\n[[journal/private]]\n"); const event = (await fixture.connector.scan(fixture.store)).events.find((candidate) => ( candidate.payload.path === "lessons/eligible.md" ))!; const context = await buildPublicKnowledgeContextPacket( fixture.store, publicKnowledgeDeclaration(), event, fixture.contextOptions, ); const valid = validProposedDiff(context); expect(() => validatePublicKnowledgeProposedDiffAgainstContext({ ...valid, proposal: { ...valid.proposal!, target: { kind: "replacement", slug: "missing-entry", baseSha256: "a".repeat(64) }, }, }, context)).toThrow("not admitted"); expect(() => validatePublicKnowledgeProposedDiffAgainstContext({ ...valid, proposal: { ...valid.proposal!, target: { ...valid.proposal!.target, baseSha256: "b".repeat(64) }, }, }, context)).toThrow("base hash"); expect(() => validatePublicKnowledgeProposedDiffAgainstContext({ ...valid, proposal: { ...valid.proposal!, draft: { ...valid.proposal!.draft, relatedSlugs: ["missing-entry"] }, }, }, context)).toThrow("unknown related slugs"); expect(() => validatePublicKnowledgeProposedDiffAgainstContext({ ...valid, privacy: { status: "clear", findings: [] }, }, context)).toThrow("blocked wikilinks"); expect(() => validatePublicKnowledgeProposedDiffAgainstContext({ ...valid, privateDependencies: ["private evidence"], privacy: { status: "clear", findings: [] }, }, { ...context, manifest: { ...context.manifest, publicKnowledge: { ...(context.manifest.publicKnowledge as object), blockedWikilinkCount: 0 }, }, })).toThrow("private dependencies"); const colliding = validNewProposedDiff(); expect(() => validatePublicKnowledgeProposedDiffAgainstContext({ ...colliding, proposal: { ...colliding.proposal!, target: { kind: "new", slug: "agent-memory", baseSha256: null }, }, }, context)).toThrow("collides"); }); test("requires inert new, replacement, and blocked-skip shapes", () => { expect(() => publicKnowledgeProposedDiffOutputSchema.parse({ ...validNewProposedDiff(), publicationEligible: true, })).toThrow(); expect(() => publicKnowledgeProposedDiffOutputSchema.parse({ ...validNewProposedDiff(), proposal: { ...validNewProposedDiff().proposal!, target: { kind: "new", slug: "new-entry", baseSha256: "a".repeat(64) }, }, })).toThrow(); expect(() => publicKnowledgeProposedDiffOutputSchema.parse({ ...validNewProposedDiff(), privacy: { status: "blocked", findings: ["private"] }, })).toThrow(); expect(publicKnowledgeProposedDiffOutputSchema.parse({ proposalState: "agent-proposed", decision: "skip", summary: "No public-safe draft.", rationale: ["The source is private."], proposal: null, publicSourcesToVerify: [], privateDependencies: [], privacy: { status: "blocked", findings: ["private"] }, confidence: "high", publicationEligible: false, })).toMatchObject({ decision: "skip", proposal: null, publicationEligible: false }); }); test.each([ ["none", "missing-tool-call"], ["unknown", "unexpected-tool-call"], ["duplicate", "duplicate-call"], ["malformed", "invalid-schema"], ["context-invalid", "invalid-context"], ["missing-result", "missing-tool-result"], ["error-result", "invalid-tool-result"], ] as const)("fails closed for %s proposal-tool behavior", async (toolBehavior, reason) => { const fixture = await fixtureWorkspace(); const event = (await fixture.connector.scan(fixture.store)).events.find((candidate) => ( candidate.payload.path === "lessons/eligible.md" ))!; const declaration = publicKnowledgeDeclaration(); const context = await buildPublicKnowledgeContextPacket(fixture.store, declaration, event, fixture.contextOptions); const client = new FakeConversationClient(validProposedDiff(context), [], toolBehavior); const runner = new LettaAgentSdkRunner({ client, conversationStore: fixture.store, environment: { THOUGHTSTREAM_LETTA_CO_MEMORY_DIR: "/tmp/co-memory" }, reconciliationDelayMs: 0, }); const error = await runner.run({ runId: `thought-run-tool-${toolBehavior}`, declaration, event, context, }, async () => {}).catch((caught) => caught); expect(error).toMatchObject({ diagnostic: { code: "invalid-proposal-tool-output", reason }, advanceProgress: true, }); expect(JSON.stringify(error.diagnostic)).not.toContain("PRIVATE-MALFORMED-RATIONALE"); }); }); class ProposedDiffProbe implements AgentRunner { readonly mode = "letta-agent-sdk" as const; calls = 0; async run(_input: AgentRunInput, _onTrace: (trace: RunnerTrace) => Promise): Promise { this.calls += 1; return validNewProposedDiff(); } } type ToolBehavior = "valid" | "none" | "unknown" | "duplicate" | "malformed" | "context-invalid" | "missing-result" | "error-result"; class FakeConversationClient implements LettaAgentSdkClient { readonly created: LettaConversation[] = []; readonly resumedIds: string[] = []; readonly sessionOptions: Array = []; readonly sessions: FakeSession[] = []; private readonly remote = new Map(); private sequence = 0; readonly conversations: NonNullable; constructor( private readonly output: PublicKnowledgeProposedDiffOutput, conversations: LettaConversation[] = [], private readonly toolBehavior: ToolBehavior = "valid", private readonly history: unknown[] = [], ) { for (const item of conversations) this.remote.set(item.id, item); this.conversations = { list: async (options) => [...this.remote.values()].filter((item) => ( (!options?.agentId || item.agent_id === options.agentId) && (!options?.summarySearch || item.summary?.includes(options.summarySearch)) )), create: async (options) => { const item = conversation(`conv-created-${++this.sequence}`, options.summary ?? ""); this.remote.set(item.id, item); this.created.push(item); return item; }, retrieve: async (conversationId) => { const item = this.remote.get(conversationId); if (!item) throw new Error("conversation missing"); return item; }, }; } resumeSession(id: string, options?: LettaCodeClientSessionOptions): LettaCodeSession { this.resumedIds.push(id); this.sessionOptions.push(options); const session = new FakeSession(id, this.output, options?.tools ?? [], this.toolBehavior, this.history); this.sessions.push(session); return session as unknown as LettaCodeSession; } } class FakeSession { readonly agentId = "agent-co-fixture"; readonly sessionId = "session-pk-fixture"; readonly sent: string[] = []; streamCalls = 0; closed = false; constructor( readonly conversationId: string, private readonly output: PublicKnowledgeProposedDiffOutput, private readonly tools: AnyAgentTool[], private readonly toolBehavior: ToolBehavior, private readonly history: unknown[], ) {} async send(message: SendMessage): Promise { if (typeof message !== "string") throw new Error("Fixture accepts text only"); this.sent.push(message); } async *stream(): AsyncGenerator { this.streamCalls += 1; if (this.toolBehavior === "unknown") { yield { type: "tool_call", toolCallId: "tool-call-unknown", toolName: "Bash", toolInput: { command: "redacted" }, uuid: "tool-call-message-unknown", runId: "run-pk-fixture", } as SDKMessage; } else if (this.toolBehavior !== "none") { const tool = this.tools.find((candidate) => candidate.name === PUBLIC_KNOWLEDGE_PROPOSAL_TOOL_NAME); if (!tool) throw new Error("Fixture proposal tool is missing"); const calls = this.toolBehavior === "duplicate" ? 2 : 1; for (let index = 0; index < calls; index += 1) { const toolCallId = `tool-call-fixture-${index + 1}`; const input = this.toolBehavior === "malformed" ? { ...this.output, rationale: "PRIVATE-MALFORMED-RATIONALE" } : this.toolBehavior === "context-invalid" && this.output.proposal ? { ...this.output, proposal: { ...this.output.proposal, target: { ...this.output.proposal.target, baseSha256: "b".repeat(64) }, }, } : this.output; const toolInput = { raw: JSON.stringify(input) }; const result = await tool.execute(toolCallId, toolInput); yield { type: "tool_call", toolCallId, toolName: tool.name, toolInput, uuid: `tool-call-message-fixture-${index + 1}`, runId: "run-pk-fixture", } as SDKMessage; if (this.toolBehavior !== "missing-result") { yield { type: "tool_result", toolCallId, content: result.content.map((part) => part.text ?? "").join(""), isError: this.toolBehavior === "error-result" ? true : result.isError ?? false, uuid: `tool-result-message-fixture-${index + 1}`, runId: "run-pk-fixture", } as SDKMessage; } } } yield { type: "result", success: true, result: "PROPOSAL_CAPTURED", durationMs: 20, conversationId: this.conversationId, runIds: ["run-pk-fixture"], }; } async abort(): Promise {} async listMessages(): Promise { return { messages: this.history as ListMessagesResult["messages"], nextBefore: null, hasMore: false }; } close(): void { this.closed = true; } } async function fixtureWorkspace(source = "# Eligible source\n\nA durable memory architecture note.\n") { const project = await temporaryProject("thoughtstream-pk-"); roots.push(project); const vault = path.join(project, "vault"); const catalog = path.join(project, "published"); const policyPath = path.join(project, "policy.json"); await fs.mkdir(path.join(vault, "lessons"), { recursive: true }); await fs.mkdir(path.join(vault, "journal"), { recursive: true }); await fs.mkdir(catalog, { recursive: true }); await fs.writeFile(path.join(vault, "lessons", "eligible.md"), source); await fs.writeFile(path.join(vault, "journal", "private.md"), "PRIVATE JOURNAL SENTINEL\n"); await fs.writeFile(path.join(catalog, "agent-memory.md"), [ "---", "slug: agent-memory", "title: Agent memory", "summary: Public metadata only", "---", "PUBLIC ADMITTED TARGET BODY", "", ].join("\n")); await fs.writeFile(path.join(catalog, "unrelated-entry.md"), [ "---", "slug: unrelated-entry", "title: Maritime fertilizer logistics", "summary: Public shipping metadata", "---", "UNRELATED PUBLIC BODY MUST STAY OUT", "", ].join("\n")); await fs.writeFile(policyPath, JSON.stringify({ version: 1, defaultDecision: "deny", sourceMappings: [{ pattern: "lessons/*.md", decision: "stage" }], blockedPrefixes: ["journal/"], blockedWikilinkPrefixes: ["journal/"], })); const store = await testStore(project); stores.push(store); return { project, store, connector: new FilesystemConnector({ id: "filesystem:coil", root: vault, privacy: "sensitive" }), contextOptions: { policyPath, catalogRoot: catalog }, }; } function publicKnowledgeDeclaration(): ThoughtAgentDeclaration { return { id: "coil-public-knowledge", version: 3, name: "Coil Public Knowledge", description: "Fixture", mode: "letta-agent-sdk", provider: "letta-local", model: "chatgpt-plus-pro/gpt-5.6-luna", outputContract: { ...PUBLIC_KNOWLEDGE_PROPOSED_DIFF_OUTPUT_CONTRACT.identity }, lettaAgent: { backend: "local", agentIdEnv: "THOUGHTSTREAM_LETTA_CO_AGENT_ID", agentId: "agent-co-fixture", conversation: "per-document", responseMode: "strict-json", outputOnly: true, proposalTool: "public-knowledge-diff", permissionMode: "strict", skillSources: [], memoryDirEnv: "THOUGHTSTREAM_LETTA_CO_MEMORY_DIR", dreaming: { trigger: "off" }, sandbox: { ttlMinutes: 5, terminateOnClose: false }, }, eventTypes: [ "stream.thought.source.file.added", "stream.thought.source.file.changed", "stream.thought.source.file.renamed", "stream.thought.source.file.deleted", ], compiledEventTypes: [ "stream.thought.source.file.added", "stream.thought.source.file.changed", "stream.thought.source.file.renamed", "stream.thought.source.file.deleted", ], sourcePatterns: ["filesystem:coil"], acceptedPrivacy: ["sensitive"], initialReplay: "beginning", outputEventType: PUBLIC_KNOWLEDGE_PROPOSED_DIFF_EVENT_TYPE, emit: [PUBLIC_KNOWLEDGE_PROPOSED_DIFF_EVENT_TYPE], promptRef: "prompts/coil-public-knowledge.md", systemPrompt: "Recommend Public Knowledge content.", enabled: true, maxEvents: 1, maxInputChars: 100_000, contextStrategy: "coil-public-knowledge", payloadFields: ["documentId", "path", "versionId", "sha256"], maxOutputTokens: 4_000, timeoutMs: 180_000, accounting: { leaseMs: 240_000, reservation: { inputTokens: 60_000, outputTokens: 4_000 }, limits: [{ window: "hour", maxCalls: 20, maxInputTokens: 1_200_000, maxOutputTokens: 40_000, }], }, tools: [], externalActions: false, }; } function validProposedDiff(context: { manifest: { publicKnowledge?: unknown } }): PublicKnowledgeProposedDiffOutput { const evidence = context.manifest.publicKnowledge as { catalogTargets?: Array<{ slug: string; sha256: string }> }; const target = evidence.catalogTargets?.[0]; if (!target) throw new Error("Fixture context has no admitted target"); return { proposalState: "agent-proposed", decision: "revise-existing", summary: "Revise the existing agent-memory entry.", rationale: ["The source adds a useful architectural distinction."], proposal: { target: { kind: "replacement", slug: target.slug, baseSha256: target.sha256 }, draft: { title: "Agent memory", summary: "A public explanation of durable agent memory.", kind: "concept", topics: ["agents", "memory"], relatedSlugs: [], bodyMarkdown: "# Agent memory\n\nDurable memory depends on explicit context custody.", }, }, publicSourcesToVerify: ["Primary source"], privateDependencies: [], privacy: { status: "clear", findings: [] }, confidence: "high", publicationEligible: false, }; } function validNewProposedDiff(): PublicKnowledgeProposedDiffOutput { return { proposalState: "agent-proposed", decision: "propose-new", summary: "Propose a new durable entry.", rationale: ["The source contains a distinct public concept."], proposal: { target: { kind: "new", slug: "new-entry", baseSha256: null }, draft: { title: "New entry", summary: "A concise public concept.", kind: "concept", topics: ["agents"], relatedSlugs: [], bodyMarkdown: "# New entry\n\nA proposed body.", }, }, publicSourcesToVerify: [], privateDependencies: [], privacy: { status: "clear", findings: [] }, confidence: "medium", publicationEligible: false, }; } function conversation(id: string, summary: string): LettaConversation { return { id, agent_id: "agent-co-fixture", summary, } as LettaConversation; }