Files
PaperClipAI/packages/plugins/plugin-llm-wiki/tests/plugin.spec.ts
T
DottaandPaperclip dabb8c5daf test: remove repeated setup and strengthen regression proof (#16022)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Its tests protect company boundaries, approvals, durable tasks,
credentials and the board UI.
> - Several owner suites repeat large database fixtures and render
frames.
> - Some tests repeat stronger proof or pass when the behavior they
describe is broken.
> - This pull request shares exact setup, removes proven duplicate cases
and repairs weak observations.
> - It preserves distinct security, lifecycle, concurrency and
user-facing contracts.
> - The benefit is 5,027 fewer test lines and stronger regression
checks.

## Linked Issues or Issue Description

Refs #15978. This continues the merged test-audit cleanup in [PR
#15978](https://github.com/paperclipai/paperclip/pull/15978), which
removed 11,976 test/support lines. The savings in this pull request are
additional.

Related open work: [PR
#13460](https://github.com/paperclipai/paperclip/pull/13460) changes
legacy OAuth parent/version lock ordering. This pull request retains
those production paths and the existing lock-order test. Its secrets
changes compact fixtures and repair the two AWS wrapper exclusion
observations.

Scoped title searches found no open duplicate audit or
fixture-consolidation PR and no matching audit issue. The problem is
described here using the enhancement template.

**What existing behavior does this improve?**

The maintenance and regression value of the existing server, UI, CLI,
shared and wiki-plugin test suites.

**Subsystem affected**

Cross-cutting test code. Two UI modules also lose unused test inspection
exports.

**Current behavior**

Owner tests repeat database rows, service inputs, HTTP setup and render
frames. Some cases repeat stronger assertions. Two AWS lock tests record
only cleanup events, so an AWS provider write can happen inside the held
lock without failing those observations. Several other negative tests
accept or do not observe the wrong result. Worktree fixtures also use a
temporary path alias that conflicts with the existing canonical-path
checks on macOS.

**Proposed behavior**

Use small local helpers that preserve exact inputs, fresh allocations,
callbacks, query order and await positions. Remove only cases with named
stronger keepers. Tighten negative assertions and observe actual AWS
provider entry while a confirmed lock holder remains parked. Resolve
temporary fixture roots to their canonical paths.

**Reason and benefit**

Remove 5,027 net test lines and 15 redundant registered executions.
Remove 11 lines of unused UI inspection exports. Keep every distinct
company, actor, approval, credential, persistence, stale-write and
concurrency contract. No wall-time speedup is claimed for setup
compaction.

**Breaking changes**

None for application behavior, APIs or stored data. The removed exports
expose private UI test state and have no remaining callers.

## What Changed

- Consolidate repeated runtime, workspace, portability, route,
tool-access, policy, gateway and state-service fixtures.
- Share repeated UI render frames and CLI/wiki-plugin setup while
retaining the original actions and expected results.
- Remove 15 repeated case executions only where the audit records an
exact stronger keeper.
- Repair weak HTTP/UI negative assertions and two AWS account-home lock
observations. Keep the existing durable results and cleanup behavior.
- Remove the unused `__inflightGetCount` and `__secondTickInternals`
inspection exports. Keep observable request coalescing and ticker
lifecycle checks.
- Canonicalize temporary worktree fixture paths without weakening
production path checks.
- Record the owner decisions, savings, independent preservation reviews
and validation in [the dated audit
report](https://github.com/paperclipai/paperclip/blob/58c5c4aa241c85f4665a3159c192888bbb2a5cfa/doc/plans/2026-10-12-test-audit-rounds.md)
and [the compact control
evidence](https://github.com/paperclipai/paperclip/blob/58c5c4aa241c85f4665a3159c192888bbb2a5cfa/doc/plans/2026-10-12-test-audit-controls.json).

## Verification

- Complete owner and retained-sibling baselines passed before each audit
cutover. Independent reviewers checked the full original tests, actual
helper bodies, exact inputs, receipt provenance, async order, fresh
allocations and case registrations.
- All 14 UI/route/wiki mutations failed at their intended assertions:
ten UI/API/ticker controls, one route control and three wiki
persistence/receipt controls. Each mutated production source was
restored to its exact original bytes.
- Both old AWS lock tests passed with their respective AWS-only lock
bypass. Both repaired tests failed at the intended assertions with the
same bypasses. These give 16 intended failures and two passing weak
controls across 18 executions. Each source was restored exactly.
- Final complete state-owner/sibling run: 329/329 passed at code
revision `64370831ebe191e5ce092f85f79b6fb661df7e16`.
- Final `pnpm -r typecheck`, `pnpm check:token-gates` and `pnpm build`:
passed at the same code revision.
- Delivery head `58c5c4aa241c85f4665a3159c192888bbb2a5cfa` includes the
evidence commit and master `4b766b872993045a2e787404f0475503683e5ded`.
All 27 audited test files and both application files match the locally
verified code revision byte-for-byte. Current-head CI validates the
integrated branch, including the incoming master changes.
- All eight production-owner SHA guards for the 16 deliberate failing
mutation controls still match the integrated delivery checkout. The
mutation receipts therefore apply to those current owners.
- Full default `pnpm test:run`: **failed** with exit 1 at frozen code
revision `64370831ebe191e5ce092f85f79b6fb661df7e16`; HEAD and tracked
source bytes remained unchanged. The first general-server group reported
878 passing files, four failing files and six skipped files; 17,846
passing cases, 24 failing cases and 105 skipped cases. Later groups did
not run. Failures were `http-log-redaction` (socket hangup),
`public-mcp` (initial 15-second timeout followed by hosted token
“Refresh before subscribing” failures), `remove-test-home` (macOS
`ENOTEMPTY` where permission errors were expected, plus cleanup
failure), and `workspace-git-snapshot-streaming` (300-second timeout).
All four failing test files and the relevant cleanup/MCP production
owners are unchanged by this audit. Full local success is not claimed.
- Focused complete-owner diagnosis at the same frozen revision: 149/152
passed, three failed, zero skipped. `public-mcp` passed 82/82 and
`http-log-redaction` passed 66/66 unchanged. The two `remove-test-home`
cases reproduced macOS `ENOTEMPTY` against an expected `EACCES`/`EPERM`
contract; the 32 MiB workspace snapshot case reproduced its existing
300,000 ms timeout. HEAD and tracked files stayed clean. Exact blob
comparison confirmed all four test files and the relevant cleanup/MCP
owners match both inspected master
`4b766b872993045a2e787404f0475503683e5ded` and the frozen local
revision. The three remaining local failures are unresolved; no timeout,
retry or assertion was weakened.
- Current-head CI: [workflow
38299262149](https://github.com/paperclipai/paperclip/actions/runs/38299262149)
has passed runner selection and created all downstream
test/typecheck/build gates; those gates are queued, with no failures
reported. Greptile completed successfully at
`58c5c4aa241c85f4665a3159c192888bbb2a5cfa` with [5/5 and zero
comments](https://github.com/paperclipai/paperclip/pull/16022#issuecomment-6131457592).
All review threads are resolved or absent. This pull request will remain
open after verification.

Reviewers can reproduce the required workspace checks:

```sh
pnpm -r typecheck
pnpm check:token-gates
pnpm test:run
pnpm build
```

Browser suites were not run. Their sources and user journeys are
unchanged by this audit.

## Risks

- A fixture helper can hide a specialized input or change object
freshness. Full-program expansion checks and independent reviews
preserve the exact old inputs and execution order.
- Removing duplicate proof can remove a distinct contract by mistake.
The audit records the keeper for each deletion; all distinct security
and lifecycle cases remain.
- Concurrency checks can miss progress during a fixed delay. The AWS
repairs record actual provider entry, confirm holder entry, use measured
entry windows, require exact final event order and drain both operations
in `finally`.
- The full local default run failed. Focused diagnosis reproduced two
macOS cleanup failures and one existing snapshot timeout in unchanged
owners; these remain unresolved. Current-head CI is pending. No test
deadline, retry policy, skip or CI shard was weakened to obtain a pass.

> For core feature work, check [`ROADMAP.md`](ROADMAP.md) first and
discuss it in `#dev` before opening the PR. Feature PRs that overlap
with planned core work may need to be redirected — check the roadmap
first. See `CONTRIBUTING.md`.

## Model Used

OpenAI Codex with GPT-6, reasoning, repository inspection, code
execution and delegated audit/review. The runtime does not expose the
exact served model identifier or context-window size; those values are
unavailable and are not inferred from the model catalog.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [ ] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-12 22:23:11 +00:00

3668 lines
147 KiB
TypeScript

import { readFileSync } from "node:fs";
import { createElement } from "react";
import { renderToStaticMarkup } from "react-dom/server";
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { createTestHarness } from "@paperclipai/plugin-sdk/testing";
import type { Agent, Issue, PluginManagedRoutineResolution, Project } from "@paperclipai/plugin-sdk";
import manifest, {
CURSOR_WINDOW_ROUTINE_KEY,
INDEX_REFRESH_ROUTINE_KEY,
NIGHTLY_LINT_ROUTINE_KEY,
PAPERCLIP_DISTILL_SKILL_KEY,
WIKI_MAINTAINER_AGENT_KEY,
WIKI_MAINTAINER_SKILL_CANONICAL_KEY,
WIKI_MAINTAINER_SKILL_KEY,
WIKI_MANAGED_SKILL_CANONICAL_KEYS,
WIKI_MANAGED_SKILL_KEYS,
WIKI_MAINTENANCE_ROUTINE_KEYS,
WIKI_PROJECT_KEY,
} from "../src/manifest.js";
import {
DEFAULT_AGENT_INSTRUCTION_FILES,
DEFAULT_AGENT_INSTRUCTIONS,
DEFAULT_IDEA,
DEFAULT_INDEX,
DEFAULT_LOG,
DEFAULT_WIKI_SCHEMA,
KARPATHY_LLM_WIKI_GIST_URL,
LINT_PROMPT,
QUERY_PROMPT,
} from "../src/templates.js";
import { SettingsPage, SidebarLink, WikiPage, WikiRouteSidebar } from "../src/ui/index.js";
import plugin from "../src/worker.js";
import { OPERATION_ORIGIN_KIND, type WikiSkillResource } from "../src/wiki.js";
const COMPANY_ID = "11111111-1111-4111-8111-111111111111";
const OTHER_COMPANY_ID = "99999999-9999-4999-8999-999999999999";
const ORIGINAL_DEPLOYMENT_MODE = process.env.PAPERCLIP_DEPLOYMENT_MODE;
const ORIGINAL_DEPLOYMENT_EXPOSURE = process.env.PAPERCLIP_DEPLOYMENT_EXPOSURE;
type TestBridgeGlobal = typeof globalThis & {
__paperclipPluginBridge__?: {
sdkUi?: Record<string, unknown>;
};
};
const packageJson = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")) as {
dependencies?: Record<string, string>;
devDependencies?: Record<string, string>;
peerDependencies?: Record<string, string>;
};
const DEFAULT_MANAGED_SKILL = {
status: "resolved",
skillId: "skill-1",
resourceKey: WIKI_MAINTAINER_SKILL_KEY,
details: {
name: "LLM Wiki Maintainer",
key: WIKI_MAINTAINER_SKILL_CANONICAL_KEY,
description: "Use the LLM Wiki plugin tools to maintain a cited local company wiki.",
},
skill: {
id: "skill-1",
name: "LLM Wiki Maintainer",
key: WIKI_MAINTAINER_SKILL_CANONICAL_KEY,
description: "Use the LLM Wiki plugin tools to maintain a cited local company wiki.",
},
};
const DEFAULT_MANAGED_SKILLS = WIKI_MANAGED_SKILL_KEYS.map((skillKey, index) => ({
status: "resolved",
skillId: `skill-${index + 1}`,
resourceKey: skillKey,
details: skillKey === WIKI_MAINTAINER_SKILL_KEY
? DEFAULT_MANAGED_SKILL.details
: {
name: skillKey.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" "),
key: WIKI_MANAGED_SKILL_CANONICAL_KEYS[index],
description: null,
},
skill: skillKey === WIKI_MAINTAINER_SKILL_KEY
? DEFAULT_MANAGED_SKILL.skill
: {
id: `skill-${index + 1}`,
name: skillKey.split("-").map((part) => `${part[0]?.toUpperCase() ?? ""}${part.slice(1)}`).join(" "),
key: WIKI_MANAGED_SKILL_CANONICAL_KEYS[index],
description: null,
},
}));
let mockPathname = "/PAP/wiki";
let mockSearch = "";
let mockAutoSelectFile: string | null = null;
let mockNavigatedTo: string | null = null;
let mockOverviewFolder: Record<string, unknown> | null = null;
let mockSettingsFolder: Record<string, unknown> | null = null;
let mockSettingsManagedAgent: Record<string, unknown> | null = null;
let mockSettingsManagedRoutines: Array<Record<string, unknown>> = [];
let mockSettingsManagedSkills: Array<Record<string, unknown>> = [];
let mockDistillationOverviewData: Record<string, unknown> | null = null;
let mockPageContentsByPath: Record<string, string> = {};
let mockPageMetadataByPath: Record<string, {
backlinks?: string[];
sourceRefs?: Array<Record<string, unknown> | string>;
}> = {};
beforeEach(() => {
if (ORIGINAL_DEPLOYMENT_MODE == null) {
delete process.env.PAPERCLIP_DEPLOYMENT_MODE;
} else {
process.env.PAPERCLIP_DEPLOYMENT_MODE = ORIGINAL_DEPLOYMENT_MODE;
}
if (ORIGINAL_DEPLOYMENT_EXPOSURE == null) {
delete process.env.PAPERCLIP_DEPLOYMENT_EXPOSURE;
} else {
process.env.PAPERCLIP_DEPLOYMENT_EXPOSURE = ORIGINAL_DEPLOYMENT_EXPOSURE;
}
mockPathname = "/PAP/wiki";
mockSearch = "";
mockAutoSelectFile = null;
mockNavigatedTo = null;
mockOverviewFolder = null;
mockSettingsFolder = null;
mockSettingsManagedAgent = null;
mockSettingsManagedRoutines = [];
mockSettingsManagedSkills = [];
mockDistillationOverviewData = null;
mockPageContentsByPath = {};
mockPageMetadataByPath = {};
(globalThis as TestBridgeGlobal).__paperclipPluginBridge__ = {
sdkUi: {
usePluginData: (key: string, params?: Record<string, unknown>) => {
if (key === "overview") {
return {
data: {
status: "ok",
checkedAt: new Date().toISOString(),
wikiId: "default",
folder: mockOverviewFolder ?? {
configured: true,
path: "/tmp/company-wiki",
realPath: "/tmp/company-wiki",
access: "readWrite",
readable: true,
writable: true,
requiredDirectories: [],
requiredFiles: [],
missingDirectories: [],
missingFiles: [],
healthy: true,
problems: [],
checkedAt: new Date().toISOString(),
},
managedAgent: { status: "resolved", source: "managed", agentId: "agent-1", resourceKey: "wiki-maintainer", details: { name: "Wiki Maintainer", status: "idle", adapterType: "claude_local", icon: "book-open", urlKey: "wiki-maintainer" } },
managedProject: { status: "resolved", projectId: "project-1", details: { name: "LLM Wiki", status: "in_progress" } },
managedSkills: DEFAULT_MANAGED_SKILLS,
operationCount: 0,
eventIngestion: {
enabled: false,
sources: { issues: false, comments: false, documents: false },
wikiId: "default",
maxCharacters: 12000,
},
capabilities: [],
prompts: { query: QUERY_PROMPT, lint: LINT_PROMPT },
},
loading: false,
error: null,
refresh: () => undefined,
};
}
if (key === "spaces") {
return {
data: {
spaces: [
{
id: "space-default",
companyId: COMPANY_ID,
wikiId: "default",
slug: "default",
displayName: "default",
spaceType: "managed",
folderMode: "managed_subfolder",
rootFolderKey: "wiki-root",
pathPrefix: null,
configuredRootPath: null,
accessScope: "shared",
ownerUserId: null,
ownerAgentId: null,
teamKey: null,
settings: {},
status: "active",
createdAt: null,
updatedAt: null,
},
],
},
loading: false,
error: null,
refresh: () => undefined,
};
}
if (key === "pages") {
return {
data: {
pages: [
{
path: "wiki/concepts/sidebar-navigation.md",
title: "Sidebar navigation",
pageType: "concepts",
backlinkCount: 0,
sourceCount: 0,
contentHash: "abc123",
updatedAt: new Date().toISOString(),
},
],
sources: [
{
rawPath: "raw/sidebar-notes.md",
title: "Sidebar notes",
sourceType: "text",
url: null,
status: "captured",
createdAt: new Date().toISOString(),
},
],
},
loading: false,
error: null,
refresh: () => undefined,
};
}
if (key === "settings") {
return {
data: {
status: "ok",
checkedAt: new Date().toISOString(),
wikiId: "default",
folder: mockSettingsFolder ?? {
configured: true,
path: "/tmp/company-wiki",
realPath: "/tmp/company-wiki",
access: "readWrite",
readable: true,
writable: true,
requiredDirectories: [],
requiredFiles: [],
missingDirectories: [],
missingFiles: [],
healthy: true,
problems: [],
checkedAt: new Date().toISOString(),
},
managedAgent: mockSettingsManagedAgent ?? { status: "resolved", source: "managed", agentId: "agent-1", resourceKey: "wiki-maintainer", details: { name: "Wiki Maintainer", status: "idle", adapterType: "claude_local", icon: "book-open", urlKey: "wiki-maintainer" } },
managedProject: { status: "resolved", source: "managed", projectId: "project-1", resourceKey: "llm-wiki", details: { name: "LLM Wiki", status: "in_progress" } },
managedSkills: mockSettingsManagedSkills.length > 0 ? mockSettingsManagedSkills : DEFAULT_MANAGED_SKILLS,
managedRoutines: mockSettingsManagedRoutines,
managedRoutine: mockSettingsManagedRoutines[0] ?? null,
eventIngestion: {
enabled: false,
sources: { issues: false, comments: false, documents: false },
wikiId: "default",
maxCharacters: 12000,
},
agentOptions: [{ id: "agent-1", name: "Wiki Maintainer", status: "idle", icon: "book-open", urlKey: "wiki-maintainer" }],
projectOptions: [{ id: "project-1", name: "LLM Wiki", status: "in_progress", color: "#2563eb" }],
capabilities: [],
},
loading: false,
error: null,
refresh: () => undefined,
};
}
if (key === "space") {
return {
data: {
id: "space-default",
companyId: COMPANY_ID,
wikiId: "default",
slug: "default",
displayName: "default",
spaceType: "managed",
folderMode: "managed_subfolder",
rootFolderKey: "wiki-root",
pathPrefix: null,
configuredRootPath: null,
accessScope: "shared",
ownerUserId: null,
ownerAgentId: null,
teamKey: null,
settings: {},
status: "active",
createdAt: null,
updatedAt: null,
relativeRoot: "",
folder: {
configured: true,
path: "/tmp/company-wiki",
realPath: "/tmp/company-wiki",
access: "readWrite",
readable: true,
writable: true,
requiredDirectories: ["raw", "wiki"],
requiredFiles: ["AGENTS.md"],
missingDirectories: [],
missingFiles: [],
healthy: true,
problems: [],
checkedAt: new Date().toISOString(),
},
},
loading: false,
error: null,
refresh: () => undefined,
};
}
if (key === "distillation-overview") {
return {
data: mockDistillationOverviewData,
loading: false,
error: null,
refresh: () => undefined,
};
}
if (key === "page-content") {
const path = typeof params?.path === "string" ? params.path : "wiki/index.md";
const contents = mockPageContentsByPath[path] ?? (path === "AGENTS.md"
? DEFAULT_AGENT_INSTRUCTIONS
: path === "IDEA.md"
? DEFAULT_IDEA
: `# ${path}\n`);
return {
data: {
wikiId: "default",
path,
contents,
title: path === "AGENTS.md" ? "LLM Wiki Maintainer" : path.replace(/\.md$/, ""),
pageType: path === "AGENTS.md" ? null : "index",
backlinks: mockPageMetadataByPath[path]?.backlinks ?? [],
sourceRefs: mockPageMetadataByPath[path]?.sourceRefs ?? [],
updatedAt: null,
hash: "abc123",
},
loading: false,
error: null,
refresh: () => undefined,
};
}
return { data: null, loading: false, error: null, refresh: () => undefined };
},
usePluginAction: () => async () => ({}),
usePluginToast: () => () => null,
useHostNavigation: () => ({
resolveHref: (to: string) => `/PAP${to.startsWith("/") ? to : `/${to}`}`,
navigate: (to: string) => { mockNavigatedTo = to; },
linkProps: (to: string) => ({
href: `/PAP${to.startsWith("/") ? to : `/${to}`}`,
onClick: () => undefined,
}),
}),
useHostLocation: () => ({
pathname: mockPathname,
search: mockSearch,
hash: "",
}),
FileTree: (props: {
nodes: Array<{ name: string; path: string; kind: string; children?: Array<{ name: string; path: string; kind: string }> }>;
selectedFile?: string | null;
ariaLabel?: string;
wrapLabels?: boolean;
fileBadges?: Record<string, unknown>;
onSelectFile?: (path: string) => void;
}) => {
if (mockAutoSelectFile) props.onSelectFile?.(mockAutoSelectFile);
return createElement(
"div",
{
role: "tree",
"aria-label": props.ariaLabel,
"data-selected-file": props.selectedFile ?? "",
"data-wrap-labels": String(props.wrapLabels),
"data-has-file-badges": String(Boolean(props.fileBadges && Object.keys(props.fileBadges).length > 0)),
},
props.nodes.map((node) => createElement("div", { key: node.path }, node.name)),
);
},
IssuesList: (props: {
projectId?: string | null;
filters?: { originKindPrefix?: string };
}) => createElement(
"div",
{ "data-testid": "plugin-issues-list" },
`Issues table · ${props.projectId ?? "no-project"} · ${props.filters?.originKindPrefix ?? "no-origin-filter"}`,
),
MarkdownBlock: ({ content }: { content: string }) => createElement("div", { "data-testid": "markdown-block" }, content),
MarkdownEditor: ({ value, onChange }: { value: string; onChange: (value: string) => void }) => createElement("textarea", {
"data-testid": "markdown-editor",
value,
onChange: (event: { currentTarget: { value: string } }) => onChange(event.currentTarget.value),
}),
AssigneePicker: (props: {
value: string;
placeholder?: string;
onChange: (value: string, selection: { assigneeAgentId: string | null; assigneeUserId: string | null }) => void;
}) => createElement(
"button",
{
type: "button",
"data-testid": "assignee-picker",
onClick: () => props.onChange("agent:agent-1", { assigneeAgentId: "agent-1", assigneeUserId: null }),
},
props.value === "agent:agent-1" ? "Wiki Maintainer" : (props.placeholder ?? "Select assignee"),
),
ProjectPicker: (props: {
value: string;
placeholder?: string;
onChange: (projectId: string) => void;
}) => createElement(
"button",
{
type: "button",
"data-testid": "project-picker",
onClick: () => props.onChange("project-1"),
},
props.value === "project-1" ? "LLM Wiki" : (props.placeholder ?? "Project"),
),
ManagedRoutinesList: (props: {
routines: Array<{
key: string;
title: string;
href?: string | null;
projectId?: string | null;
assigneeAgentId?: string | null;
defaultDrift?: { changedFields: string[] } | null;
}>;
agents?: Array<{ id: string; name: string }>;
projects?: Array<{ id: string; name: string }>;
onReset?: (routine: { key: string; title: string }) => void;
}) => createElement(
"div",
{ "data-testid": "managed-routines-list" },
props.routines.map((routine) => {
const agent = props.agents?.find((item) => item.id === routine.assigneeAgentId);
const project = props.projects?.find((item) => item.id === routine.projectId);
return createElement(
"div",
{ key: routine.key },
createElement("span", null, routine.title),
routine.href ? createElement("a", { href: `/PAP${routine.href}` }, "Configure") : null,
routine.defaultDrift?.changedFields.length
? createElement("span", null, `Plugin defaults changed: ${routine.defaultDrift.changedFields.join(", ")}`)
: null,
routine.defaultDrift?.changedFields.length && props.onReset
? createElement("button", null, "Reset")
: null,
createElement("span", null, `${project?.name ?? "No project"} · ${agent?.name ?? "No default agent"}`),
);
}),
),
},
};
});
afterEach(() => {
if (ORIGINAL_DEPLOYMENT_MODE == null) {
delete process.env.PAPERCLIP_DEPLOYMENT_MODE;
} else {
process.env.PAPERCLIP_DEPLOYMENT_MODE = ORIGINAL_DEPLOYMENT_MODE;
}
if (ORIGINAL_DEPLOYMENT_EXPOSURE == null) {
delete process.env.PAPERCLIP_DEPLOYMENT_EXPOSURE;
} else {
process.env.PAPERCLIP_DEPLOYMENT_EXPOSURE = ORIGINAL_DEPLOYMENT_EXPOSURE;
}
delete (globalThis as TestBridgeGlobal).__paperclipPluginBridge__;
});
function wikiMaintainerAgent(): Agent {
const now = new Date();
return {
id: "22222222-2222-4222-8222-222222222222",
companyId: COMPANY_ID,
name: "Wiki Maintainer",
urlKey: "wiki-maintainer",
role: "general",
title: "LLM Wiki Maintainer",
icon: "book-open",
status: "idle",
reportsTo: null,
capabilities: "Maintains the wiki",
adapterType: "claude_local",
adapterConfig: {},
runtimeConfig: {},
budgetMonthlyCents: 0,
spentMonthlyCents: 0,
pauseReason: null,
pausedAt: null,
permissions: { canCreateAgents: false },
lastHeartbeatAt: null,
metadata: {
paperclipManagedResource: {
pluginKey: manifest.id,
resourceKind: "agent",
resourceKey: "wiki-maintainer",
},
},
createdAt: now,
updatedAt: now,
};
}
function existingAgent(): Agent {
return {
...wikiMaintainerAgent(),
id: "44444444-4444-4444-8444-444444444444",
name: "Existing Knowledge Agent",
urlKey: "existing-knowledge-agent",
title: "Knowledge Agent",
metadata: {},
};
}
function existingProject(): Project {
const now = new Date();
return {
id: "55555555-5555-4555-8555-555555555555",
companyId: COMPANY_ID,
urlKey: "existing-wiki-project",
goalId: null,
goalIds: [],
goals: [],
name: "Existing Wiki Project",
description: "Existing project selected for wiki operations.",
status: "in_progress",
leadAgentId: null,
targetDate: null,
color: "#0f766e",
icon: null,
env: null,
pauseReason: null,
pausedAt: null,
executionWorkspacePolicy: null,
codebase: {
workspaceId: null,
repoUrl: null,
repoRef: null,
defaultRef: null,
repoName: null,
localFolder: null,
managedFolder: "/tmp/existing-wiki-project",
effectiveLocalFolder: "/tmp/existing-wiki-project",
origin: "managed_checkout",
},
workspaces: [],
primaryWorkspace: null,
managedByPlugin: null,
archivedAt: null,
createdAt: now,
updatedAt: now,
};
}
function paperclipIssue(overrides: Partial<Issue> = {}): Issue {
const now = new Date();
return {
id: "66666666-6666-4666-8666-666666666666",
companyId: COMPANY_ID,
projectId: null,
projectWorkspaceId: null,
goalId: null,
parentId: null,
visibility: "open",
privacyRootIssueId: null,
title: "Design event ingestion controls",
description: "Decide which Paperclip issues, comments, and documents can be ingested into the wiki.",
status: "todo",
workMode: "standard",
priority: "medium",
reviewPolicy: null,
assigneeAgentId: null,
assigneeUserId: null,
responsibleUserId: null,
checkoutRunId: null,
executionRunId: null,
executionAgentNameKey: null,
executionLockedAt: null,
createdByAgentId: null,
createdByUserId: null,
issueNumber: 3204,
identifier: "PAP-3204",
originId: null,
originRunId: null,
originFingerprint: null,
requestDepth: 0,
billingCode: null,
assigneeAdapterOverrides: null,
executionPolicy: null,
executionState: null,
executionWorkspaceId: null,
executionWorkspacePreference: null,
executionWorkspaceSettings: null,
startedAt: null,
completedAt: null,
cancelledAt: null,
hiddenAt: null,
createdAt: now,
updatedAt: now,
...overrides,
};
}
function wikiSpaceRow(space: Record<string, unknown>) {
return {
id: space.id,
company_id: space.companyId ?? COMPANY_ID,
wiki_id: space.wikiId ?? "default",
slug: space.slug,
display_name: space.displayName,
space_type: space.spaceType ?? "local_folder",
folder_mode: space.folderMode ?? "managed_subfolder",
root_folder_key: space.rootFolderKey ?? "wiki-root",
path_prefix: space.pathPrefix ?? `spaces/${space.slug}`,
configured_root_path: space.configuredRootPath ?? null,
access_scope: space.accessScope ?? "shared",
owner_user_id: space.ownerUserId ?? null,
owner_agent_id: space.ownerAgentId ?? null,
team_key: space.teamKey ?? null,
settings: space.settings ?? {},
status: space.status ?? "active",
created_at: space.createdAt ?? null,
updated_at: space.updatedAt ?? null,
};
}
function defaultWikiSpaceRow() {
return wikiSpaceRow({
id: "77777777-7777-4777-8777-7777777777d0",
companyId: COMPANY_ID,
wikiId: "default",
slug: "default",
displayName: "default",
pathPrefix: null,
accessScope: "shared",
settings: {},
});
}
function mockPersistedWikiSpace(harness: ReturnType<typeof createTestHarness>, space: Record<string, unknown>) {
const row = wikiSpaceRow(space);
const originalQuery = harness.ctx.db.query.bind(harness.ctx.db);
harness.ctx.db.query = async <T,>(sql: string, params?: unknown[]) => {
if (sql.includes("wiki_spaces") && params?.[2] === row.slug) {
return [row] as T[];
}
if (sql.includes("wiki_spaces") && sql.includes("ORDER BY CASE WHEN slug = 'default'")) {
return [defaultWikiSpaceRow(), row] as T[];
}
return originalQuery<T>(sql, params);
};
}
function renderWikiPage(): string {
return renderToStaticMarkup(createElement(WikiPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
}
function captureWikiWrites(harness: ReturnType<typeof createTestHarness>) {
const writes: Array<{ path: string; contents: string }> = [];
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
writes.push({ path: relativePath, contents });
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
return writes;
}
function managedSpaceRow(created: {
space: { id: string; companyId: string; wikiId: string; slug: string; displayName: string; pathPrefix: string | null };
}): Record<string, unknown> {
return {
id: created.space.id,
company_id: created.space.companyId,
wiki_id: created.space.wikiId,
slug: created.space.slug,
display_name: created.space.displayName,
space_type: "local_folder",
folder_mode: "managed_subfolder",
root_folder_key: "wiki-root",
path_prefix: created.space.pathPrefix,
configured_root_path: null,
access_scope: "shared",
owner_user_id: null,
owner_agent_id: null,
team_key: null,
settings: {},
status: "active",
created_at: null,
updated_at: null,
};
}
describe("LLM Wiki plugin scaffold", () => {
it("declares standalone plugin surfaces without core wiki coupling", () => {
expect(manifest.id).toBe("paperclipai.plugin-llm-wiki");
expect(manifest.entrypoints.worker).toBe("./dist/worker.js");
expect(manifest.entrypoints.ui).toBe("./dist/ui");
expect(manifest.database?.namespaceSlug).toBe("llm_wiki");
expect(manifest.localFolders?.[0]?.requiredDirectories).toContain("wiki/projects");
expect(manifest.localFolders?.[0]?.requiredDirectories).not.toContain("projects");
expect(manifest.localFolders?.[0]?.requiredFiles).toEqual([
"AGENTS.md",
"IDEA.md",
"wiki/index.md",
"wiki/log.md",
]);
expect(manifest.agents?.[0]?.agentKey).toBe("wiki-maintainer");
expect(manifest.agents?.[0]?.adapterType).toBe("claude_local");
expect(manifest.agents?.[0]?.adapterConfig).toMatchObject({
dangerouslySkipPermissions: false,
dangerouslyBypassApprovalsAndSandbox: false,
sandbox: true,
});
expect(manifest.agents?.[0]?.instructions?.entryFile).toBe("AGENTS.md");
expect(manifest.agents?.[0]?.instructions?.content).toContain("You are the maintainer of this personal wiki");
expect(manifest.agents?.[0]?.instructions?.files?.["AGENTS.md"]).toContain("{{localFolders.wiki-root.path}}");
expect(manifest.agents?.[0]?.instructions?.assetPath).toBe("agents/wiki-maintainer");
expect(manifest.projects?.[0]?.projectKey).toBe("llm-wiki");
expect(manifest.routines?.map((routine) => routine.routineKey)).toEqual([
CURSOR_WINDOW_ROUTINE_KEY,
NIGHTLY_LINT_ROUTINE_KEY,
INDEX_REFRESH_ROUTINE_KEY,
]);
expect(manifest.routines).toEqual(
WIKI_MAINTENANCE_ROUTINE_KEYS.map((routineKey) => expect.objectContaining({
routineKey,
assigneeRef: { resourceKind: "agent", resourceKey: WIKI_MAINTAINER_AGENT_KEY },
projectRef: { resourceKind: "project", resourceKey: WIKI_PROJECT_KEY },
concurrencyPolicy: "skip_if_active",
catchUpPolicy: "skip_missed",
issueTemplate: expect.objectContaining({
surfaceVisibility: "plugin_operation",
billingCode: expect.stringMatching(/^plugin-llm-wiki:/),
}),
})),
);
for (const routine of manifest.routines ?? []) {
expect(routine.description).toContain("Run procedure:");
expect(routine.description).toContain("Target space: default (slug: default)");
expect(routine.description).toContain("spaceSlug `default`");
expect(routine.description).toContain("AGENTS.md");
expect(routine.description).toContain("wiki/log.md");
}
expect(manifest.tools?.map((tool) => tool.name)).toEqual([
"wiki_search",
"wiki_read_page",
"wiki_write_page",
"wiki_propose_patch",
"wiki_list_sources",
"wiki_read_source",
"wiki_append_log",
"wiki_update_index",
"wiki_list_backlinks",
"wiki_list_pages",
]);
expect(manifest.ui?.slots?.map((slot) => slot.type)).toEqual([
"sidebar",
"page",
"routeSidebar",
]);
expect(manifest.capabilities).not.toContain("instance.settings.register");
expect(manifest.instanceConfigSchema).toBeUndefined();
const routeSidebarSlot = manifest.ui?.slots?.find((slot) => slot.type === "routeSidebar");
expect(routeSidebarSlot).toMatchObject({
id: "wiki-route-sidebar",
exportName: "WikiRouteSidebar",
routePath: "wiki",
});
expect(packageJson.dependencies).toBeUndefined();
expect(packageJson.devDependencies?.react).toBeUndefined();
expect(packageJson.devDependencies?.["react-dom"]).toBeDefined();
expect(packageJson.devDependencies?.["@types/react-dom"]).toBeDefined();
expect(packageJson.peerDependencies?.react).toBe(">=18");
});
it("renders a host-aligned sidebar link with an open-book icon", () => {
const markup = renderToStaticMarkup(createElement(SidebarLink, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
expect(markup).toContain('href="/PAP/wiki"');
expect(markup).toContain("gap-2.5 px-3 py-2 text-[13px] font-medium");
expect(markup).toContain("hover:bg-accent/50 hover:text-foreground");
expect(markup).toContain("<svg");
expect(markup).toContain("M12 7v14");
expect(markup).not.toContain("Wiki plugin");
expect(markup).not.toContain("border-radius:999");
expect(markup).not.toContain("📖");
});
it("ships Karpathy-pattern schema and workflow prompts by default", () => {
expect(DEFAULT_WIKI_SCHEMA).toContain("You are the maintainer of this personal wiki");
expect(DEFAULT_WIKI_SCHEMA).toContain("raw/");
expect(DEFAULT_WIKI_SCHEMA).toContain("wiki/projects/<project-slug>/standup.md");
expect(DEFAULT_WIKI_SCHEMA).toContain("wiki/projects/<project-slug>/index.md");
expect(DEFAULT_WIKI_SCHEMA).toContain("Do not create a top-level `projects/` directory");
expect(DEFAULT_WIKI_SCHEMA).not.toContain("\n├── projects/");
expect(DEFAULT_WIKI_SCHEMA).toContain("wiki/");
expect(DEFAULT_WIKI_SCHEMA).toContain("AGENTS.md");
expect(DEFAULT_IDEA).toContain("persistent, compounding artifact");
expect(DEFAULT_AGENT_INSTRUCTIONS).toContain("You are the maintainer of this personal wiki");
expect(DEFAULT_AGENT_INSTRUCTIONS).toContain("ingest, query, lint, index, or maintenance work");
expect(DEFAULT_AGENT_INSTRUCTIONS).toContain("dedicated LLM Wiki skill installed on this agent");
expect(DEFAULT_AGENT_INSTRUCTIONS).not.toContain("skills/<name>/SKILL.md");
expect(DEFAULT_AGENT_INSTRUCTION_FILES["skills/wiki-ingest/SKILL.md"]).toBeUndefined();
expect(manifest.skills?.map((skill) => skill.skillKey)).toEqual([...WIKI_MANAGED_SKILL_KEYS]);
expect(manifest.agents?.[0]?.adapterConfig?.paperclipSkillSync).toEqual({
desiredSkills: WIKI_MANAGED_SKILL_CANONICAL_KEYS,
});
expect(QUERY_PROMPT).toContain("wiki-query skill");
expect(QUERY_PROMPT).not.toContain("skills/wiki-query/SKILL.md");
expect(QUERY_PROMPT).toContain("filed back into wiki/");
expect(LINT_PROMPT).toContain("wiki-lint skill");
expect(LINT_PROMPT).not.toContain("skills/wiki-lint/SKILL.md");
expect(LINT_PROMPT).toContain("severity");
});
it("renders the route-scoped Wiki sidebar with tool actions, page navigation, and a back link", () => {
const markup = renderToStaticMarkup(createElement(WikiRouteSidebar, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
expect(markup).toContain('href="/PAP/dashboard"');
expect(markup).toContain("PAP");
expect(markup).toContain('href="/PAP/wiki/query"');
expect(markup).not.toContain('href="/PAP/wiki/lint"');
expect(markup).toContain('href="/PAP/wiki/history"');
expect(markup).toContain('href="/PAP/wiki/settings"');
expect(markup).not.toContain('href="/PAP/wiki/operations"');
// Add Content reuses the legacy /wiki/ingest route so deep links still work.
expect(markup).toContain('href="/PAP/wiki/ingest"');
expect(markup).toContain('aria-label="Wiki primary"');
expect(markup).toContain('aria-label="Wiki secondary"');
for (const label of ["Ask", "Add Content", "History", "Settings", "Shared Spaces", "default", "raw", "wiki", "AGENTS.md", "IDEA.md"]) {
expect(markup).toContain(label);
}
expect(markup).not.toContain(">Lint</span>");
expect(markup).not.toContain(">Ingest</span>");
expect(markup).not.toContain(">Operations</span>");
expect(markup).not.toContain('text-sm font-bold text-foreground">Wiki');
expect(markup).not.toContain("Browse");
expect(markup).not.toContain(">Query<");
expect(markup).toContain('role="tree"');
expect(markup).toContain('data-selected-file=""');
expect(markup).toContain('data-wrap-labels="false"');
expect(markup).toContain('data-has-file-badges="false"');
});
it("routes legacy Wiki operations URLs to the History issue table", () => {
mockPathname = "/PAP/wiki/operations";
const markup = renderWikiPage();
expect(markup).toContain("Issues table · project-1 · plugin:paperclipai.plugin-llm-wiki:operation");
expect(markup).not.toContain("Recent runs");
expect(markup).not.toContain(">Operations</h2>");
});
it("loads AGENTS.md from the Wiki page and exposes an edit affordance", () => {
mockPathname = "/PAP/wiki/page/templates/AGENTS.md";
const markup = renderWikiPage();
expect(markup).toContain("AGENTS");
expect(markup).toContain(">AGENTS.md</h1>");
expect(markup).not.toContain(">LLM Wiki Maintainer</h1>");
expect(markup).toContain("You are the maintainer of this personal wiki");
expect(markup).toContain("wiki-root `AGENTS.md`");
expect(markup).toContain("Edit page");
expect(markup).toContain("Updated —");
expect(markup).not.toContain("0 backlinks");
expect(markup).not.toContain("0 sources");
expect(markup).not.toContain("abc123");
expect(markup).not.toContain("+ Ingest");
expect(markup).not.toContain("Folder healthy");
});
it("does not render page footer sources and backlinks", () => {
mockPathname = "/PAP/wiki/page/wiki/projects/control-plane/index.md";
mockPageContentsByPath["wiki/projects/control-plane/index.md"] = "# Control plane\n\nCurrent project state.";
mockPageMetadataByPath["wiki/projects/control-plane/index.md"] = {
backlinks: ["wiki/backlinks/hidden-footer-link.md"],
sourceRefs: [{ kind: "issue", issueIdentifier: "PAP-FOOTER-1" }],
};
const markup = renderWikiPage();
expect(markup).toContain("Current project state.");
expect(markup).not.toContain(">Sources</");
expect(markup).not.toContain(">Backlinks</");
expect(markup).not.toContain("PAP-FOOTER-1");
expect(markup).not.toContain("hidden-footer-link");
});
it("renders YAML frontmatter as foldable properties without duplicating title", () => {
mockPathname = "/PAP/wiki/page/wiki/concepts/sidebar-navigation.md";
mockPageContentsByPath["wiki/concepts/sidebar-navigation.md"] = `---
title: Sidebar navigation
type: concept
tags: [paperclip, wiki]
sources:
- raw/sidebar-notes.md
created: 2026-05-04
updated: 2026-05-04
---
# Sidebar navigation
Route sidebar state stays attached to the selected wiki page.
`;
const markup = renderWikiPage();
expect(markup).toContain("<summary");
expect(markup).toContain("Properties");
expect(markup).toContain(">type</dt>");
expect(markup).toContain("concept");
expect(markup).toContain(">tags</dt>");
expect(markup).toContain("paperclip");
expect(markup).toContain("wiki");
expect(markup).toContain(">sources</dt>");
expect(markup).toContain("raw/sidebar-notes.md");
expect(markup).toContain("Route sidebar state");
expect(markup).not.toContain("title: Sidebar navigation");
expect(markup).not.toContain("title</dt>");
expect(markup).not.toContain("---");
});
it("renders a foldable on-this-page pane from wiki page headings", () => {
mockPathname = "/PAP/wiki/page/wiki/concepts/sidebar-navigation.md";
mockPageContentsByPath["wiki/concepts/sidebar-navigation.md"] = `# Sidebar navigation
## Why it matters
Route sidebar state stays attached to the selected wiki page.
### Deep link behavior
Wiki links preserve normal browser navigation.
\`\`\`md
## Ignored code heading
\`\`\`
## Why it matters
Duplicate headings receive stable suffixes.
`;
const markup = renderWikiPage();
expect(markup).toContain('aria-label="On this page"');
expect(markup).toContain('aria-expanded="true"');
expect(markup).toContain('aria-current="location"');
expect(markup).toContain('href="#why-it-matters"');
expect(markup).toContain('href="#deep-link-behavior"');
expect(markup).toContain('href="#why-it-matters-2"');
expect(markup).not.toContain('href="#ignored-code-heading"');
const tocMarkup = markup.slice(
markup.indexOf('aria-label="On this page"'),
markup.indexOf("</aside>", markup.indexOf('aria-label="On this page"')),
);
expect(tocMarkup).toContain("position:sticky");
expect(tocMarkup).toContain("top:88px");
expect(tocMarkup).not.toContain("background:color-mix");
expect(tocMarkup).not.toContain("border-radius");
});
it("shows folder repair instead of reading pages when the wiki root is stale", () => {
mockPathname = "/PAP/wiki/page/AGENTS.md";
mockOverviewFolder = {
configured: true,
path: "/tmp/deleted-wiki-root",
realPath: null,
access: "readWrite",
readable: false,
writable: false,
requiredDirectories: ["raw", "wiki"],
requiredFiles: ["AGENTS.md"],
missingDirectories: ["raw", "wiki"],
missingFiles: ["AGENTS.md"],
healthy: false,
problems: [
{ code: "missing", message: "Configured local folder cannot be inspected.", path: "/tmp/deleted-wiki-root" },
],
checkedAt: new Date().toISOString(),
};
const markup = renderWikiPage();
expect(markup).toContain("Repair wiki root folder");
expect(markup).toContain("/tmp/deleted-wiki-root");
expect(markup).toContain("Configured local folder cannot be inspected.");
expect(markup).toContain("Repair &amp; bootstrap");
expect(markup).not.toContain("Failed to read AGENTS.md");
expect(markup).not.toContain(">AGENTS.md</h1>");
});
it("serializes root template pages as regular path segments", () => {
mockAutoSelectFile = "AGENTS.md";
renderToStaticMarkup(createElement(WikiRouteSidebar, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
expect(mockNavigatedTo).toBe("/wiki/page/AGENTS.md");
});
it("highlights Settings for legacy lint links after lint moved under Settings", () => {
mockPathname = "/PAP/wiki/lint";
const markup = renderToStaticMarkup(createElement(WikiRouteSidebar, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
expect(markup).not.toContain('href="/PAP/wiki/lint"');
const settingsAnchor = markup.match(/<a[^>]*href="\/PAP\/wiki\/settings"[^>]*>/);
expect(settingsAnchor?.[0]).toContain('aria-current="page"');
expect(settingsAnchor?.[0]).toContain("text-foreground");
expect(settingsAnchor?.[0]).not.toContain("bg-accent");
const askAnchor = markup.match(/<a[^>]*href="\/PAP\/wiki\/query"[^>]*>/);
expect(askAnchor?.[0]).not.toContain('aria-current="page"');
});
it("renders the maintainer settings without plugin metadata or inline AGENTS.md editing", () => {
mockPathname = "/PAP/wiki/settings/maintainer";
const markup = renderWikiPage();
expect(markup).toContain("Wiki Maintainer");
expect(markup).toContain("Adapter: claude local");
expect(markup).toContain("Maintainer");
expect(markup).toContain("Repair");
expect(markup).toContain("Reset to defaults");
expect(markup).not.toContain("Provided maintainer");
expect(markup).not.toContain("Managed by LLM Wiki");
expect(markup).not.toContain("Suggested default");
expect(markup).not.toContain("AGENT INSTRUCTIONS");
expect(markup).not.toContain("Stable key");
expect(markup).not.toContain("Plugin managed default");
});
it("recommends approval when the wiki maintainer is pending board approval", () => {
mockPathname = "/PAP/wiki/settings/maintainer";
mockSettingsManagedAgent = {
status: "created",
source: "managed",
agentId: "agent-1",
resourceKey: "wiki-maintainer",
details: { name: "Wiki Maintainer", status: "pending_approval", adapterType: "claude_local", icon: "book-open", urlKey: "wiki-maintainer" },
};
const markup = renderWikiPage();
expect(markup).toContain("pending approval");
expect(markup).toContain("Approve the agent");
expect(markup).toContain("Adapter: claude local");
});
it("renders root settings as a compact health checklist with the shared path picker", () => {
mockPathname = "/PAP/wiki/settings";
const markup = renderWikiPage();
expect(markup).toContain(">Setup</");
expect(markup).toContain("Base Folder");
expect(markup).toContain("Managed Agents");
expect(markup).toContain("Managed Skills");
expect(markup).toContain("Managed Projects");
expect(markup).toContain("Managed Routines");
expect(markup.indexOf(">Managed Agents</h2>")).toBeLessThan(markup.indexOf(">Managed Skills</h2>"));
expect(markup.indexOf(">Managed Skills</h2>")).toBeLessThan(markup.indexOf(">Managed Projects</h2>"));
expect(markup.indexOf(">Managed Projects</h2>")).toBeLessThan(markup.indexOf(">Managed Routines</h2>"));
expect(markup).toContain("Adapter: claude local");
expect(markup).toContain("Status: in progress");
expect(markup).toContain("Wiki root health checklist");
expect(markup).toContain("Health check");
expect(markup).toContain("Wiki agents health checklist");
expect(markup).toContain("Wiki routines health checklist");
expect(markup).toContain("Wiki skills health checklist");
expect(markup).toContain("Wiki projects health checklist");
const routineChecklistStart = markup.indexOf('aria-label="Wiki routines health checklist"');
const routineChecklist = markup.slice(routineChecklistStart);
expect(routineChecklist).toContain("left:8px");
expect(routineChecklist).toContain("background:oklch(0.38 0.09 145)");
expect(routineChecklist).toContain("Process LLM Wiki updates");
expect(routineChecklist).toContain("Run LLM Wiki lint");
expect(routineChecklist).toContain("Refresh LLM Wiki index");
expect(routineChecklist).not.toContain("Wiki Maintainer");
expect(routineChecklist).not.toContain("LLM Wiki project");
const skillChecklistStart = markup.indexOf('aria-label="Wiki skills health checklist"');
const skillChecklist = markup.slice(skillChecklistStart, markup.indexOf('aria-label="Wiki projects health checklist"'));
expect(skillChecklist).toContain("left:8px");
expect(skillChecklist).toContain("background:oklch(0.38 0.09 145)");
for (const headline of ["Path configured", "Readable", "Writable", "Baseline files", "Wiki folders"]) {
expect(markup).toContain(headline);
}
expect(markup).toContain("Local wiki folder");
expect(markup).toContain("Choose");
expect(markup).toContain("Apply path");
expect(markup).not.toContain("AGENTS.md, IDEA.md");
expect(markup).not.toContain("Ready</span>");
expect(markup).not.toContain("Needs attention</span>");
expect(markup).not.toContain("wiki/sources/");
expect(markup).not.toContain("wiki/entities/");
expect(markup).not.toContain("Wiki root folder");
expect(markup).not.toContain("Provided maintainer");
expect(markup).not.toContain(">Project</span>");
expect(markup).toContain("Ingestion Settings");
});
it("shows a top-level fix-all banner when settings configuration has errors", () => {
mockPathname = "/PAP/wiki/settings";
mockSettingsFolder = {
configured: true,
path: "/tmp/company-wiki",
realPath: "/tmp/company-wiki",
access: "readWrite",
readable: true,
writable: true,
requiredDirectories: ["raw", "wiki"],
requiredFiles: ["AGENTS.md"],
missingDirectories: ["raw"],
missingFiles: ["AGENTS.md"],
healthy: false,
problems: [
{ code: "missing_directory", message: "Required directory is missing.", path: "raw" },
{ code: "missing_file", message: "Required file is missing.", path: "AGENTS.md" },
],
checkedAt: new Date().toISOString(),
};
const markup = renderWikiPage();
expect(markup).toContain("configuration errors detected, fix them all?");
expect(markup).toContain("Wiki root folder");
expect(markup).toContain("Managed routines");
expect(markup).toContain("need attention.");
expect(markup).toContain("Fix them all");
expect(markup.indexOf("configuration errors detected")).toBeLessThan(markup.indexOf(">Base Folder</"));
});
it("shows missing managed skills in setup health with a re-sync action", () => {
mockPathname = "/PAP/wiki/settings";
mockSettingsManagedSkills = [{
status: "missing",
skillId: null,
resourceKey: WIKI_MAINTAINER_SKILL_KEY,
details: {
name: "LLM Wiki Maintainer",
key: WIKI_MAINTAINER_SKILL_CANONICAL_KEY,
description: null,
},
}];
const markup = renderWikiPage();
expect(markup).toContain("Managed Skills");
expect(markup).toContain("skill issue(s) need attention");
expect(markup).toContain("LLM Wiki Maintainer is not installed in the company skill library.");
expect(markup).toContain("Re-sync skills");
});
it("shows managed skill default drift in setup health", () => {
mockPathname = "/PAP/wiki/settings";
mockSettingsManagedSkills = [{
status: "resolved",
skillId: "skill-1",
resourceKey: WIKI_MAINTAINER_SKILL_KEY,
defaultDrift: { changedFiles: ["SKILL.md"] },
details: {
name: "LLM Wiki Maintainer",
key: WIKI_MAINTAINER_SKILL_CANONICAL_KEY,
description: null,
},
}];
const markup = renderWikiPage();
expect(markup).toContain("skill issue(s) need attention");
expect(markup).toContain("LLM Wiki Maintainer differs from the plugin default: SKILL.md.");
expect(markup).toContain("Re-sync skills");
});
it("renders host settings directly as the Setup page without an extra plugin heading", () => {
const markup = renderToStaticMarkup(createElement(SettingsPage, {
context: { companyId: COMPANY_ID, companyPrefix: "PAP" },
} as never));
expect(markup).toContain(">Setup</h1>");
expect(markup).toContain("Base Folder");
expect(markup).not.toContain("LLM Wiki Settings");
expect(markup).not.toContain("These settings live inside the plugin");
});
it("renders project settings as a project picker without managed-resource metadata", () => {
mockPathname = "/PAP/wiki/settings/project";
const markup = renderWikiPage();
expect(markup).toContain("Use existing project");
expect(markup).toContain("LLM Wiki");
expect(markup).toContain("Save project");
expect(markup).toContain("Open project");
expect(markup).toContain("Repair / reconcile");
expect(markup).toContain("Reset to plugin defaults");
expect(markup).not.toContain("Managed by LLM Wiki");
expect(markup).not.toContain("Operations project binding");
expect(markup).not.toContain("Stable key");
expect(markup).not.toContain("Resolved project");
expect(markup).toContain("Status: in progress");
expect(markup).not.toContain("Plugin managed default");
});
it("renders space settings with health line styling and disabled access controls", () => {
mockPathname = "/PAP/wiki/settings/spaces/default";
const markup = renderWikiPage();
expect(markup).toContain("Space folder health checklist");
expect(markup).toContain("left:8px");
expect(markup).toContain("background:oklch(0.38 0.09 145)");
expect(markup).toContain("Folder readable");
expect(markup).toContain("raw/ present");
expect(markup).toContain("Access");
expect(markup).toContain("Coming soon");
expect(markup).not.toContain("Future enforcement");
expect(markup).not.toContain("stored only");
expect(markup).not.toContain("Permissions are stored but not enforced");
});
it("renders distillation settings with assigned-agent execution without budget controls", () => {
mockPathname = "/PAP/wiki/settings/distillation";
mockDistillationOverviewData = {
counts: { cursors: 1, runningRuns: 0, failedRuns24h: 0, reviewRequired: 0 },
cursors: [{
id: "cursor-1",
projectId: "project-1",
rootIssueId: null,
projectName: "Existing Wiki Project",
rootIssueIdentifier: null,
sourceScope: "project",
scopeKey: "project-1",
}],
runs: [],
};
const markup = renderWikiPage();
expect(markup).toContain("Agent execution");
expect(markup).toContain("Assigned maintainer");
expect(markup).toContain("Wiki Maintainer · claude local");
expect(markup).toContain("All sections — apply when source hash matches and confidence");
expect(markup).not.toContain("Per-task budget");
expect(markup).not.toContain("Project total budget");
expect(markup).not.toContain("/task");
expect(markup).not.toContain("Model lanes");
expect(markup).not.toContain("Claude Haiku");
expect(markup).not.toContain("Daily plugin cap");
expect(markup).not.toContain("Monthly plugin cap");
});
it("passes managed routine titles, bindings, and configuration links to the host list", () => {
mockPathname = "/PAP/wiki/settings/routines";
mockSettingsManagedRoutines = [{
status: "resolved",
routineId: "routine-1",
resourceKey: "nightly-wiki-lint",
routine: {
id: "routine-1",
title: "Run LLM Wiki lint",
status: "active",
assigneeAgentId: "agent-1",
projectId: "project-1",
lastTriggeredAt: "2026-05-03T12:00:00Z",
managedByPlugin: { pluginDisplayName: "LLM Wiki", resourceKey: "nightly-wiki-lint" },
},
details: { cronExpression: "0 3 * * *" },
}];
const markup = renderWikiPage();
expect(markup).toContain("Run LLM Wiki lint");
expect(markup).toContain("Configure");
expect(markup).toContain("LLM Wiki · Wiki Maintainer");
expect(markup).toContain("href=\"/PAP/routines/routine-1\"");
});
it("alerts when managed routine defaults changed and offers a reset path", () => {
mockPathname = "/PAP/wiki/settings/routines";
mockSettingsManagedRoutines = [{
status: "resolved",
routineId: "routine-1",
resourceKey: "nightly-wiki-lint",
defaultDrift: {
changedFields: ["description"],
defaultTitle: "Run LLM Wiki lint",
defaultDescription: "Updated instructions",
},
routine: {
id: "routine-1",
title: "Run LLM Wiki lint",
status: "active",
assigneeAgentId: "agent-1",
projectId: "project-1",
managedByPlugin: { pluginDisplayName: "LLM Wiki", resourceKey: "nightly-wiki-lint" },
},
details: { cronExpression: "0 3 * * *" },
}];
const markup = renderWikiPage();
expect(markup).toContain("Routine defaults changed");
expect(markup).toContain("Plugin defaults changed: description");
expect(markup).toContain(">Reset</button>");
});
it("shows managed agent instruction drift in the setup health check", () => {
mockPathname = "/PAP/wiki/settings";
mockSettingsManagedAgent = {
status: "resolved",
source: "managed",
agentId: "agent-1",
resourceKey: "wiki-maintainer",
defaultDrift: { entryFile: "AGENTS.md", changedFiles: ["AGENTS.md"] },
details: { name: "Wiki Maintainer", status: "idle", adapterType: "claude_local", icon: "book-open", urlKey: "wiki-maintainer" },
};
const markup = renderWikiPage();
expect(markup).toContain("Wiki Maintainer instructions differ from the plugin default: AGENTS.md.");
expect(markup).toContain("Wiki Maintainer instruction defaults changed: AGENTS.md");
});
it("shows one routine repair warning instead of per-routine reconcile controls", () => {
mockPathname = "/PAP/wiki/settings/routines";
mockSettingsManagedRoutines = [{
status: "resolved",
routineId: "routine-1",
resourceKey: "nightly-wiki-lint",
routine: {
id: "routine-1",
title: "Run LLM Wiki lint",
status: "active",
assigneeAgentId: "other-agent",
projectId: "project-1",
managedByPlugin: { pluginDisplayName: "LLM Wiki", resourceKey: "nightly-wiki-lint" },
},
details: { cronExpression: "0 3 * * *" },
}];
const markup = renderWikiPage();
expect(markup).toContain("Routine setup needs repair");
expect(markup).toContain("Fix routines");
expect(markup).toContain("not assigned to the Wiki Maintainer");
expect(markup).not.toContain("Plugin-managed routine defaults can be reconciled from here");
expect(markup).not.toContain(">Reconcile</button>");
expect(markup).not.toContain(">Reset</button>");
});
it("renders legacy lint routes inside the Wiki settings section", () => {
mockPathname = "/PAP/wiki/lint";
const markup = renderWikiPage();
expect(markup).toContain("Run lint now");
expect(markup).toContain("Recent lint runs");
expect(markup).toContain("LLM Wiki settings sections");
});
it("does not expose IDEA.md pattern editing as a settings section", () => {
mockPathname = "/PAP/wiki/settings";
const markup = renderWikiPage();
expect(markup).toContain("LLM Wiki settings sections");
expect(markup).not.toContain(">Pattern</span>");
expect(markup).not.toContain("Pattern · IDEA.md");
expect(markup).not.toContain("IDEA.md skeleton reference");
});
it("does not expose plugin capabilities as a settings section", () => {
mockPathname = "/PAP/wiki/settings";
const markup = renderWikiPage();
expect(markup).toContain("LLM Wiki settings sections");
expect(markup).not.toContain("Plugin capabilities");
expect(markup).not.toContain("api.routes.register");
});
it("reconciles managed maintenance routines through stable agent and project refs", async () => {
const harness = createTestHarness({ manifest });
const writes = captureWikiWrites(harness);
await plugin.definition.setup(harness.ctx);
const missing = await harness.performAction<PluginManagedRoutineResolution>("reconcile-managed-routine", {
companyId: COMPANY_ID,
routineKey: NIGHTLY_LINT_ROUTINE_KEY,
});
expect(missing.status).toBe("missing_refs");
expect(missing.missingRefs).toEqual([
expect.objectContaining({ resourceKind: "agent", resourceKey: WIKI_MAINTAINER_AGENT_KEY }),
expect.objectContaining({ resourceKind: "project", resourceKey: WIKI_PROJECT_KEY }),
]);
await harness.performAction("bootstrap-root", { companyId: COMPANY_ID, path: "/tmp/company-wiki" });
const reconciled = await Promise.all(
WIKI_MAINTENANCE_ROUTINE_KEYS.map((routineKey) =>
harness.performAction<PluginManagedRoutineResolution>("reconcile-managed-routine", {
companyId: COMPANY_ID,
routineKey,
})),
);
expect(reconciled.map((routine) => routine.resourceKey)).toEqual([...WIKI_MAINTENANCE_ROUTINE_KEYS]);
expect(reconciled).toEqual(
expect.arrayContaining([
expect.objectContaining({
resourceKey: NIGHTLY_LINT_ROUTINE_KEY,
routine: expect.objectContaining({
projectId: expect.any(String),
assigneeAgentId: expect.any(String),
managedByPlugin: expect.objectContaining({
defaultsJson: expect.objectContaining({
issueTemplate: expect.objectContaining({ surfaceVisibility: "plugin_operation" }),
}),
}),
}),
}),
expect.objectContaining({ resourceKey: INDEX_REFRESH_ROUTINE_KEY, routineId: expect.any(String) }),
]),
);
});
it("requires an explicit managed routine key for single-routine actions", async () => {
const harness = createTestHarness({ manifest });
await plugin.definition.setup(harness.ctx);
await expect(harness.performAction("reconcile-managed-routine", {
companyId: COMPANY_ID,
})).rejects.toThrow("routineKey is required");
});
it("repairs all managed maintenance routines through one action", async () => {
const harness = createTestHarness({ manifest });
await plugin.definition.setup(harness.ctx);
await harness.performAction("bootstrap-root", { companyId: COMPANY_ID, path: "/tmp/company-wiki" });
const repaired = await harness.performAction<{
managedRoutines: PluginManagedRoutineResolution[];
}>("reconcile-managed-routines", { companyId: COMPANY_ID });
expect(repaired.managedRoutines).toHaveLength(WIKI_MAINTENANCE_ROUTINE_KEYS.length);
expect(repaired.managedRoutines.map((routine) => routine.resourceKey)).toEqual([...WIKI_MAINTENANCE_ROUTINE_KEYS]);
for (const routine of repaired.managedRoutines) {
expect(routine.routine).toEqual(expect.objectContaining({
assigneeAgentId: expect.any(String),
projectId: expect.any(String),
}));
expect(routine.missingRefs).toEqual([]);
}
});
it("installs and resets managed company skills through setup actions", async () => {
const harness = createTestHarness({ manifest });
await plugin.definition.setup(harness.ctx);
const before = await harness.getData<{ managedSkills: WikiSkillResource[] }>("settings", {
companyId: COMPANY_ID,
});
expect(before.managedSkills.map((skill) => skill.resourceKey)).toEqual([...WIKI_MANAGED_SKILL_KEYS]);
expect(before.managedSkills[0]).toMatchObject({
status: "missing",
skillId: null,
});
const repaired = await harness.performAction<{
managedSkills: WikiSkillResource[];
}>("reconcile-managed-skills", { companyId: COMPANY_ID });
expect(repaired.managedSkills).toHaveLength(WIKI_MANAGED_SKILL_KEYS.length);
expect(repaired.managedSkills[0]).toMatchObject({
status: "created",
skillId: expect.any(String),
resourceKey: WIKI_MAINTAINER_SKILL_KEY,
details: {
name: "LLM Wiki Maintainer",
key: WIKI_MAINTAINER_SKILL_CANONICAL_KEY,
},
});
const resolved = await harness.getData<{ managedSkills: WikiSkillResource[] }>("settings", {
companyId: COMPANY_ID,
});
expect(resolved.managedSkills[0]).toMatchObject({
status: "resolved",
resourceKey: WIKI_MAINTAINER_SKILL_KEY,
details: { key: WIKI_MAINTAINER_SKILL_CANONICAL_KEY },
});
const reset = await harness.performAction<{
managedSkills: WikiSkillResource[];
}>("reset-managed-skills", { companyId: COMPANY_ID });
expect(reset.managedSkills[0]).toMatchObject({
status: "reset",
skillId: expect.any(String),
resourceKey: WIKI_MAINTAINER_SKILL_KEY,
});
});
it("registers worker data, actions, and tools", async () => {
const harness = createTestHarness({ manifest });
await plugin.definition.setup(harness.ctx);
const overview = await harness.getData<{ status: string; operationCount: number; eventIngestion: { enabled: boolean } }>("overview", {
companyId: COMPANY_ID,
});
expect(overview.status).toBe("ok");
expect(overview.operationCount).toBe(0);
expect(overview.eventIngestion.enabled).toBe(false);
const pages = await harness.executeTool<{ content?: string }>("wiki_list_pages", {
companyId: COMPANY_ID,
wikiId: "default",
});
expect(pages.content).toBe("No pages indexed yet.");
});
it("filters stale page and raw source rows out of browse data", async () => {
const harness = createTestHarness({ manifest });
const files = new Map<string, string>([
["wiki/concepts/live.md", "# Live Page\n"],
["raw/live-source.md", "# Live Source\n"],
]);
const now = new Date().toISOString();
harness.ctx.localFolders.readText = async (_companyId, _folderKey, relativePath) => {
const contents = files.get(relativePath);
if (contents == null) throw new Error(`missing ${relativePath}`);
return contents;
};
harness.ctx.db.query = async <T = Record<string, unknown>>(sql: string, params?: unknown[]) => {
harness.dbQueries.push({ sql, params });
if (sql.includes("wiki_pages")) {
return [
{
path: "wiki/concepts/live.md",
title: "Live Page",
page_type: "concepts",
backlinks: [],
source_refs: [],
content_hash: "live",
updated_at: now,
},
{
path: "wiki/concepts/stale.md",
title: "Stale Page",
page_type: "concepts",
backlinks: [],
source_refs: [],
content_hash: "stale",
updated_at: now,
},
] as T[];
}
if (sql.includes("wiki_sources")) {
return [
{
raw_path: "raw/missing-source.md",
title: "Missing Source",
source_type: "text",
url: null,
status: "captured",
created_at: now,
},
{
raw_path: "raw/live-source.md",
title: "Live Source",
source_type: "text",
url: null,
status: "captured",
created_at: now,
},
] as T[];
}
return [];
};
await plugin.definition.setup(harness.ctx);
const result = await harness.getData<{
pages: Array<{ path: string }>;
sources: Array<{ rawPath: string }>;
}>("pages", {
companyId: COMPANY_ID,
wikiId: "default",
includeRaw: true,
});
expect(result.pages.map((page) => page.path)).toEqual(["wiki/concepts/live.md"]);
expect(result.sources.map((source) => source.rawPath)).toEqual(["raw/live-source.md"]);
});
it("includes local wiki files in browse data before metadata is indexed", async () => {
const harness = createTestHarness({ manifest });
const modifiedAt = new Date().toISOString();
harness.ctx.localFolders.list = async (_companyId, folderKey, options) => ({
folderKey,
relativePath: options?.relativePath ?? null,
truncated: false,
entries: options?.relativePath === "wiki"
? [
{ path: "wiki/concepts/agent-memory-layer.md", name: "agent-memory-layer.md", kind: "file", size: 12, modifiedAt },
{ path: "wiki/entities/paperclip.md", name: "paperclip.md", kind: "file", size: 10, modifiedAt },
{ path: "wiki/projects/llm-wiki/standup.md", name: "standup.md", kind: "file", size: 16, modifiedAt },
]
: [
{ path: "raw/2026-04-09-thomas-gieselmann-fundraising-call.md", name: "2026-04-09-thomas-gieselmann-fundraising-call.md", kind: "file", size: 14, modifiedAt },
],
});
harness.ctx.db.query = async <T = Record<string, unknown>>(sql: string, params?: unknown[]) => {
harness.dbQueries.push({ sql, params });
return [] as T[];
};
await plugin.definition.setup(harness.ctx);
const result = await harness.getData<{
pages: Array<{ path: string; title: string | null }>;
sources: Array<{ rawPath: string; title: string | null }>;
}>("pages", {
companyId: COMPANY_ID,
wikiId: "default",
includeRaw: true,
});
expect(result.pages).toEqual([
expect.objectContaining({ path: "wiki/concepts/agent-memory-layer.md", title: null }),
expect.objectContaining({ path: "wiki/entities/paperclip.md", title: null }),
expect.objectContaining({ path: "wiki/projects/llm-wiki/standup.md", title: null }),
]);
expect(result.sources).toEqual([
expect.objectContaining({ rawPath: "raw/2026-04-09-thomas-gieselmann-fundraising-call.md", title: null }),
]);
});
it("does not ingest Paperclip events until operator controls enable them", async () => {
const harness = createTestHarness({ manifest });
const issue = paperclipIssue();
harness.seed({ issues: [issue] });
const writes = captureWikiWrites(harness);
await plugin.definition.setup(harness.ctx);
await harness.emit("issue.created", { identifier: issue.identifier }, {
companyId: COMPANY_ID,
entityId: issue.id,
entityType: "issue",
eventId: "event-disabled-issue-created",
});
expect(writes).toHaveLength(0);
expect(harness.dbExecutes.some((execute) => execute.sql.includes("wiki_sources"))).toBe(false);
expect(harness.dbExecutes.some((execute) => execute.sql.includes("wiki_operations"))).toBe(false);
});
it("records enabled Paperclip issue events as cursor observations without creating ingest operations", async () => {
const harness = createTestHarness({ manifest });
const issue = paperclipIssue();
harness.seed({ issues: [issue] });
const writes = captureWikiWrites(harness);
await plugin.definition.setup(harness.ctx);
const policy = await harness.performAction<{ enabled: boolean; sources: { issues: boolean; comments: boolean; documents: boolean } }>(
"update-event-ingestion-settings",
{
companyId: COMPANY_ID,
enabled: true,
sources: { issues: true, comments: false, documents: false },
},
);
expect(policy).toMatchObject({ enabled: true, sources: { issues: true, comments: false, documents: false } });
await harness.emit("issue.created", { identifier: issue.identifier }, {
companyId: COMPANY_ID,
entityId: issue.id,
entityType: "issue",
eventId: "event-enabled-issue-created",
});
expect(writes).toHaveLength(0);
const operations = await harness.ctx.issues.list({
companyId: COMPANY_ID,
originKindPrefix: String(OPERATION_ORIGIN_KIND),
});
expect(operations).toHaveLength(0);
expect(harness.dbExecutes.some((execute) => execute.sql.includes("wiki_sources"))).toBe(false);
expect(harness.dbExecutes.some((execute) => execute.sql.includes("wiki_operations"))).toBe(false);
const cursorUpsert = harness.dbExecutes.find((execute) => execute.sql.includes("paperclip_distillation_cursors"));
expect(cursorUpsert?.params).toEqual(expect.arrayContaining([
COMPANY_ID,
"default",
"company",
null,
null,
]));
});
it("preserves Paperclip event ingestion sources when only enabled changes", async () => {
const harness = createTestHarness({ manifest });
await plugin.definition.setup(harness.ctx);
await harness.performAction("update-event-ingestion-settings", {
companyId: COMPANY_ID,
enabled: true,
sources: { issues: true, comments: true, documents: true },
});
const disabled = await harness.performAction<{
enabled: boolean;
sources: { issues: boolean; comments: boolean; documents: boolean };
}>("update-event-ingestion-settings", {
companyId: COMPANY_ID,
enabled: false,
});
expect(disabled).toMatchObject({
enabled: false,
sources: { issues: true, comments: true, documents: true },
});
const reenabled = await harness.performAction<{
enabled: boolean;
sources: { issues: boolean; comments: boolean; documents: boolean };
}>("update-event-ingestion-settings", {
companyId: COMPANY_ID,
enabled: true,
});
expect(reenabled).toMatchObject({
enabled: true,
sources: { issues: true, comments: true, documents: true },
});
});
it("keeps Paperclip event cursor observations company scoped and ignores plugin-operation issues", async () => {
const harness = createTestHarness({ manifest });
const visibleIssue = paperclipIssue({ projectId: "77777777-7777-4777-8777-777777777777" });
const otherCompanyIssue = paperclipIssue({
id: "77777777-7777-4777-8777-777777777778",
companyId: OTHER_COMPANY_ID,
projectId: "77777777-7777-4777-8777-777777777779",
identifier: "PAP-9999",
});
const operationIssue = paperclipIssue({
id: "77777777-7777-4777-8777-777777777780",
originKind: `${OPERATION_ORIGIN_KIND}:ingest`,
});
harness.seed({ issues: [visibleIssue, otherCompanyIssue, operationIssue] });
await plugin.definition.setup(harness.ctx);
await harness.performAction("update-event-ingestion-settings", {
companyId: COMPANY_ID,
enabled: true,
sources: { issues: true, comments: true, documents: true },
});
await harness.emit("issue.updated", {}, {
companyId: COMPANY_ID,
entityId: visibleIssue.id,
entityType: "issue",
eventId: "event-visible",
});
await harness.emit("issue.updated", {}, {
companyId: OTHER_COMPANY_ID,
entityId: otherCompanyIssue.id,
entityType: "issue",
eventId: "event-other-company",
});
await harness.emit("issue.updated", {}, {
companyId: COMPANY_ID,
entityId: operationIssue.id,
entityType: "issue",
eventId: "event-plugin-operation",
});
const cursorWrites = harness.dbExecutes.filter((execute) => execute.sql.includes("paperclip_distillation_cursors"));
expect(cursorWrites).toHaveLength(1);
expect(cursorWrites[0].params).toEqual(expect.arrayContaining([
COMPANY_ID,
"default",
"project",
visibleIssue.projectId,
]));
});
it("routes Paperclip issue, comment, and document event cursors only to the default space", async () => {
const harness = createTestHarness({ manifest });
const issue = paperclipIssue({ projectId: "77777777-7777-4777-8777-777777777777" });
harness.seed({ issues: [issue] });
await plugin.definition.setup(harness.ctx);
const created = await harness.performAction<{
space: { id: string; slug: string };
}>("create-space", {
companyId: COMPANY_ID,
displayName: "Team Research",
});
await harness.performAction("update-event-ingestion-settings", {
companyId: COMPANY_ID,
enabled: true,
sources: { issues: true, comments: true, documents: true },
});
await harness.emit("issue.created", {}, {
companyId: COMPANY_ID,
entityId: issue.id,
entityType: "issue",
eventId: "event-default-issue-created",
});
await harness.emit("issue.comment.created", { commentId: "comment-1" }, {
companyId: COMPANY_ID,
entityId: issue.id,
entityType: "issue",
eventId: "event-default-comment-created",
});
await harness.emit("issue.document.updated", { key: "plan", revisionId: "revision-1" }, {
companyId: COMPANY_ID,
entityId: issue.id,
entityType: "issue",
eventId: "event-default-document-updated",
});
const cursorWrites = harness.dbExecutes.filter((execute) => execute.sql.includes("paperclip_distillation_cursors"));
expect(cursorWrites).toHaveLength(3);
expect(cursorWrites.every((execute) => execute.params?.[10] !== created.space.id)).toBe(true);
expect(cursorWrites.map((execute) => execute.params?.[2])).toEqual(["default", "default", "default"]);
expect(String(cursorWrites[0].params?.[9])).toContain('"lastSourceKind":"issues"');
expect(String(cursorWrites[1].params?.[9])).toContain('"lastSourceKind":"comments"');
expect(String(cursorWrites[2].params?.[9])).toContain('"lastSourceKind":"documents"');
});
it("routes Paperclip events into an explicitly enabled shared non-default space", async () => {
const harness = createTestHarness({ manifest });
const project = existingProject();
const issue = paperclipIssue({ projectId: project.id });
harness.seed({ projects: [project], issues: [issue] });
await plugin.definition.setup(harness.ctx);
const created = await harness.performAction<{
space: { id: string; slug: string };
}>("create-space", {
companyId: COMPANY_ID,
displayName: "Engineering Wiki",
accessScope: "shared",
});
mockPersistedWikiSpace(harness, created.space as unknown as Record<string, unknown>);
const enabledProfile = {
version: 1,
enabled: true,
sourceScopes: [{ kind: "selected_projects", projectIds: [project.id] }],
sourceKinds: { issues: true, comments: true, documents: true, attachments: "off", workProducts: "off" },
cursor: { maxWindowCharacters: 60000, maxCharactersPerSource: 12000, minSourceAgeMinutes: 15, maxWindowsPerRun: 6, staleAfterHours: 72 },
backfill: { requireManualQueue: true },
};
await harness.performAction("update-paperclip-ingestion-profile", {
companyId: COMPANY_ID,
spaceSlug: created.space.slug,
profile: enabledProfile,
});
mockPersistedWikiSpace(harness, { ...(created.space as unknown as Record<string, unknown>), settings: { paperclipIngestion: enabledProfile } });
await harness.emit("issue.created", {}, {
companyId: COMPANY_ID,
entityId: issue.id,
entityType: "issue",
eventId: "event-non-default-enabled",
});
const cursorWrites = harness.dbExecutes.filter((execute) => execute.sql.includes("paperclip_distillation_cursors"));
expect(cursorWrites.some((execute) => execute.params?.[10] === created.space.id)).toBe(true);
});
it("stops new non-default observations after the per-space profile is disabled", async () => {
const harness = createTestHarness({ manifest });
const project = existingProject();
const issue = paperclipIssue({ projectId: project.id });
harness.seed({ projects: [project], issues: [issue] });
await plugin.definition.setup(harness.ctx);
const created = await harness.performAction<{
space: { id: string; slug: string };
}>("create-space", {
companyId: COMPANY_ID,
displayName: "Support Wiki",
accessScope: "shared",
});
mockPersistedWikiSpace(harness, created.space as unknown as Record<string, unknown>);
const enabledProfile = {
version: 1,
enabled: true,
sourceScopes: [{ kind: "selected_projects", projectIds: [project.id] }],
sourceKinds: { issues: true, comments: false, documents: false, attachments: "off", workProducts: "off" },
cursor: { maxWindowCharacters: 60000, maxCharactersPerSource: 12000, minSourceAgeMinutes: 15, maxWindowsPerRun: 6, staleAfterHours: 72 },
backfill: { requireManualQueue: true },
};
await harness.performAction("update-paperclip-ingestion-profile", {
companyId: COMPANY_ID,
spaceSlug: created.space.slug,
profile: enabledProfile,
});
mockPersistedWikiSpace(harness, { ...(created.space as unknown as Record<string, unknown>), settings: { paperclipIngestion: enabledProfile } });
await harness.emit("issue.created", {}, {
companyId: COMPANY_ID,
entityId: issue.id,
entityType: "issue",
eventId: "event-before-disable",
});
await harness.performAction("update-paperclip-ingestion-profile", {
companyId: COMPANY_ID,
spaceSlug: created.space.slug,
profile: { ...enabledProfile, enabled: false },
});
mockPersistedWikiSpace(harness, { ...(created.space as unknown as Record<string, unknown>), settings: { paperclipIngestion: { ...enabledProfile, enabled: false } } });
await harness.emit("issue.updated", {}, {
companyId: COMPANY_ID,
entityId: issue.id,
entityType: "issue",
eventId: "event-after-disable",
});
const nonDefaultCursorWrites = harness.dbExecutes.filter((execute) =>
execute.sql.includes("paperclip_distillation_cursors") && execute.params?.[10] === created.space.id);
expect(nonDefaultCursorWrites).toHaveLength(1);
});
it("assembles deterministic Paperclip source bundles with issue, document, and comment provenance", async () => {
const harness = createTestHarness({ manifest });
const root = paperclipIssue({
id: "77777777-7777-4777-8777-777777777781",
identifier: "PAP-4000",
title: "Root distillation issue",
projectId: "77777777-7777-4777-8777-777777777777",
updatedAt: new Date("2026-05-01T10:00:00Z"),
});
const child = paperclipIssue({
id: "77777777-7777-4777-8777-777777777782",
identifier: "PAP-4001",
title: "Child source issue",
parentId: root.id,
projectId: root.projectId,
description: "Child issue has a decision and implementation notes.",
updatedAt: new Date("2026-05-02T10:00:00Z"),
});
harness.seed({
issues: [root, child],
issueComments: [{
id: "77777777-7777-4777-8777-777777777783",
companyId: COMPANY_ID,
issueId: child.id,
authorType: "user",
authorAgentId: null,
authorUserId: null,
onBehalfOfUserId: null,
body: "Comment evidence for the source bundle.",
presentation: null,
metadata: null,
createdAt: new Date("2026-05-03T10:00:00Z"),
updatedAt: new Date("2026-05-03T10:00:00Z"),
}],
});
await plugin.definition.setup(harness.ctx);
await harness.ctx.issues.documents.upsert({
companyId: COMPANY_ID,
issueId: child.id,
key: "plan",
title: "Plan",
body: "Document evidence for the source bundle.",
});
const first = await harness.performAction<{
markdown: string;
sourceRefs: Array<{ kind: string; issueIdentifier: string | null; documentKey?: string; commentId?: string }>;
sourceHash: string;
sourceWindowEnd: string | null;
}>("assemble-paperclip-source-bundle", {
companyId: COMPANY_ID,
rootIssueId: root.id,
maxCharacters: 20000,
});
const second = await harness.performAction<typeof first>("assemble-paperclip-source-bundle", {
companyId: COMPANY_ID,
rootIssueId: root.id,
maxCharacters: 20000,
});
expect(second.sourceHash).toBe(first.sourceHash);
expect(first.markdown).toContain("Root distillation issue");
expect(first.markdown).toContain("Child issue has a decision");
expect(first.markdown).toContain("Document evidence for the source bundle.");
expect(first.markdown).toContain("Comment evidence for the source bundle.");
expect(first.sourceRefs).toEqual(expect.arrayContaining([
expect.objectContaining({ kind: "issue", issueIdentifier: "PAP-4001" }),
expect.objectContaining({ kind: "document", documentKey: "plan" }),
expect.objectContaining({ kind: "comment", commentId: "77777777-7777-4777-8777-777777777783" }),
]));
expect(first.sourceWindowEnd).toEqual(expect.any(String));
});
it("suppresses secret-like comment and document bodies before storing distillation snapshots", async () => {
const harness = createTestHarness({ manifest });
const issue = paperclipIssue({
id: "77777777-7777-4777-8777-777777777784",
identifier: "PAP-4002",
title: "Sensitive source issue",
projectId: "77777777-7777-4777-8777-777777777777",
description: "Keep the project page current without copying credential material into the wiki.",
updatedAt: new Date("2026-05-04T10:00:00Z"),
});
harness.seed({
issues: [issue],
issueComments: [{
id: "77777777-7777-4777-8777-777777777785",
companyId: COMPANY_ID,
issueId: issue.id,
authorType: "user",
authorAgentId: null,
authorUserId: null,
onBehalfOfUserId: null,
body: "Authorization: Bearer ghp_supersecretcommenttoken1234567890",
presentation: null,
metadata: null,
createdAt: new Date("2026-05-04T11:00:00Z"),
updatedAt: new Date("2026-05-04T11:00:00Z"),
}],
});
await plugin.definition.setup(harness.ctx);
await harness.ctx.issues.documents.upsert({
companyId: COMPANY_ID,
issueId: issue.id,
key: "plan",
title: "Plan",
body: "OPENAI_API_KEY=sk-supersecretdocumentvalue1234567890",
});
const run = await harness.performAction<{
bundle: {
markdown: string;
warnings: string[];
sourceRefs: Array<Record<string, unknown>>;
};
}>("create-paperclip-distillation-run", {
companyId: COMPANY_ID,
projectId: issue.projectId,
maxCharacters: 20000,
});
expect(run.bundle.markdown).toContain("Suppressed by LLM Wiki distillation security policy");
expect(run.bundle.markdown).not.toContain("ghp_supersecretcommenttoken1234567890");
expect(run.bundle.markdown).not.toContain("sk-supersecretdocumentvalue1234567890");
expect(run.bundle.warnings).toEqual(expect.arrayContaining([
expect.stringContaining("Suppressed comment content"),
expect.stringContaining("Suppressed document content"),
]));
expect(run.bundle.sourceRefs).toEqual(expect.arrayContaining([
expect.objectContaining({ kind: "comment", redactionStatus: "suppressed_sensitive_content" }),
expect.objectContaining({ kind: "document", redactionStatus: "suppressed_sensitive_content" }),
]));
const snapshotInsert = harness.dbExecutes.find((execute) => execute.sql.includes("paperclip_source_snapshots"));
const storedSourceRefs = String(snapshotInsert?.params?.[9] ?? "");
const storedMarkdown = String(snapshotInsert?.params?.[10] ?? "");
expect(storedSourceRefs).toContain("suppressed_sensitive_content");
expect(storedMarkdown).toContain("Suppressed by LLM Wiki distillation security policy");
expect(storedMarkdown).not.toContain("ghp_supersecretcommenttoken1234567890");
expect(storedMarkdown).not.toContain("sk-supersecretdocumentvalue1234567890");
});
it("creates source snapshots and only advances cursors after successful distillation outcomes", async () => {
const harness = createTestHarness({ manifest });
const issue = paperclipIssue({
projectId: "77777777-7777-4777-8777-777777777777",
updatedAt: new Date("2026-05-02T10:00:00Z"),
});
harness.seed({ issues: [issue] });
await plugin.definition.setup(harness.ctx);
const run = await harness.performAction<{
runId: string;
cursorId: string;
snapshotId: string;
bundle: { sourceHash: string; sourceWindowEnd: string };
}>("create-paperclip-distillation-run", {
companyId: COMPANY_ID,
projectId: issue.projectId,
});
expect(run.snapshotId).toEqual(expect.any(String));
expect(harness.dbExecutes.some((execute) => execute.sql.includes("paperclip_source_snapshots"))).toBe(true);
const failed = await harness.performAction<{ cursorAdvanced: boolean }>("record-paperclip-distillation-outcome", {
companyId: COMPANY_ID,
runId: run.runId,
cursorId: run.cursorId,
status: "failed",
sourceHash: run.bundle.sourceHash,
sourceWindowEnd: run.bundle.sourceWindowEnd,
warning: "writer failed",
});
expect(failed.cursorAdvanced).toBe(false);
const cursorUpdatesAfterFailure = harness.dbExecutes.filter((execute) =>
execute.sql.trim().startsWith("UPDATE") && execute.sql.includes("paperclip_distillation_cursors"));
expect(cursorUpdatesAfterFailure).toHaveLength(0);
const succeeded = await harness.performAction<{ cursorAdvanced: boolean }>("record-paperclip-distillation-outcome", {
companyId: COMPANY_ID,
runId: run.runId,
cursorId: run.cursorId,
status: "succeeded",
sourceHash: run.bundle.sourceHash,
sourceWindowEnd: run.bundle.sourceWindowEnd,
});
expect(succeeded.cursorAdvanced).toBe(true);
const cursorSuccessUpdate = harness.dbExecutes.find((execute) =>
execute.sql.trim().startsWith("UPDATE") && execute.sql.includes("paperclip_distillation_cursors"));
expect(cursorSuccessUpdate?.params).toEqual(expect.arrayContaining([
COMPANY_ID,
"default",
run.runId,
run.bundle.sourceWindowEnd,
run.bundle.sourceHash,
run.cursorId,
]));
});
it("uses the existing distillation cursor id after an upsert conflict", async () => {
const harness = createTestHarness({ manifest });
const project = existingProject();
const issue = paperclipIssue({
id: "77777777-7777-4777-8777-777777777800",
identifier: "PAP-4099",
title: "Existing cursor target",
projectId: project.id,
status: "in_progress",
});
const existingCursorId = "77777777-7777-4777-8777-777777777899";
const originalQuery = harness.ctx.db.query.bind(harness.ctx.db);
harness.ctx.db.query = async <T,>(sql: string, params?: unknown[]) => {
if (sql.includes("SELECT id") && sql.includes("paperclip_distillation_cursors")) {
return [{ id: existingCursorId }] as T[];
}
return originalQuery<T>(sql, params);
};
harness.seed({ projects: [project], issues: [issue] });
await plugin.definition.setup(harness.ctx);
const result = await harness.performAction<{ cursorId: string }>("create-paperclip-distillation-run", {
companyId: COMPANY_ID,
projectId: project.id,
});
expect(result.cursorId).toBe(existingCursorId);
const runInsert = harness.dbExecutes.find((execute) =>
execute.sql.includes("paperclip_distillation_runs") && execute.sql.includes("'source_ready'"));
expect(runInsert?.params?.[3]).toBe(existingCursorId);
});
it("creates explicit distillation work items for manual, retry, and backfill lanes", async () => {
const harness = createTestHarness({ manifest });
await plugin.definition.setup(harness.ctx);
await harness.performAction("create-paperclip-distillation-work-item", {
companyId: COMPANY_ID,
kind: "manual",
projectId: "77777777-7777-4777-8777-777777777777",
idempotencyKey: "manual:project:77777777-7777-4777-8777-777777777777",
});
await harness.performAction("create-paperclip-distillation-work-item", {
companyId: COMPANY_ID,
kind: "retry",
rootIssueId: "77777777-7777-4777-8777-777777777781",
priority: "high",
idempotencyKey: "retry:run:1",
});
await harness.performAction("create-paperclip-distillation-work-item", {
companyId: COMPANY_ID,
kind: "backfill",
projectId: "77777777-7777-4777-8777-777777777777",
priority: "low",
metadata: { window: "last-30-days" },
idempotencyKey: "backfill:last-30-days",
});
const workItemWrites = harness.dbExecutes.filter((execute) => execute.sql.includes("paperclip_distillation_work_items"));
expect(workItemWrites).toHaveLength(3);
expect(workItemWrites.map((write) => write.params?.[3])).toEqual(["manual", "retry", "backfill"]);
expect(String(workItemWrites[0].params?.[9])).toContain('"sourceScope":"project"');
expect(String(workItemWrites[1].params?.[9])).toContain('"sourceScope":"root_issue"');
expect(String(workItemWrites[2].params?.[9])).toContain('"sourceScope":"project"');
await expect(harness.performAction("create-paperclip-distillation-work-item", {
companyId: COMPANY_ID,
kind: "backfill",
idempotencyKey: "backfill:company",
})).rejects.toThrow("whole-company backfill is not allowed");
});
it("records estimated Paperclip distillation cost without refusing on legacy cost config", async () => {
const harness = createTestHarness({
manifest,
config: {
maxPaperclipRoutineRunCostCents: 1,
maxPaperclipDistillationTaskCostCents: 1,
maxPaperclipDistillationProjectCostCents: 1,
paperclipCostCentsPerThousandSourceCharacters: 100,
},
});
const project = existingProject();
const issue = paperclipIssue({
id: "77777777-7777-4777-8777-777777777795",
identifier: "PAP-4104",
title: "Large source bundle",
description: `Accepted plan. ${"Detailed implementation note. ".repeat(160)}`,
projectId: project.id,
status: "in_progress",
});
harness.seed({ projects: [project], issues: [issue] });
await plugin.definition.setup(harness.ctx);
const result = await harness.performAction<{
status: string;
estimatedCostCents: number;
snapshotId: string | null;
}>("create-paperclip-distillation-run", {
companyId: COMPANY_ID,
projectId: project.id,
routineRun: true,
});
expect(result.status).toBe("source_ready");
expect(result.estimatedCostCents).toBeGreaterThan(1);
expect(result.snapshotId).toEqual(expect.any(String));
const readyRun = harness.dbExecutes.find((execute) =>
execute.sql.includes("paperclip_distillation_runs") && execute.sql.includes("'source_ready'"));
expect(readyRun?.params).toEqual(expect.arrayContaining([
COMPANY_ID,
"default",
expect.any(String),
expect.any(String),
null,
project.id,
]));
expect(harness.dbExecutes.some((execute) => execute.sql.includes("paperclip_source_snapshots"))).toBe(true);
expect(harness.dbExecutes.some((execute) => execute.sql.includes("refused_cost_cap"))).toBe(false);
});
it("queues visible manual distill operation issues for a company-wide stale cursor scan", async () => {
const harness = createTestHarness({ manifest });
const project = existingProject();
const issue = paperclipIssue({
id: "77777777-7777-4777-8777-777777777796",
identifier: "PAP-4105",
title: "Manual distillation target",
description: "Implemented enough evidence to manually distill into the wiki.",
status: "done",
projectId: project.id,
});
harness.seed({ agents: [wikiMaintainerAgent()], projects: [project], issues: [issue] });
await plugin.definition.setup(harness.ctx);
const result = await harness.performAction<{
status: string;
operation: { issue: { originKind: string; billingCode: string | null; assigneeAgentId: string | null; assigneeAdapterOverrides: Record<string, unknown> | null; description: string | null } };
workItem: { kind: string; workItemId: string };
}>("distill-paperclip-now", {
companyId: COMPANY_ID,
autoApply: false,
includeSupportingPages: false,
});
expect(result.status).toBe("queued");
expect(result.workItem.kind).toBe("manual");
expect(result.operation.issue.originKind).toBe(`${OPERATION_ORIGIN_KIND}:distill`);
expect(result.operation.issue.billingCode).toBe("plugin-llm-wiki:default");
expect(result.operation.issue.assigneeAgentId).toBe(wikiMaintainerAgent().id);
expect(result.operation.issue.assigneeAdapterOverrides).toBeNull();
expect(result.operation.issue.description).toContain("Prompt source: LLM Wiki plugin action `distill-paperclip-now`");
expect(result.operation.issue.description).toContain(`Required skill: use the installed \`${PAPERCLIP_DISTILL_SKILL_KEY}\` skill`);
expect(result.operation.issue.description).toContain("Do not hardcode a single project");
expect(result.operation.issue.description).not.toContain(`Source project ID: ${project.id}`);
const workItemInsert = harness.dbExecutes.find((execute) =>
execute.sql.includes("paperclip_distillation_work_items") && execute.params?.[3] === "manual");
expect(workItemInsert?.params).toEqual(expect.arrayContaining([
COMPANY_ID,
"default",
"manual",
"medium",
null,
null,
]));
const runInsert = harness.dbExecutes.find((execute) =>
execute.sql.includes("paperclip_distillation_runs") && execute.sql.includes("operation_issue_id"));
expect(runInsert).toBeUndefined();
});
it("enables distillation cursors for the most recently active non-plugin projects", async () => {
const harness = createTestHarness({ manifest });
const recentProject = {
...existingProject(),
id: "77777777-7777-4777-8777-777777777801",
name: "Recent Active Project",
status: "in_progress" as const,
updatedAt: new Date("2026-05-04T18:00:00Z"),
};
const olderProject = {
...existingProject(),
id: "77777777-7777-4777-8777-777777777802",
name: "Older Active Project",
status: "in_progress" as const,
updatedAt: new Date("2026-05-03T18:00:00Z"),
};
const overflowProject = {
...existingProject(),
id: "77777777-7777-4777-8777-777777777803",
name: "Overflow Active Project",
status: "in_progress" as const,
updatedAt: new Date("2026-05-02T18:00:00Z"),
};
const completedProject = {
...existingProject(),
id: "77777777-7777-4777-8777-777777777804",
name: "Completed Project",
status: "completed" as const,
updatedAt: new Date("2026-05-04T19:00:00Z"),
};
const pluginProject = {
...existingProject(),
id: "77777777-7777-4777-8777-777777777805",
name: "LLM Wiki",
status: "in_progress" as const,
updatedAt: new Date("2026-05-04T20:00:00Z"),
managedByPlugin: {
id: "77777777-7777-4777-8777-777777777806",
pluginId: "plugin-instance-1",
pluginKey: manifest.id,
pluginDisplayName: manifest.displayName,
resourceKind: "project" as const,
resourceKey: WIKI_PROJECT_KEY,
defaultsJson: {},
createdAt: new Date("2026-05-04T00:00:00Z"),
updatedAt: new Date("2026-05-04T00:00:00Z"),
},
};
harness.seed({ projects: [recentProject, olderProject, overflowProject, completedProject, pluginProject] });
await plugin.definition.setup(harness.ctx);
const result = await harness.performAction<{
selectedProjects: Array<{ id: string; observedAt: string | null }>;
eventIngestion: { enabled: boolean; sources: { issues: boolean; comments: boolean; documents: boolean } };
}>("enable-paperclip-distillation-active-projects", {
companyId: COMPANY_ID,
limit: 2,
});
expect(result.selectedProjects.map((project) => project.id)).toEqual([recentProject.id, olderProject.id]);
expect(result.eventIngestion).toMatchObject({
enabled: true,
sources: { issues: true, comments: true, documents: true },
});
const cursorWrites = harness.dbExecutes.filter((execute) => execute.sql.includes("paperclip_distillation_cursors"));
expect(cursorWrites).toHaveLength(2);
expect(cursorWrites.map((execute) => execute.params?.[5])).toEqual([recentProject.id, olderProject.id]);
expect(cursorWrites.map((execute) => execute.params?.[8])).toEqual([1, 1]);
expect(String(cursorWrites[0]?.params?.[9])).toContain('"configuredBy":"enable-active-projects"');
});
it("backfills only the selected Paperclip project and date window", async () => {
const harness = createTestHarness({ manifest });
const project = existingProject();
const inWindow = paperclipIssue({
id: "77777777-7777-4777-8777-777777777797",
identifier: "PAP-4106",
title: "Backfill in-window decision",
description: "Accepted historical decision that should appear in the backfill page.",
status: "done",
projectId: project.id,
updatedAt: new Date("2026-04-15T12:00:00Z"),
});
const outOfWindow = paperclipIssue({
id: "77777777-7777-4777-8777-777777777798",
identifier: "PAP-4107",
title: "Backfill out-of-window decision",
description: "This old decision must not be included in the selected date window.",
status: "done",
projectId: project.id,
updatedAt: new Date("2026-03-01T12:00:00Z"),
});
const otherProject = paperclipIssue({
id: "77777777-7777-4777-8777-777777777799",
identifier: "PAP-4108",
title: "Other project decision",
description: "This issue belongs to a different project and must not be included.",
status: "done",
projectId: "88888888-8888-4888-8888-888888888888",
updatedAt: new Date("2026-04-16T12:00:00Z"),
});
harness.seed({ agents: [wikiMaintainerAgent()], projects: [project], issues: [inWindow, outOfWindow, otherProject] });
await plugin.definition.setup(harness.ctx);
const result = await harness.performAction<{
status: string;
patches: Array<{ operationType: string; proposedContents: string }>;
workItem: { kind: string };
operation: { issue: { originKind: string } };
}>("backfill-paperclip-distillation", {
companyId: COMPANY_ID,
projectId: project.id,
backfillStartAt: "2026-04-01T00:00:00Z",
backfillEndAt: "2026-04-30T23:59:59Z",
autoApply: false,
includeSupportingPages: false,
});
expect(result.status).toBe("review_required");
expect(result.workItem.kind).toBe("backfill");
expect(result.operation.issue.originKind).toBe(`${OPERATION_ORIGIN_KIND}:backfill`);
const projectPatch = result.patches.find((patch) => patch.operationType === "project_page_distill");
expect(projectPatch?.proposedContents).toContain("PAP-4106");
expect(projectPatch?.proposedContents).not.toContain("PAP-4107");
expect(projectPatch?.proposedContents).not.toContain("PAP-4108");
const workItemInsert = harness.dbExecutes.find((execute) =>
execute.sql.includes("paperclip_distillation_work_items") && execute.params?.[3] === "backfill");
expect(String(workItemInsert?.params?.[9])).toContain('"backfillStartAt":"2026-04-01T00:00:00Z"');
});
it("generates review-required Paperclip project page patches with provenance, index, and log updates", async () => {
const harness = createTestHarness({ manifest });
const project = existingProject();
const issue = paperclipIssue({
id: "77777777-7777-4777-8777-777777777791",
identifier: "PAP-4100",
title: "Approved project page distillation plan",
description: "Accepted plan: write stable project overview sections with source provenance.",
status: "in_progress",
projectId: project.id,
updatedAt: new Date("2026-05-03T10:00:00Z"),
});
const files = new Map<string, string>([
["wiki/index.md", DEFAULT_INDEX],
["wiki/log.md", DEFAULT_LOG],
]);
const writes: Array<{ path: string; contents: string }> = [];
harness.seed({ projects: [project], issues: [issue] });
harness.ctx.localFolders.readText = async (_companyId, _folderKey, relativePath) => {
const contents = files.get(relativePath);
if (contents == null) throw new Error(`missing ${relativePath}`);
return contents;
};
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
writes.push({ path: relativePath, contents });
files.set(relativePath, contents);
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
await plugin.definition.setup(harness.ctx);
const result = await harness.performAction<{
status: string;
patches: Array<{ pagePath: string; operationType: string; currentHash: string | null; proposedContents: string; sourceRefs: Array<{ issueIdentifier: string | null }> }>;
warnings: string[];
}>("distill-paperclip-project-page", {
companyId: COMPANY_ID,
projectId: project.id,
autoApply: false,
maxCharacters: 20000,
includeSupportingPages: false,
});
expect(result.status).toBe("review_required");
expect(writes).toHaveLength(0);
expect(result.patches.map((patch) => patch.operationType)).toEqual([
"standup_update",
"project_page_distill",
"index_refresh",
"log_append",
]);
const standupPatch = result.patches[0];
expect(standupPatch.pagePath).toBe("wiki/projects/existing-wiki-project/standup.md");
expect(standupPatch.proposedContents).toContain("## Executive Readout");
expect(standupPatch.proposedContents).toContain("## What Changed");
const projectPatch = result.patches[1];
expect(projectPatch.currentHash).toBeNull();
expect(projectPatch.pagePath).toBe("wiki/projects/existing-wiki-project/index.md");
expect(projectPatch.proposedContents).toContain("## Workstreams");
expect(projectPatch.proposedContents).toContain("PAP-4100");
expect(projectPatch.sourceRefs).toEqual([expect.objectContaining({ issueIdentifier: "PAP-4100" })]);
expect(result.patches[2].proposedContents).toContain("[[wiki/projects/existing-wiki-project/index.md]]");
expect(result.patches[2].proposedContents).toContain("[[wiki/projects/existing-wiki-project/standup.md]]");
expect(result.patches[3].proposedContents).toContain("paperclip-distill | proposed");
expect(result.warnings).toContain("Auto-apply policy disabled; proposed patches require review.");
});
it("keeps suppressed secret-like source content out of generated wiki patches", async () => {
const harness = createTestHarness({ manifest });
const project = existingProject();
const issue = paperclipIssue({
id: "77777777-7777-4777-8777-777777777796",
identifier: "PAP-4104",
title: "Distill sanitized provenance",
description: "Publish enough project state for a reviewable project page without leaking credentials.",
status: "in_progress",
projectId: project.id,
updatedAt: new Date("2026-05-04T10:00:00Z"),
});
const files = new Map<string, string>([
["wiki/index.md", DEFAULT_INDEX],
["wiki/log.md", DEFAULT_LOG],
]);
harness.seed({
projects: [project],
issues: [issue],
issueComments: [{
id: "77777777-7777-4777-8777-777777777797",
companyId: COMPANY_ID,
issueId: issue.id,
authorType: "user",
authorAgentId: null,
authorUserId: null,
onBehalfOfUserId: null,
body: "Authorization: Bearer ghp_patchsecretcommenttoken1234567890",
presentation: null,
metadata: null,
createdAt: new Date("2026-05-04T11:00:00Z"),
updatedAt: new Date("2026-05-04T11:00:00Z"),
}],
});
harness.ctx.localFolders.readText = async (_companyId, _folderKey, relativePath) => {
const contents = files.get(relativePath);
if (contents == null) throw new Error(`missing ${relativePath}`);
return contents;
};
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
files.set(relativePath, contents);
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
await plugin.definition.setup(harness.ctx);
await harness.ctx.issues.documents.upsert({
companyId: COMPANY_ID,
issueId: issue.id,
key: "plan",
title: "Plan",
body: "OPENAI_API_KEY=sk-patchsecretdocumentvalue1234567890",
});
const result = await harness.performAction<{
status: string;
patches: Array<{ operationType: string; proposedContents: string }>;
}>("distill-paperclip-project-page", {
companyId: COMPANY_ID,
projectId: project.id,
maxCharacters: 20000,
includeSupportingPages: false,
});
expect(result.status).toBe("review_required");
const combinedPatchContents = result.patches.map((patch) => patch.proposedContents).join("\n");
expect(combinedPatchContents).toContain("redaction=suppressed_sensitive_content");
expect(combinedPatchContents).toContain("redaction_reasons=secret_like_token");
expect(combinedPatchContents).not.toContain("ghp_patchsecretcommenttoken1234567890");
expect(combinedPatchContents).not.toContain("sk-patchsecretdocumentvalue1234567890");
});
it("auto-applies Paperclip project page patches by default when policy allows and records page bindings", async () => {
const harness = createTestHarness({ manifest });
const project = existingProject();
const issue = paperclipIssue({
id: "77777777-7777-4777-8777-777777777792",
identifier: "PAP-4101",
title: "Implement project page writer",
description: "Implementation completed enough to publish the generated project page.",
status: "done",
projectId: project.id,
updatedAt: new Date("2026-05-04T10:00:00Z"),
});
const files = new Map<string, string>([
["wiki/index.md", DEFAULT_INDEX],
["wiki/log.md", DEFAULT_LOG],
]);
harness.seed({ projects: [project], issues: [issue] });
harness.ctx.localFolders.readText = async (_companyId, _folderKey, relativePath) => {
const contents = files.get(relativePath);
if (contents == null) throw new Error(`missing ${relativePath}`);
return contents;
};
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
files.set(relativePath, contents);
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
await plugin.definition.setup(harness.ctx);
const result = await harness.performAction<{
status: string;
appliedPages: string[];
patches: Array<{ pagePath: string; sourceHash: string }>;
}>("distill-paperclip-project-page", {
companyId: COMPANY_ID,
projectId: project.id,
autoApply: true,
maxCharacters: 20000,
includeSupportingPages: false,
});
expect(result.status).toBe("applied");
expect(result.appliedPages).toEqual([
"wiki/projects/existing-wiki-project/standup.md",
"wiki/projects/existing-wiki-project/index.md",
"wiki/index.md",
"wiki/log.md",
]);
expect(files.get("wiki/projects/existing-wiki-project/standup.md")).toContain("## Executive Readout");
expect(files.get("wiki/projects/existing-wiki-project/index.md")).toContain("## Current Direction");
expect(files.get("wiki/projects/existing-wiki-project/index.md")).toContain("## References");
expect(files.get("wiki/index.md")).toContain("wiki/projects/existing-wiki-project/index.md");
expect(files.get("wiki/log.md")).toContain("paperclip-distill | proposed");
const bindingWrites = harness.dbExecutes.filter((execute) => execute.sql.includes("paperclip_page_bindings"));
expect(bindingWrites).toHaveLength(4);
expect(bindingWrites[0].params).toEqual(expect.arrayContaining([
COMPANY_ID,
"default",
project.id,
null,
"wiki/projects/existing-wiki-project/standup.md",
result.patches[0].sourceHash,
]));
});
it("refuses auto-apply Paperclip project page patches in authenticated/public deployments", async () => {
process.env.PAPERCLIP_DEPLOYMENT_MODE = "authenticated";
process.env.PAPERCLIP_DEPLOYMENT_EXPOSURE = "public";
const harness = createTestHarness({ manifest, config: { autoApplyIngestPatches: true } });
const project = existingProject();
const issue = paperclipIssue({
id: "77777777-7777-4777-8777-77777777779a",
identifier: "PAP-4101",
title: "Implement project page writer",
description: "Implementation completed enough to publish the generated project page.",
status: "done",
projectId: project.id,
updatedAt: new Date("2026-05-04T10:00:00Z"),
});
const files = new Map<string, string>([
["wiki/index.md", DEFAULT_INDEX],
["wiki/log.md", DEFAULT_LOG],
]);
const writes: string[] = [];
harness.seed({ projects: [project], issues: [issue] });
harness.ctx.localFolders.readText = async (_companyId, _folderKey, relativePath) => {
const contents = files.get(relativePath);
if (contents == null) throw new Error(`missing ${relativePath}`);
return contents;
};
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
writes.push(relativePath);
files.set(relativePath, contents);
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
await plugin.definition.setup(harness.ctx);
const result = await harness.performAction<{
status: string;
appliedPages: string[];
warnings: string[];
}>("distill-paperclip-project-page", {
companyId: COMPANY_ID,
projectId: project.id,
autoApply: true,
maxCharacters: 20000,
includeSupportingPages: false,
});
expect(result.status).toBe("review_required");
expect(result.appliedPages).toEqual([]);
expect(writes).toHaveLength(0);
expect(result.warnings).toContain(
"Authenticated/public deployments always require manual review before wiki writes.",
);
});
it("refuses stale project page hashes before writing generated Paperclip pages", async () => {
const harness = createTestHarness({ manifest, config: { autoApplyIngestPatches: true } });
const project = existingProject();
const issue = paperclipIssue({
id: "77777777-7777-4777-8777-777777777793",
identifier: "PAP-4102",
title: "Publish project page",
description: "Ready to publish.",
status: "done",
projectId: project.id,
});
const files = new Map<string, string>([
["wiki/projects/existing-wiki-project/index.md", "# Existing\n"],
["wiki/index.md", DEFAULT_INDEX],
["wiki/log.md", DEFAULT_LOG],
]);
const writes: string[] = [];
harness.seed({ projects: [project], issues: [issue] });
harness.ctx.localFolders.readText = async (_companyId, _folderKey, relativePath) => {
const contents = files.get(relativePath);
if (contents == null) throw new Error(`missing ${relativePath}`);
return contents;
};
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
writes.push(relativePath);
files.set(relativePath, contents);
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
await plugin.definition.setup(harness.ctx);
await expect(harness.performAction("distill-paperclip-project-page", {
companyId: COMPANY_ID,
projectId: project.id,
autoApply: true,
expectedProjectPageHash: "stale",
includeSupportingPages: false,
})).rejects.toThrow("Refusing to overwrite");
expect(writes).toHaveLength(0);
});
it("skips low-signal Paperclip source windows without proposing wiki writes", async () => {
const harness = createTestHarness({ manifest });
const project = existingProject();
const issue = paperclipIssue({
id: "77777777-7777-4777-8777-777777777794",
identifier: "PAP-4103",
title: "Routine heartbeat",
description: "",
status: "todo",
projectId: project.id,
});
const writes: string[] = [];
harness.seed({ projects: [project], issues: [issue] });
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
writes.push(relativePath);
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
await plugin.definition.setup(harness.ctx);
const result = await harness.performAction<{ status: string; reason: string; patches: unknown[] }>("distill-paperclip-project-page", {
companyId: COMPANY_ID,
projectId: project.id,
maxCharacters: 20000,
});
expect(result.status).toBe("skipped");
expect(result.reason).toBe("low_signal");
expect(result.patches).toEqual([]);
expect(writes).toHaveLength(0);
});
it("bootstraps required local wiki files through the local folder API", async () => {
const harness = createTestHarness({ manifest });
const writes = captureWikiWrites(harness);
await plugin.definition.setup(harness.ctx);
const result = await harness.performAction<{ writtenFiles: string[]; managedSkills: WikiSkillResource[] }>("bootstrap-root", {
companyId: COMPANY_ID,
path: "/tmp/company-wiki",
});
expect(result.writtenFiles).toContain("AGENTS.md");
expect(result.writtenFiles).toContain("IDEA.md");
expect(result.managedSkills[0]).toMatchObject({
status: "created",
resourceKey: WIKI_MAINTAINER_SKILL_KEY,
details: { key: WIKI_MAINTAINER_SKILL_CANONICAL_KEY },
});
expect(writes.map((write) => write.path)).toEqual([
".gitignore",
"AGENTS.md",
"IDEA.md",
"wiki/index.md",
"wiki/log.md",
"raw/.gitkeep",
"wiki/sources/.gitkeep",
"wiki/projects/.gitkeep",
"wiki/entities/.gitkeep",
"wiki/concepts/.gitkeep",
"wiki/synthesis/.gitkeep",
]);
expect(writes.find((write) => write.path === "AGENTS.md")?.contents).toContain("LLM Wiki Schema");
expect(writes.find((write) => write.path === "AGENTS.md")?.contents).toContain("wiki/projects/<project-slug>/index.md");
expect(writes.find((write) => write.path === "AGENTS.md")?.contents).toContain("wiki/projects/<project-slug>/standup.md");
});
it("creates a managed space with an immediately readable baseline skeleton", async () => {
const harness = createTestHarness({ manifest });
const files = new Map<string, string>();
harness.ctx.localFolders.readText = async (_companyId, _folderKey, relativePath) => {
const value = files.get(relativePath);
if (value == null) throw new Error(`missing ${relativePath}`);
return value;
};
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
files.set(relativePath, contents);
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
await plugin.definition.setup(harness.ctx);
const created = await harness.performAction<{
space: { slug: string; pathPrefix: string | null };
}>("create-space", {
companyId: COMPANY_ID,
displayName: "QA Space",
});
expect(created.space).toMatchObject({
slug: "qa-space",
pathPrefix: "spaces/qa-space",
});
await expect(harness.ctx.localFolders.readText(
COMPANY_ID,
"wiki-root",
"spaces/qa-space/AGENTS.md",
)).resolves.toContain("LLM Wiki Schema");
expect(files.get("spaces/qa-space/IDEA.md")).toBe(DEFAULT_IDEA);
expect(files.has("spaces/qa-space/raw/.gitkeep")).toBe(true);
expect(files.has("spaces/qa-space/projects/.gitkeep")).toBe(false);
expect(files.has("spaces/qa-space/wiki/projects/.gitkeep")).toBe(true);
expect(files.has("spaces/qa-space/wiki/index.md")).toBe(true);
});
it("prevents the default space from being archived through update-space", async () => {
const harness = createTestHarness({ manifest });
await plugin.definition.setup(harness.ctx);
await expect(harness.performAction("update-space", {
companyId: COMPANY_ID,
spaceSlug: "default",
status: "archived",
})).rejects.toThrow("The default LLM Wiki space cannot be archived.");
const defaultSpaceInsert = harness.dbExecutes.find((execute) =>
execute.sql.includes("INSERT INTO") && execute.sql.includes("wiki_spaces"));
expect(defaultSpaceInsert?.params?.[0]).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-8[0-9a-f]{3}-[0-9a-f]{12}$/);
expect(harness.dbExecutes.some((execute) =>
execute.sql.includes("UPDATE") &&
execute.sql.includes("wiki_spaces") &&
execute.params?.includes("archived"))).toBe(false);
});
it("archives a non-default space through update-space without re-resolving it as active", async () => {
const harness = createTestHarness({ manifest });
const spaceRow = wikiSpaceRow({
id: "77777777-7777-4777-8777-7777777777b1",
slug: "qa-space",
displayName: "QA Space",
pathPrefix: "spaces/qa-space",
status: "active",
settings: { owner: "qa" },
});
let archived = false;
const originalQuery = harness.ctx.db.query.bind(harness.ctx.db);
harness.ctx.db.query = async <T,>(sql: string, params?: unknown[]) => {
harness.dbQueries.push({ sql, params });
if (sql.includes("wiki_spaces") && params?.[2] === "qa-space") {
return archived && sql.includes("status <> 'archived'") ? [] as T[] : [spaceRow] as T[];
}
return originalQuery<T>(sql, params);
};
const originalExecute = harness.ctx.db.execute.bind(harness.ctx.db);
harness.ctx.db.execute = async (sql: string, params?: unknown[]) => {
if (sql.includes("UPDATE") && sql.includes("wiki_spaces") && params?.includes("archived")) archived = true;
return originalExecute(sql, params);
};
await plugin.definition.setup(harness.ctx);
const updated = await harness.performAction<{
status: string;
space: { slug: string; displayName: string; status: string; settings: Record<string, unknown> };
}>("update-space", {
companyId: COMPANY_ID,
spaceSlug: "qa-space",
displayName: "Archived QA",
settings: { archivedBy: "test" },
status: "archived",
});
expect(updated.status).toBe("ok");
expect(updated.space).toMatchObject({
slug: "qa-space",
displayName: "Archived QA",
status: "archived",
settings: { owner: "qa", archivedBy: "test" },
});
expect(archived).toBe(true);
});
it("restores an archived non-default space through update-space", async () => {
const harness = createTestHarness({ manifest });
const spaceRow = wikiSpaceRow({
id: "77777777-7777-4777-8777-7777777777b2",
slug: "qa-space",
displayName: "QA Space",
pathPrefix: "spaces/qa-space",
status: "archived",
});
let restored = false;
const originalQuery = harness.ctx.db.query.bind(harness.ctx.db);
harness.ctx.db.query = async <T,>(sql: string, params?: unknown[]) => {
harness.dbQueries.push({ sql, params });
if (sql.includes("wiki_spaces") && params?.[2] === "qa-space") {
if (!restored && sql.includes("status <> 'archived'")) return [] as T[];
return [{
...spaceRow,
status: restored ? "active" : "archived",
}] as T[];
}
return originalQuery<T>(sql, params);
};
const originalExecute = harness.ctx.db.execute.bind(harness.ctx.db);
harness.ctx.db.execute = async (sql: string, params?: unknown[]) => {
if (sql.includes("UPDATE") && sql.includes("wiki_spaces") && params?.includes("active")) restored = true;
return originalExecute(sql, params);
};
await plugin.definition.setup(harness.ctx);
const updated = await harness.performAction<{
status: string;
space: { slug: string; status: string };
}>("update-space", {
companyId: COMPANY_ID,
spaceSlug: "qa-space",
status: "active",
});
expect(updated.status).toBe("ok");
expect(updated.space).toMatchObject({
slug: "qa-space",
status: "active",
});
expect(restored).toBe(true);
});
it("rejects unknown space statuses through update-space", async () => {
const harness = createTestHarness({ manifest });
await plugin.definition.setup(harness.ctx);
await expect(harness.performAction("update-space", {
companyId: COMPANY_ID,
spaceSlug: "default",
status: "suspended",
})).rejects.toThrow("LLM Wiki space status must be active or archived.");
expect(harness.dbExecutes.some((execute) =>
execute.sql.includes("UPDATE") &&
execute.sql.includes("wiki_spaces") &&
execute.params?.includes("suspended"))).toBe(false);
});
it("omits archived spaces from the spaces data API", async () => {
const harness = createTestHarness({ manifest });
const activeRow = wikiSpaceRow({
id: "77777777-7777-4777-8777-7777777777a1",
slug: "team-research",
displayName: "Team Research",
pathPrefix: "spaces/team-research",
status: "active",
});
const archivedRow = wikiSpaceRow({
id: "77777777-7777-4777-8777-7777777777a2",
slug: "qa-team-lock",
displayName: "QA Team Lock",
pathPrefix: "spaces/qa-team-lock",
status: "archived",
});
harness.ctx.db.query = async <T,>(sql: string, params?: unknown[]) => {
harness.dbQueries.push({ sql, params });
if (sql.includes("wiki_spaces") && sql.includes("ORDER BY CASE WHEN slug = 'default'")) {
const rows = [defaultWikiSpaceRow(), activeRow];
if (!sql.includes("status <> 'archived'")) rows.push(archivedRow);
return rows as T[];
}
if (sql.includes("wiki_spaces") && sql.includes("slug = 'default'")) {
return [defaultWikiSpaceRow()] as T[];
}
return [] as T[];
};
await plugin.definition.setup(harness.ctx);
const result = await harness.getData<{ spaces: Array<{ slug: string }> }>("spaces", {
companyId: COMPANY_ID,
wikiId: "default",
});
expect(result.spaces.map((space) => space.slug)).toEqual(["default", "team-research"]);
expect(harness.dbQueries.some((query) => query.sql.includes("status <> 'archived'"))).toBe(true);
});
it("captures raw sources into local files and plugin metadata", async () => {
const harness = createTestHarness({ manifest });
const writes = captureWikiWrites(harness);
await plugin.definition.setup(harness.ctx);
const result = await harness.performAction<{ rawPath: string; hash: string }>("capture-source", {
companyId: COMPANY_ID,
wikiId: "default",
title: "Plugin Boundaries",
contents: "# Plugin Boundaries\n\nKeep wiki logic in the plugin.",
});
expect(result.rawPath).toMatch(/^raw\/\d{4}-\d{2}-\d{2}-plugin-boundaries-/);
expect(result.hash).toHaveLength(64);
expect(writes[0]).toMatchObject({ path: result.rawPath });
expect(harness.dbExecutes.some((execute) => execute.sql.includes("wiki_sources"))).toBe(true);
});
it("preserves manual source ingest for non-default spaces while refusing Paperclip distillation there", async () => {
const harness = createTestHarness({ manifest });
const writes = captureWikiWrites(harness);
harness.seed({
agents: [wikiMaintainerAgent()],
projects: [existingProject()],
});
const spaces = new Map<string, Record<string, unknown>>();
const originalQuery = harness.ctx.db.query.bind(harness.ctx.db);
harness.ctx.db.query = async <T,>(sql: string, params?: unknown[]) => {
if (sql.includes("wiki_spaces")) {
const slug = typeof params?.[2] === "string" ? params[2] : null;
if (slug && spaces.has(slug)) return [spaces.get(slug)] as T[];
}
return originalQuery<T>(sql, params);
};
await plugin.definition.setup(harness.ctx);
const created = await harness.performAction<{
space: { id: string; companyId: string; wikiId: string; slug: string; displayName: string; pathPrefix: string | null };
}>("create-space", {
companyId: COMPANY_ID,
displayName: "Team Research",
});
spaces.set(created.space.slug, managedSpaceRow(created));
const source = await harness.performAction<{ rawPath: string; spaceSlug: string }>("capture-source", {
companyId: COMPANY_ID,
spaceSlug: created.space.slug,
title: "Team notes",
contents: "# Team notes\n\nManual source ingest still belongs to the selected space.",
});
expect(source.spaceSlug).toBe(created.space.slug);
expect(writes.map((write) => write.path)).toContain(`spaces/${created.space.slug}/${source.rawPath}`);
await expect(harness.performAction("distill-paperclip-now", {
companyId: COMPANY_ID,
spaceSlug: created.space.slug,
projectId: existingProject().id,
})).rejects.toThrow("Paperclip ingestion policy denied queue");
});
it("fails closed for direct Paperclip ingestion actions against restricted spaces", async () => {
const harness = createTestHarness({ manifest });
harness.seed({
agents: [wikiMaintainerAgent()],
projects: [existingProject()],
});
await plugin.definition.setup(harness.ctx);
const created = await harness.performAction<{
space: { slug: string; accessScope: string };
}>("create-space", {
companyId: COMPANY_ID,
displayName: "Private Notes",
accessScope: "personal",
});
expect(created.space.accessScope).toBe("personal");
const originalQuery = harness.ctx.db.query.bind(harness.ctx.db);
harness.ctx.db.query = async <T,>(sql: string, params?: unknown[]) => {
if (sql.includes("wiki_spaces") && params?.[2] === created.space.slug) {
return [{
id: "77777777-7777-4777-8777-7777777777b2",
company_id: COMPANY_ID,
wiki_id: "default",
slug: created.space.slug,
display_name: "Private Notes",
space_type: "local_folder",
folder_mode: "managed_subfolder",
root_folder_key: "wiki-root",
path_prefix: `spaces/${created.space.slug}`,
configured_root_path: null,
access_scope: "personal",
owner_user_id: null,
owner_agent_id: null,
team_key: null,
settings: {},
status: "active",
created_at: null,
updated_at: null,
}] as T[];
}
return originalQuery<T>(sql, params);
};
await expect(harness.performAction("distill-paperclip-now", {
companyId: COMPANY_ID,
spaceSlug: created.space.slug,
projectId: existingProject().id,
})).rejects.toThrow("Paperclip ingestion policy denied queue");
const operations = await harness.ctx.issues.list({
companyId: COMPANY_ID,
originKindPrefix: String(OPERATION_ORIGIN_KIND),
});
expect(operations).toHaveLength(0);
expect(harness.dbExecutes.some((execute) => execute.sql.includes("paperclip_distillation_work_items"))).toBe(false);
});
it("re-checks Paperclip ingestion policy at execution time for queued work", async () => {
const harness = createTestHarness({ manifest });
const project = existingProject();
const issue = paperclipIssue({
id: "77777777-7777-4777-8777-7777777777b0",
identifier: "PAP-4111",
title: "Queued distillation source",
description: "Accepted queued work should not run after policy changes.",
projectId: project.id,
status: "done",
});
harness.seed({ agents: [wikiMaintainerAgent()], projects: [project], issues: [issue] });
await plugin.definition.setup(harness.ctx);
const queued = await harness.performAction<{ status: string }>("distill-paperclip-now", {
companyId: COMPANY_ID,
projectId: project.id,
});
expect(queued.status).toBe("queued");
const originalQuery = harness.ctx.db.query.bind(harness.ctx.db);
harness.ctx.db.query = async <T,>(sql: string, params?: unknown[]) => {
if (sql.includes("wiki_spaces") && sql.includes("slug = 'default'")) {
return [{
id: "77777777-7777-4777-8777-7777777777b1",
company_id: COMPANY_ID,
wiki_id: "default",
slug: "default",
display_name: "default",
space_type: "local_folder",
folder_mode: "managed_subfolder",
root_folder_key: "wiki-root",
path_prefix: null,
configured_root_path: null,
access_scope: "personal",
owner_user_id: null,
owner_agent_id: null,
team_key: null,
settings: {},
status: "active",
created_at: null,
updated_at: null,
}] as T[];
}
return originalQuery<T>(sql, params);
};
await expect(harness.performAction("create-paperclip-distillation-run", {
companyId: COMPANY_ID,
projectId: project.id,
})).rejects.toThrow("personal spaces cannot ingest Paperclip sources");
expect(harness.dbExecutes.some((execute) =>
execute.sql.includes("paperclip_distillation_runs") && execute.sql.includes("'source_ready'"))).toBe(false);
});
it("queues Paperclip ingestion backfills for every selected project scope", async () => {
const harness = createTestHarness({ manifest });
await plugin.definition.setup(harness.ctx);
const queued = await harness.performAction<{
status: string;
workItemId: string;
issueId: string;
workItems: Array<{ workItemId: string; issueId: string; projectId: string | null; rootIssueId: string | null }>;
}>("queue-paperclip-ingestion-backfill", {
companyId: COMPANY_ID,
sourceScope: {
kind: "selected_projects",
projectIds: [
"77777777-7777-4777-8777-7777777777a1",
"77777777-7777-4777-8777-7777777777a2",
],
},
backfillStartAt: "2026-05-01T00:00:00.000Z",
backfillEndAt: "2026-05-02T00:00:00.000Z",
});
expect(queued.status).toBe("queued");
expect(queued.workItems).toHaveLength(2);
expect(queued.workItemId).toBe(queued.workItems[0]?.workItemId);
expect(queued.issueId).toBe(queued.workItems[0]?.issueId);
expect(queued.workItems.map((item) => item.projectId)).toEqual([
"77777777-7777-4777-8777-7777777777a1",
"77777777-7777-4777-8777-7777777777a2",
]);
expect(harness.dbExecutes.filter((execute) => execute.sql.includes("paperclip_distillation_work_items"))).toHaveLength(2);
});
it("rejects oversized Paperclip ingestion profile and source-scope payloads", async () => {
const harness = createTestHarness({ manifest });
await plugin.definition.setup(harness.ctx);
await expect(harness.performAction("update-event-ingestion-settings", {
companyId: COMPANY_ID,
enabled: true,
maxCharacters: 20001,
sources: { issues: true },
})).rejects.toThrow("maxCharacters exceeds the hard Paperclip ingestion cap");
await expect(harness.performAction("enable-paperclip-distillation-active-projects", {
companyId: COMPANY_ID,
limit: 26,
})).rejects.toThrow("fan-out exceeds the hard cap");
await expect(harness.performAction("assemble-paperclip-source-bundle", {
companyId: COMPANY_ID,
projectId: "77777777-7777-4777-8777-777777777777",
rootIssueId: "77777777-7777-4777-8777-777777777778",
})).rejects.toThrow("either projectId or rootIssueId");
await expect(harness.performAction("assemble-paperclip-source-bundle", {
companyId: COMPANY_ID,
projectId: "77777777-7777-4777-8777-777777777777",
maxCharacters: 60001,
})).rejects.toThrow("maxCharacters exceeds the hard Paperclip ingestion cap");
});
it("keeps default-space files at the root and isolates managed spaces under slug prefixes", async () => {
const harness = createTestHarness({ manifest });
const files = new Map<string, string>();
const writes: Array<{ path: string; contents: string }> = [];
harness.ctx.localFolders.readText = async (_companyId, _folderKey, relativePath) => {
const value = files.get(relativePath);
if (value == null) throw new Error(`missing ${relativePath}`);
return value;
};
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
writes.push({ path: relativePath, contents });
files.set(relativePath, contents);
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
const spaces = new Map<string, Record<string, unknown>>();
const originalQuery = harness.ctx.db.query.bind(harness.ctx.db);
harness.ctx.db.query = async <T,>(sql: string, params?: unknown[]) => {
if (sql.includes("wiki_spaces")) {
const slug = typeof params?.[2] === "string" ? params[2] : null;
if (slug && spaces.has(slug)) return [spaces.get(slug)] as T[];
}
return originalQuery<T>(sql, params);
};
await plugin.definition.setup(harness.ctx);
const created = await harness.performAction<{
space: { id: string; companyId: string; wikiId: string; slug: string; displayName: string; pathPrefix: string | null };
}>("create-space", {
companyId: COMPANY_ID,
displayName: "Research Space",
});
spaces.set(created.space.slug, managedSpaceRow(created));
await harness.performAction("bootstrap-space", {
companyId: COMPANY_ID,
spaceSlug: created.space.slug,
});
await harness.performAction("write-page", {
companyId: COMPANY_ID,
wikiId: "default",
path: "wiki/concepts/shared.md",
contents: "# Default Shared\n",
});
await harness.performAction("write-page", {
companyId: COMPANY_ID,
wikiId: "default",
spaceSlug: created.space.slug,
path: "wiki/concepts/shared.md",
contents: "# Space Shared\n",
});
await harness.performAction("capture-source", {
companyId: COMPANY_ID,
wikiId: "default",
rawPath: "raw/shared.md",
title: "Shared Source",
contents: "# Default Raw\n",
});
await harness.performAction("capture-source", {
companyId: COMPANY_ID,
wikiId: "default",
spaceSlug: created.space.slug,
rawPath: "raw/shared.md",
title: "Shared Source",
contents: "# Space Raw\n",
});
expect(created.space).toMatchObject({
slug: "research-space",
pathPrefix: "spaces/research-space",
});
expect(files.get("wiki/concepts/shared.md")).toBe("# Default Shared\n");
expect(files.get("spaces/research-space/wiki/concepts/shared.md")).toBe("# Space Shared\n");
expect(files.get("raw/shared.md")).toBe("# Default Raw\n");
expect(files.get("spaces/research-space/raw/shared.md")).toBe("# Space Raw\n");
expect(writes.map((write) => write.path)).not.toContain("spaces/default/wiki/concepts/shared.md");
const pageWrites = harness.dbExecutes.filter((execute) => execute.sql.includes("wiki_pages"));
const sourceWrites = harness.dbExecutes.filter((execute) => execute.sql.includes("wiki_sources"));
expect(pageWrites).toHaveLength(4);
expect(sourceWrites).toHaveLength(2);
expect(pageWrites.every((write) => write.sql.includes("space_id"))).toBe(true);
expect(sourceWrites.every((write) => write.sql.includes("space_id"))).toBe(true);
});
it("ingests source metadata and creates a hidden plugin-operation issue", async () => {
const harness = createTestHarness({ manifest });
harness.seed({ agents: [wikiMaintainerAgent()] });
const writes = captureWikiWrites(harness);
await plugin.definition.setup(harness.ctx);
const result = await harness.performAction<{
source: { rawPath: string; title: string; hash: string };
operation: { operationId: string; issue: { originKind: string; originId: string | null; billingCode: string | null; assigneeAgentId: string | null } };
}>("ingest-source", {
companyId: COMPANY_ID,
wikiId: "engineering",
sourceType: "url",
title: "Standalone Plugin Notes",
url: "https://example.test/wiki",
contents: "# Standalone Plugin Notes\n\nKeep wiki behavior in the plugin package.",
rawPath: "raw/standalone-plugin-notes.md",
metadata: { importedBy: "alpha-verification" },
});
expect(result.source.rawPath).toBe("raw/standalone-plugin-notes.md");
expect(result.source.title).toBe("Standalone Plugin Notes");
expect(result.source.hash).toHaveLength(64);
expect(writes).toEqual([
expect.objectContaining({
path: "raw/standalone-plugin-notes.md",
contents: expect.stringContaining("Keep wiki behavior in the plugin package."),
}),
]);
expect(result.operation.issue.originKind).toBe(`${OPERATION_ORIGIN_KIND}:ingest`);
expect(result.operation.issue.originId).toBe(`wiki:engineering:operation:${result.operation.operationId}`);
expect(result.operation.issue.billingCode).toBe("plugin-llm-wiki:engineering");
expect(result.operation.issue.assigneeAgentId).toBe(wikiMaintainerAgent().id);
const sourceInsert = harness.dbExecutes.find((execute) => execute.sql.includes("wiki_sources"));
expect(sourceInsert?.params).toEqual(expect.arrayContaining([
COMPANY_ID,
"engineering",
"url",
"Standalone Plugin Notes",
"https://example.test/wiki",
"raw/standalone-plugin-notes.md",
JSON.stringify({ importedBy: "alpha-verification" }),
]));
const operationInsert = harness.dbExecutes.find((execute) => execute.sql.includes("wiki_operations"));
expect(operationInsert?.params).toEqual(expect.arrayContaining([
result.operation.operationId,
COMPANY_ID,
"engineering",
"ingest",
"queued",
]));
});
it("rejects oversized source capture before raw writes or operation creation", async () => {
const harness = createTestHarness({ manifest, config: { maxSourceBytes: 16 } });
harness.seed({ agents: [wikiMaintainerAgent()] });
const writes = captureWikiWrites(harness);
await plugin.definition.setup(harness.ctx);
await expect(harness.performAction("ingest-source", {
companyId: COMPANY_ID,
wikiId: "default",
sourceType: "text",
title: "Oversized source",
contents: "x".repeat(17),
})).rejects.toThrow("exceeds the configured LLM Wiki source limit");
expect(writes).toHaveLength(0);
expect(harness.dbExecutes.some((execute) => execute.sql.includes("wiki_sources"))).toBe(false);
expect(harness.dbExecutes.some((execute) => execute.sql.includes("wiki_operations"))).toBe(false);
const operations = await harness.ctx.issues.list({
companyId: COMPANY_ID,
originKindPrefix: String(OPERATION_ORIGIN_KIND),
});
expect(operations).toHaveLength(0);
});
it("writes pages atomically, records metadata, and rejects stale hashes", async () => {
const harness = createTestHarness({ manifest });
const files = new Map<string, string>([
["wiki/concepts/plugin-boundaries.md", "# Old Title\n"],
]);
harness.ctx.localFolders.readText = async (_companyId, _folderKey, relativePath) => {
const value = files.get(relativePath);
if (value == null) throw new Error("missing");
return value;
};
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
files.set(relativePath, contents);
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
await plugin.definition.setup(harness.ctx);
const staleWrite = harness.executeTool("wiki_write_page", {
companyId: COMPANY_ID,
wikiId: "default",
path: "wiki/concepts/plugin-boundaries.md",
contents: "# New Title\n",
expectedHash: "stale",
});
await expect(staleWrite).rejects.toThrow("Refusing to overwrite");
const result = await harness.executeTool<{ data?: { hash: string } }>("wiki_write_page", {
companyId: COMPANY_ID,
wikiId: "default",
path: "wiki/concepts/plugin-boundaries.md",
contents: "# Plugin Boundaries\n\nSee [Knowledge](wiki/areas/knowledge.md).",
});
expect(result.data?.hash).toHaveLength(64);
expect(files.get("wiki/concepts/plugin-boundaries.md")).toContain("Plugin Boundaries");
expect(harness.dbExecutes.some((execute) => execute.sql.includes("wiki_pages"))).toBe(true);
expect(harness.dbExecutes.some((execute) => execute.sql.includes("wiki_page_revisions"))).toBe(true);
});
it("blocks agent-tool writes to AGENTS.md but allows explicit board edits", async () => {
const harness = createTestHarness({ manifest });
const files = new Map<string, string>([
["AGENTS.md", "# LLM Wiki Maintainer\n\nOriginal instructions.\n"],
]);
harness.ctx.localFolders.readText = async (_companyId, _folderKey, relativePath) => {
const value = files.get(relativePath);
if (value == null) throw new Error("missing");
return value;
};
harness.ctx.localFolders.writeTextAtomic = async (_companyId, _folderKey, relativePath, contents) => {
files.set(relativePath, contents);
return harness.ctx.localFolders.status(COMPANY_ID, "wiki-root");
};
await plugin.definition.setup(harness.ctx);
await expect(harness.executeTool("wiki_write_page", {
companyId: COMPANY_ID,
wikiId: "default",
path: "AGENTS.md",
contents: "# LLM Wiki Maintainer\n\nCompromised instructions.\n",
})).rejects.toThrow("Refusing to overwrite protected wiki control file AGENTS.md");
const result = await harness.performAction<{ hash: string }>("write-page", {
companyId: COMPANY_ID,
wikiId: "default",
path: "AGENTS.md",
contents: "# LLM Wiki Maintainer\n\nBoard-updated instructions.\n",
});
expect(result.hash).toHaveLength(64);
expect(files.get("AGENTS.md")).toContain("Board-updated instructions.");
});
it("creates plugin-operation issues for LLM workflows", async () => {
const harness = createTestHarness({ manifest });
harness.seed({ agents: [wikiMaintainerAgent()] });
await plugin.definition.setup(harness.ctx);
const result = await harness.performAction<{ issue: { originKind: string; billingCode: string | null } }>(
"create-operation",
{
companyId: COMPANY_ID,
operationType: "query",
title: "Ask the wiki about plugin boundaries",
prompt: "Which files own wiki behavior?",
},
);
expect(result.issue.originKind).toBe(`${OPERATION_ORIGIN_KIND}:query`);
expect(result.issue.billingCode).toBe("plugin-llm-wiki:default");
expect(harness.dbExecutes.some((execute) => execute.sql.includes("wiki_resource_bindings"))).toBe(true);
expect(harness.dbExecutes.some((execute) => execute.sql.includes("wiki_operations"))).toBe(true);
});
it("stamps resolved space context into hidden operation issues and operation metadata", async () => {
const harness = createTestHarness({ manifest });
harness.seed({ agents: [wikiMaintainerAgent()] });
const spaces = new Map<string, Record<string, unknown>>();
const originalQuery = harness.ctx.db.query.bind(harness.ctx.db);
harness.ctx.db.query = async <T,>(sql: string, params?: unknown[]) => {
if (sql.includes("wiki_spaces")) {
const slug = typeof params?.[2] === "string" ? params[2] : null;
if (slug && spaces.has(slug)) return [spaces.get(slug)] as T[];
}
return originalQuery<T>(sql, params);
};
await plugin.definition.setup(harness.ctx);
const created = await harness.performAction<{
space: { id: string; companyId: string; wikiId: string; slug: string; displayName: string; pathPrefix: string | null };
}>("create-space", {
companyId: COMPANY_ID,
displayName: "Research Space",
});
spaces.set(created.space.slug, managedSpaceRow(created));
const result = await harness.performAction<{
operationId: string;
issue: { title: string; description: string | null; billingCode: string | null; originId: string | null };
}>("create-operation", {
companyId: COMPANY_ID,
operationType: "lint",
title: "Run LLM Wiki lint",
prompt: "Audit wiki structure.",
spaceSlug: created.space.slug,
});
expect(result.issue.title).toBe("Run LLM Wiki lint [space: Research Space / research-space]");
expect(result.issue.description).toContain("Space: Research Space (research-space)");
expect(result.issue.description).toContain("Space root: wiki-root/spaces/research-space");
expect(result.issue.description).toContain("Pass wikiId `default` and spaceSlug `research-space`");
expect(result.issue.description).toContain("Manual ingest, query, lint, index, and file-as-page operations follow the named destination space");
expect(result.issue.billingCode).toBe("plugin-llm-wiki:default:research-space");
expect(result.issue.originId).toBe(`wiki:default:space:research-space:operation:${result.operationId}`);
const operationInsert = harness.dbExecutes.find((execute) =>
execute.sql.includes("wiki_operations") && execute.params?.[0] === result.operationId);
const metadata = JSON.parse(String(operationInsert?.params?.[8]));
expect(metadata).toMatchObject({
operationType: "lint",
operationId: result.operationId,
wikiId: "default",
spaceId: created.space.id,
spaceSlug: "research-space",
spaceName: "Research Space",
spaceRoot: "wiki-root/spaces/research-space",
billingCode: "plugin-llm-wiki:default:research-space",
});
});
it("uses selected existing agent and project bindings for new operations", async () => {
const harness = createTestHarness({ manifest });
const agent = existingAgent();
const project = existingProject();
harness.seed({ agents: [agent], projects: [project] });
await plugin.definition.setup(harness.ctx);
const selectedAgent = await harness.performAction<{ source: string; agentId: string }>("select-managed-agent", {
companyId: COMPANY_ID,
agentId: agent.id,
});
const selectedProject = await harness.performAction<{ source: string; projectId: string }>("select-managed-project", {
companyId: COMPANY_ID,
projectId: project.id,
});
expect(selectedAgent).toMatchObject({ source: "selected", agentId: agent.id });
expect(selectedProject).toMatchObject({ source: "selected", projectId: project.id });
expect(harness.dbExecutes.filter((execute) => execute.sql.includes("wiki_resource_bindings"))).toHaveLength(2);
harness.ctx.db.query = async <T = Record<string, unknown>>(sql: string, params?: unknown[]) => {
harness.dbQueries.push({ sql, params });
if (sql.includes("wiki_resource_bindings") && params?.[2] === "agent") {
return [{ resolved_id: agent.id, metadata: { source: "selected-existing" } }] as T[];
}
if (sql.includes("wiki_resource_bindings") && params?.[2] === "project") {
return [{ resolved_id: project.id, metadata: { source: "selected-existing" } }] as T[];
}
if (sql.includes("wiki_operations")) return [{ count: "0" }] as T[];
return [];
};
const result = await harness.performAction<{
issue: { assigneeAgentId: string | null; projectId: string | null };
}>("create-operation", {
companyId: COMPANY_ID,
operationType: "lint",
title: "Lint selected wiki",
});
expect(result.issue.assigneeAgentId).toBe(agent.id);
expect(result.issue.projectId).toBe(project.id);
});
it("starts query sessions, records run ids, and forwards session events to plugin streams", async () => {
const harness = createTestHarness({ manifest });
harness.seed({ agents: [wikiMaintainerAgent()] });
let issuedRunId: string | undefined;
const originalSendMessage = harness.ctx.agents.sessions.sendMessage.bind(harness.ctx.agents.sessions);
harness.ctx.agents.sessions.sendMessage = async (...args) => {
const receipt = await originalSendMessage(...args);
issuedRunId = receipt.runId;
return receipt;
};
const streamEvents: unknown[] = [];
harness.ctx.streams.emit = (_channel, event) => {
streamEvents.push(event);
};
await plugin.definition.setup(harness.ctx);
const result = await harness.performAction<{
operationId: string;
querySessionId: string;
sessionId: string;
runId: string;
channel: string;
}>("start-query", {
companyId: COMPANY_ID,
question: "Which files own wiki behavior?",
});
expect(result.querySessionId).toBe(result.operationId);
expect(result.channel).toBe(`llm-wiki:query:${result.operationId}`);
expect(harness.dbExecutes.some((execute) => execute.sql.includes("wiki_query_sessions"))).toBe(true);
expect(issuedRunId).toEqual(expect.any(String));
expect(issuedRunId).not.toBe("");
expect(result.runId).toBe(issuedRunId);
const runUpdate = harness.dbExecutes.find((execute) =>
/UPDATE .*wiki_operations/.test(execute.sql) && execute.sql.includes("run_ids"),
);
expect(runUpdate?.params?.slice(0, 4)).toEqual([
COMPANY_ID, result.operationId, "running", JSON.stringify([issuedRunId]),
]);
harness.simulateSessionEvent(result.sessionId, {
runId: result.runId,
seq: 1,
eventType: "chunk",
stream: "stdout",
message: "Keep wiki behavior in the plugin.",
payload: null,
});
harness.simulateSessionEvent(result.sessionId, {
runId: result.runId,
seq: 2,
eventType: "done",
stream: "system",
message: "Run completed",
payload: null,
});
await new Promise((resolve) => setTimeout(resolve, 0));
expect(streamEvents).toEqual(expect.arrayContaining([
expect.objectContaining({ type: "query.started", operationId: result.operationId }),
expect.objectContaining({ type: "agent.event", message: "Keep wiki behavior in the plugin." }),
expect.objectContaining({ type: "query.done", answer: "Keep wiki behavior in the plugin." }),
]));
expect(harness.dbExecutes.some((execute) =>
execute.sql.includes("wiki_query_sessions") && execute.params?.includes("completed"),
)).toBe(true);
});
it("files a streamed query answer as a page through a hidden file-as-page operation", async () => {
const harness = createTestHarness({ manifest });
harness.seed({ agents: [wikiMaintainerAgent()] });
const writes = captureWikiWrites(harness);
await plugin.definition.setup(harness.ctx);
const result = await harness.performAction<{ path: string; operationId: string; page: { revisionId: string } }>(
"file-as-page",
{
companyId: COMPANY_ID,
querySessionId: "33333333-3333-4333-8333-333333333333",
question: "Where should wiki code live?",
answer: "Wiki-specific code lives in the standalone plugin package.",
path: "wiki/concepts/plugin-boundaries.md",
title: "Plugin Boundaries",
},
);
expect(result.path).toBe("wiki/concepts/plugin-boundaries.md");
expect(writes[0]).toMatchObject({ path: "wiki/concepts/plugin-boundaries.md" });
expect(writes[0]?.contents).toContain("Wiki-specific code lives in the standalone plugin package.");
expect(harness.dbExecutes.some((execute) => execute.sql.includes("wiki_operations"))).toBe(true);
expect(harness.dbExecutes.some((execute) => execute.sql.includes("wiki_page_revisions"))).toBe(true);
expect(harness.dbExecutes.some((execute) => execute.sql.includes("filed_outputs"))).toBe(true);
});
});