{"repo": "christopherarter/deep-pi", "files": {"docs/superpowers/plans/2026-08-04-deeppi-performance-core.md": {"c2e9a4a125f3b971a8ef8aa82aff833ca00d8343": {"t": 1786068441.0535474, "n": 61099, "h": "aa2ccf69fbf7c816", "c": "# DeepPi Performance Core Implementation Plan\n\n> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [x]) syntax for tracking.\n\n**Goal:** Build DeepPi, a direct-DeepSeek performance extension for Pi that stabilizes cache prefixes, reports measured cache economics, and reduces paid tool/edit retries.\n\n**Architecture:** One Pi entry point wires five focused modules: exact model eligibility, request stability/prefix diagnostics, usage telemetry, batch-aware storm-breaking, and hashline editing. Pi remains responsible for provider serialization and normalized usage/cost; DeepPi is dormant and request-byte-neutral outside direct `deepseek-v4-flash` and `deepseek-v4-pro`.\n\n**Tech Stack:** TypeScript 5.9, Node.js 22.19+, Pi ExtensionAPI, Vitest 4, Node standard library.\n\n## Global Constraints\n\n- Product name is `DeepPi`; package name is `deep-pi`; command name is `/deeppi`.\n- Eligible provider is exactly `deepseek`; eligible model IDs are exactly `deepseek-v4-flash` and `deepseek-v4-pro`.\n- OpenRouter, proxies, fuzzy model matching, plan mode, rewind, persistence, and npm publication are out of scope.\n- Add no runtime or development dependency.\n- Default tests and `npm run verify` must make no network calls and require no credentials.\n- The live benchmark must require `DEEPPI_LIVE=1`, `DEEPSEEK_API_KEY`, and interactive confirmation or `DEEPPI_LIVE_CONFIRM=I_ACCEPT_COST`.\n- Keep the original BSD-3-Clause copyright notice and add a separate notice for Christopher Arter's DeepPi modifications.\n- Preserve the existing uncommitted `package-lock.json` correction and `.pi-subagents/`; never discard or stage `.pi-subagents/`.\n- Use the current worktree's `package-lock.json` as the base when Task 7 intentionally changes its package name and version.\n- This plan file is intentionally untracked when execution begins; include it in Task 1's commit.\n- Per project `AGENTS.md`, prefix every shell command shown below with `rtk` when executing it.\n\n## Final File Structure\n\n```text\nextensions/\n deeppi.ts Plugin entry point, command, footer, lifecycle wiring\n deeppi/\n eligibility.ts Exact provider/model gate and edit_lines active-tool gate\n stability.ts Thinking pruning, timestamp freezing, tool sorting, prefix shapes\n telemetry.ts Per-model usage aggregation, savings, footer/report formatting\n stormbreaker.ts Batch collection, error enhancement, guard/abort escalation\n hashlines.ts Read annotations and atomic hash-verified edit_lines tool\n utils.ts Shared line-hash and error-text utilities\ntests/\n fake-pi.ts Minimal reusable ExtensionAPI/context test double\n eligibility.test.ts\n stability.test.ts\n telemetry.test.ts\n stormbreaker.test.ts\n hashlines.test.ts\n deeppi.integration.test.ts\n package.test.ts\nscripts/\n live-benchmark.mjs Explicitly paid direct-DeepSeek cache smoke test\n```\n\n---\n\n### Task 1: Establish the DeepPi boundary and exact eligibility\n\n**Files:**\n- Move: `extensions/harness.ts` -> `extensions/deeppi.ts`\n- Move: `extensions/harness/` -> `extensions/deeppi/`\n- Move: `tests/harness.test.ts` -> `tests/deeppi.test.ts` (temporary legacy suite; removed in Task 6)\n- Create: `extensions/deeppi/eligibility.ts`\n- Create: `tests/eligibility.test.ts`\n- Modify: `package.json`\n- Modify imports in: `extensions/deeppi.ts`, `tests/deeppi.test.ts`, `tests/benchmarks.test.ts`\n\n**Interfaces:**\n- Produces: `DeepPiModel`, `DeepPiModelId`, `isDeepPiModel(model)`, and `withEditLinesActive(activeTools, eligible)`.\n- Later tasks consume `isDeepPiModel` in every hook and `withEditLinesActive` in the entry point.\n\n- [x] **Step 1: Perform the mechanical source rename and restore a green baseline**\n\nRun:\n\n```bash\ngit mv extensions/harness.ts extensions/deeppi.ts\ngit mv extensions/harness extensions/deeppi\ngit mv tests/harness.test.ts tests/deeppi.test.ts\n```\n\nUpdate `package.json` to load the renamed entry while leaving package identity for Task 7:\n\n```json\n\"pi\": {\n \"extensions\": [\n \"./extensions/deeppi.ts\"\n ]\n}\n```\n\nChange imports from `../extensions/harness.js` to `../extensions/deeppi.js` and from `./harness/` to `./deeppi/`. Run:\n\n```bash\nnpm test\nnpm run typecheck\n```\n\nExpected: both commands pass with behavior unchanged.\n\n- [x] **Step 2: Write failing exact-eligibility tests**\n\nCreate `tests/eligibility.test.ts`:\n\n```typescript\nimport { describe, expect, it } from \"vitest\";\nimport {\n\tisDeepPiModel,\n\twithEditLinesActive,\n} from \"../extensions/deeppi/eligibility.js\";\n\ndescribe(\"isDeepPiModel\", () => {\n\tit.each([\"deepseek-v4-flash\", \"deepseek-v4-pro\"])(\n\t\t\"accepts direct DeepSeek %s\",\n\t\t(id) => expect(isDeepPiModel({ provider: \"deepseek\", id })).toBe(true),\n\t);\n\n\tit.each([\n\t\t{ provider: \"openrouter\", id: \"deepseek/deepseek-v4-pro\" },\n\t\t{ provider: \"deepseek\", id: \"deepseek-v4-pro-preview\" },\n\t\t{ provider: \"deepseek-proxy\", id: \"deepseek-v4-pro\" },\n\t\tundefined,\n\t])(\"rejects $provider/$id\", (model) => {\n\t\texpect(isDeepPiModel(model)).toBe(false);\n\t});\n});\n\ndescribe(\"withEditLinesActive\", () => {\n\tit(\"adds edit_lines once without disturbing existing tools\", () => {\n\t\texpect(withEditLinesActive([\"read\", \"bash\"], true)).toEqual([\n\t\t\t\"read\",\n\t\t\t\"bash\",\n\t\t\t\"edit_lines\",\n\t\t]);\n\t\texpect(withEditLinesActive([\"read\", \"edit_lines\"], true)).toEqual([\n\t\t\t\"read\",\n\t\t\t\"edit_lines\",\n\t\t]);\n\t});\n\n\tit(\"removes only edit_lines when DeepPi is dormant\", () => {\n\t\texpect(withEditLinesActive([\"read\", \"edit_lines\", \"bash\"], false)).toEqual([\n\t\t\t\"read\",\n\t\t\t\"bash\",\n\t\t]);\n\t});\n});\n```\n\n- [x] **Step 3: Run the focused test and verify the missing module failure**\n\nRun:\n\n```bash\nnpx vitest --run tests/eligibility.test.ts\n```\n\nExpected: FAIL because `extensions/deeppi/eligibility.ts` does not exist.\n\n- [x] **Step 4: Implement the exact eligibility and active-tool transform**\n\nCreate `extensions/deeppi/eligibility.ts`:\n\n```typescript\nexport const DEEPPI_MODEL_IDS = [\n\t\"deepseek-v4-flash\",\n\t\"deepseek-v4-pro\",\n] as const;\n\nexport type DeepPiModelId = (typeof DEEPPI_MODEL_IDS)[number];\nexport interface DeepPiModel {\n\tprovider: string;\n\tid: string;\n}\n\nconst modelIds = new Set(DEEPPI_MODEL_IDS);\n\nexport function isDeepPiModel(\n\tmodel: DeepPiModel | null | undefined,\n): model is DeepPiModel & { id: DeepPiModelId } {\n\treturn model?.provider === \"deepseek\" && modelIds.has(model.id);\n}\n\nexport function withEditLinesActive(\n\tactiveTools: readonly string[],\n\teligible: boolean,\n): string[] {\n\tconst withoutDeepPi = activeTools.filter((name) => name !== \"edit_lines\");\n\treturn eligible ? [...withoutDeepPi, \"edit_lines\"] : withoutDeepPi;\n}\n```\n\n- [x] **Step 5: Run the eligibility tests and the renamed baseline**\n\nRun:\n\n```bash\nnpx vitest --run tests/eligibility.test.ts\nnpm test\nnpm run typecheck\n```\n\nExpected: all commands pass.\n\n- [x] **Step 6: Commit the package boundary**\n\n```bash\ngit add package.json extensions/deeppi.ts extensions/deeppi tests/deeppi.test.ts tests/benchmarks.test.ts tests/eligibility.test.ts\ngit add docs/superpowers/plans/2026-08-04-deeppi-performance-core.md\ngit commit -m \"refactor: establish DeepPi package boundary\"\n```\n\n---\n\n### Task 2: Build request stability and prefix diagnostics\n\n**Files:**\n- Move: `extensions/deeppi/cache.ts` -> `extensions/deeppi/stability.ts`\n- Replace implementation in: `extensions/deeppi/stability.ts`\n- Create: `tests/stability.test.ts`\n- Modify import path in: `extensions/deeppi.ts`\n\n**Interfaces:**\n- Consumes: `DeepPiModelId` from `eligibility.ts`.\n- Produces: `StabilityState`, `PrefixShape`, `PrefixChurnReason`, `stabilizeMessages`, `freezeSessionTimestamps`, `sortProviderTools`, `capturePrefixShape`, and `classifyPrefixChurn`.\n- Task 6 consumes `StabilityState.latestChurn` and wires the hooks.\n\n- [x] **Step 1: Move the cache module and write failing Pi-format message tests**\n\nRun:\n\n```bash\ngit mv extensions/deeppi/cache.ts extensions/deeppi/stability.ts\n```\n\nUpdate the entry-point import from `./deeppi/cache.js` to `./deeppi/stability.js` before running the focused suite.\n\nCreate `tests/stability.test.ts` with the real Pi content-block shapes:\n\n```typescript\nimport { describe, expect, it } from \"vitest\";\nimport {\n\tstabilizeMessages,\n\tfreezeSessionTimestamps,\n\ttype TimestampState,\n} from \"../extensions/deeppi/stability.js\";\n\ndescribe(\"stabilizeMessages\", () => {\n\tit(\"prunes thinking from a plain assistant turn without mutating input\", () => {\n\t\tconst input = [{\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [\n\t\t\t\t{ type: \"thinking\", thinking: \"private\" },\n\t\t\t\t{ type: \"text\", text: \"answer\" },\n\t\t\t],\n\t\t}];\n\t\tconst result = stabilizeMessages(input);\n\t\texpect(result.messages[0]).toEqual({\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [{ type: \"text\", text: \"answer\" }],\n\t\t});\n\t\texpect(result.prunedThinking).toBe(1);\n\t\texpect(input[0].content).toHaveLength(2);\n\t});\n\n\tit(\"preserves thinking and signatures on a Pi toolCall turn\", () => {\n\t\tconst input = [{\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [\n\t\t\t\t{\n\t\t\t\t\ttype: \"thinking\",\n\t\t\t\t\tthinking: \"need the file\",\n\t\t\t\t\tthinkingSignature: \"reasoning_content\",\n\t\t\t\t},\n\t\t\t\t{ type: \"toolCall\", id: \"call-1\", name: \"read\", arguments: { path: \"a.ts\" } },\n\t\t\t],\n\t\t}];\n\t\tconst result = stabilizeMessages(input);\n\t\texpect(result.messages).toEqual(input);\n\t\texpect(result.preservedThinking).toBe(1);\n\t});\n});\n\ndescribe(\"freezeSessionTimestamps\", () => {\n\tit(\"freezes recognized generated lines but preserves user-authored dates\", () => {\n\t\tconst state: TimestampState = { frozenLines: new Map() };\n\t\tconst first = freezeSessionTimestamps(\n\t\t\t\"Current date and time is: 2026-08-04 10:00\\nShip on 2026-08-08.\",\n\t\t\tstate,\n\t\t);\n\t\tconst second = freezeSessionTimestamps(\n\t\t\t\"Current date and time is: 2026-08-04 10:01\\nShip on 2026-08-08.\",\n\t\t\tstate,\n\t\t);\n\t\texpect(second).toBe(first);\n\t\texpect(second).toContain(\"Ship on 2026-08-08.\");\n\t});\n});\n```\n\n- [x] **Step 2: Run the message tests and verify the export failures**\n\nRun:\n\n```bash\nnpx vitest --run tests/stability.test.ts\n```\n\nExpected: FAIL because the new stability exports are absent.\n\n- [x] **Step 3: Implement thinking pruning and session timestamp freezing**\n\nReplace the reasoning/timestamp helpers in `extensions/deeppi/stability.ts` with:\n\n```typescript\ntype ContentBlock = Record & { type?: string };\ntype MessageLike = Record & { role?: string; content?: unknown };\n\nexport interface TimestampState {\n\tfrozenLines: Map;\n}\n\nconst GENERATED_TIME_LINE =\n\t/^(Current date\\/time is:|Current date and time is:|Today is:|Date:|Time:)\\s*.*$/gim;\n\nexport function stabilizeMessages(messages: readonly T[]): {\n\tmessages: T[];\n\tprunedThinking: number;\n\tpreservedThinking: number;\n} {\n\tlet prunedThinking = 0;\n\tlet preservedThinking = 0;\n\tconst stabilized = messages.map((message) => {\n\t\tif (message.role !== \"assistant\" || !Array.isArray(message.content)) return message;\n\t\tconst blocks = message.content as ContentBlock[];\n\t\tconst hasToolCall = blocks.some((block) => block.type === \"toolCall\");\n\t\tif (hasToolCall) {\n\t\t\tpreservedThinking += blocks.filter((block) => block.type === \"thinking\").length;\n\t\t\treturn message;\n\t\t}\n\t\tconst content = blocks.filter((block) => {\n\t\t\tif (block.type !== \"thinking\") return true;\n\t\t\tprunedThinking++;\n\t\t\treturn false;\n\t\t});\n\t\treturn { ...message, content };\n\t});\n\treturn { messages: stabilized, prunedThinking, preservedThinking };\n}\n\nexport function freezeSessionTimestamps(prompt: string, state: TimestampState): string {\n\treturn prompt.replace(GENERATED_TIME_LINE, (line, label: string) => {\n\t\tconst key = label.toLowerCase();\n\t\tconst frozen = state.frozenLines.get(key);\n\t\tif (frozen) return frozen;\n\t\tstate.frozenLines.set(key, line);\n\t\treturn line;\n\t});\n}\n```\n\n- [x] **Step 4: Add failing deterministic-tool and prefix-shape tests**\n\nAppend to `tests/stability.test.ts`:\n\n```typescript\nimport {\n\tcapturePrefixShape,\n\tclassifyPrefixChurn,\n\tsortProviderTools,\n\ttype PrefixChurnReason,\n\ttype PrefixShape,\n} from \"../extensions/deeppi/stability.js\";\n\nit(\"sorts OpenAI tool schemas deterministically without changing members\", () => {\n\tconst payload: Record = {\n\t\ttools: [\n\t\t\t{ type: \"function\", function: { name: \"write\" } },\n\t\t\t{ type: \"function\", function: { name: \"read\" } },\n\t\t],\n\t};\n\texpect(sortProviderTools(payload)).toBe(true);\n\texpect((payload.tools as Array<{ function: { name: string } }>).map((tool) => tool.function.name))\n\t\t.toEqual([\"read\", \"write\"]);\n});\n\nit(\"treats appended conversation messages as stable growth\", () => {\n\tconst previous = capturePrefixShape(\"deepseek-v4-pro\", {\n\t\tmessages: [\n\t\t\t{ role: \"system\", content: \"stable\" },\n\t\t\t{ role: \"user\", content: \"one\" },\n\t\t],\n\t\ttools: [{ type: \"function\", function: { name: \"read\" } }],\n\t});\n\tconst current = capturePrefixShape(\"deepseek-v4-pro\", {\n\t\tmessages: [\n\t\t\t{ role: \"system\", content: \"stable\" },\n\t\t\t{ role: \"user\", content: \"one\" },\n\t\t\t{ role: \"assistant\", content: \"answer\" },\n\t\t\t{ role: \"user\", content: \"two\" },\n\t\t],\n\t\ttools: [{ type: \"function\", function: { name: \"read\" } }],\n\t});\n\texpect(classifyPrefixChurn(previous, current)).toEqual([]);\n});\n\nconst churnCases: Array<[PrefixChurnReason, Partial]> = [\n\t[\"model\", { modelId: \"deepseek-v4-flash\" }],\n\t[\"system-prompt\", { systemDigest: \"changed\" }],\n\t[\"tool-schema\", { toolsDigest: \"changed\" }],\n\t[\"conversation-history\", { messageDigests: [\"changed\"] }],\n];\n\nit.each(churnCases)(\"classifies %s churn\", (reason, change) => {\n\tconst base = capturePrefixShape(\"deepseek-v4-pro\", {\n\t\tmessages: [{ role: \"system\", content: \"stable\" }, { role: \"user\", content: \"one\" }],\n\t\ttools: [{ type: \"function\", function: { name: \"read\" } }],\n\t});\n\texpect(classifyPrefixChurn(base, { ...base, ...change })).toContain(reason);\n});\n```\n\n- [x] **Step 5: Run the prefix tests and verify the missing export failures**\n\nRun:\n\n```bash\nnpx vitest --run tests/stability.test.ts\n```\n\nExpected: FAIL because tool sorting and prefix-shape functions are absent.\n\n- [x] **Step 6: Implement deterministic sorting and prefix classification**\n\nAdd to `extensions/deeppi/stability.ts`:\n\n```typescript\nimport { createHash } from \"node:crypto\";\nimport type { DeepPiModelId } from \"./eligibility.js\";\n\nexport type PrefixChurnReason =\n\t| \"model\"\n\t| \"system-prompt\"\n\t| \"tool-schema\"\n\t| \"conversation-history\";\n\nexport interface PrefixShape {\n\tmodelId: DeepPiModelId;\n\tsystemDigest: string;\n\ttoolsDigest: string;\n\tmessageDigests: string[];\n}\n\nfunction digest(value: unknown): string {\n\treturn createHash(\"sha256\").update(JSON.stringify(value) ?? \"undefined\").digest(\"hex\");\n}\n\nfunction toolName(value: unknown): string {\n\tconst tool = value as { name?: unknown; function?: { name?: unknown } } | undefined;\n\tconst name = tool?.function?.name ?? tool?.name;\n\treturn typeof name === \"string\" ? name : \"\";\n}\n\nexport function sortProviderTools(payload: Record): boolean {\n\tif (!Array.isArray(payload.tools)) return false;\n\tconst sorted = [...payload.tools].sort((left, right) =>\n\t\ttoolName(left).localeCompare(toolName(right)),\n\t);\n\tpayload.tools = sorted;\n\treturn true;\n}\n\nexport function capturePrefixShape(\n\tmodelId: DeepPiModelId,\n\tpayload: Record,\n): PrefixShape {\n\tconst messages = Array.isArray(payload.messages) ? payload.messages : [];\n\tconst system = messages.find((value) => {\n\t\tconst role = (value as { role?: unknown })?.role;\n\t\treturn role === \"system\" || role === \"developer\";\n\t});\n\tconst conversation = messages.filter((value) => {\n\t\tconst role = (value as { role?: unknown })?.role;\n\t\treturn role !== \"system\" && role !== \"developer\";\n\t});\n\treturn {\n\t\tmodelId,\n\t\tsystemDigest: digest(system ?? null),\n\t\ttoolsDigest: digest(Array.isArray(payload.tools) ? payload.tools : []),\n\t\tmessageDigests: conversation.map(digest),\n\t};\n}\n\nexport function classifyPrefixChurn(\n\tprevious: PrefixShape,\n\tcurrent: PrefixShape,\n): PrefixChurnReason[] {\n\tconst reasons: PrefixChurnReason[] = [];\n\tif (previous.modelId !== current.modelId) reasons.push(\"model\");\n\tif (previous.systemDigest !== current.systemDigest) reasons.push(\"system-prompt\");\n\tif (previous.toolsDigest !== current.toolsDigest) reasons.push(\"tool-schema\");\n\tconst historyChanged =\n\t\tprevious.messageDigests.length > current.messageDigests.length ||\n\t\tprevious.messageDigests.some((value, index) => current.messageDigests[index] !== value);\n\tif (historyChanged) reasons.push(\"conversation-history\");\n\treturn reasons;\n}\n\nexport interface StabilityState extends TimestampState {\n\tpreviousShape: PrefixShape | null;\n\tlatestChurn: PrefixChurnReason[];\n\tprunedThinking: number;\n\tpreservedThinking: number;\n\ttransformErrors: number;\n}\n\nexport function createStabilityState(): StabilityState {\n\treturn {\n\t\tfrozenLines: new Map(),\n\t\tpreviousShape: null,\n\t\tlatestChurn: [],\n\t\tprunedThinking: 0,\n\t\tpreservedThinking: 0,\n\t\ttransformErrors: 0,\n\t};\n}\n```\n\n- [x] **Step 7: Run focused and full verification**\n\nRun:\n\n```bash\nnpx vitest --run tests/stability.test.ts\nnpm test\nnpm run typecheck\n```\n\nExpected: all commands pass.\n\n- [x] **Step 8: Commit request stability**\n\n```bash\ngit add extensions/deeppi.ts extensions/deeppi/stability.ts tests/stability.test.ts\ngit commit -m \"feat: stabilize direct DeepSeek request prefixes\"\n```\n\n---\n\n### Task 3: Add measured cache economics and reporting\n\n**Files:**\n- Create: `extensions/deeppi/telemetry.ts`\n- Create: `tests/telemetry.test.ts`\n\n**Interfaces:**\n- Consumes: `DeepPiModelId` and `PrefixChurnReason`.\n- Produces: `TelemetryState`, `recordUsage`, `cacheHitRate`, `footerText`, and `formatDeepPiReport`.\n- Task 6 calls `recordUsage` from `message_end` and supplies retry/hashline counters to `formatDeepPiReport`.\n\n- [x] **Step 1: Write failing telemetry formula tests**\n\nCreate `tests/telemetry.test.ts`:\n\n```typescript\nimport { describe, expect, it } from \"vitest\";\nimport {\n\tcacheHitRate,\n\tcreateTelemetryState,\n\tfooterText,\n\trecordUsage,\n} from \"../extensions/deeppi/telemetry.js\";\n\nconst pro = {\n\tprovider: \"deepseek\",\n\tid: \"deepseek-v4-pro\" as const,\n\tcost: { input: 1.74, output: 3.48, cacheRead: 0.145, cacheWrite: 0 },\n};\n\nit(\"records normalized Pi usage and model-aware savings\", () => {\n\tconst state = createTelemetryState();\n\trecordUsage(state, pro, {\n\t\tinput: 20_000,\n\t\toutput: 1_000,\n\t\tcacheRead: 80_000,\n\t\tcacheWrite: 0,\n\t\ttotalTokens: 101_000,\n\t\tcost: { input: 0.0348, output: 0.00348, cacheRead: 0.0116, cacheWrite: 0, total: 0.04988 },\n\t});\n\tconst totals = state.byModel[\"deepseek-v4-pro\"];\n\texpect(totals.responses).toBe(1);\n\texpect(totals.hitTokens).toBe(80_000);\n\texpect(totals.missTokens).toBe(20_000);\n\texpect(cacheHitRate(totals)).toBe(0.8);\n\texpect(totals.actualInputCost).toBeCloseTo(0.0464);\n\texpect(totals.estimatedSavings).toBeCloseTo(0.1276);\n\texpect(footerText(state, \"deepseek-v4-pro\")).toBe(\"DeepPi · 80% cache\");\n});\n\nit(\"omits rates and savings when usage or matching pricing is unavailable\", () => {\n\tconst state = createTelemetryState();\n\texpect(footerText(state, \"deepseek-v4-flash\")).toBe(\"DeepPi · warming\");\n\trecordUsage(state, null, {\n\t\tinput: 0,\n\t\toutput: 0,\n\t\tcacheRead: 0,\n\t\tcacheWrite: 0,\n\t\ttotalTokens: 0,\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t});\n\texpect(state.usageUnavailable).toBe(true);\n});\n```\n\n- [x] **Step 2: Run the telemetry test and verify the missing module failure**\n\nRun:\n\n```bash\nnpx vitest --run tests/telemetry.test.ts\n```\n\nExpected: FAIL because `telemetry.ts` does not exist.\n\n- [x] **Step 3: Implement per-model totals and formulas**\n\nCreate `extensions/deeppi/telemetry.ts`:\n\n```typescript\nimport type { DeepPiModelId } from \"./eligibility.js\";\nimport type { PrefixChurnReason } from \"./stability.js\";\n\nexport interface PiUsage {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\ttotalTokens: number;\n\tcost: { input: number; output: number; cacheRead: number; cacheWrite: number; total: number };\n}\n\nexport interface PricedModel {\n\tprovider: string;\n\tid: DeepPiModelId;\n\tcost: { input: number; output: number; cacheRead: number; cacheWrite: number };\n}\n\nexport interface ModelTotals {\n\tresponses: number;\n\thitTokens: number;\n\tmissTokens: number;\n\tactualInputCost: number;\n\testimatedSavings: number;\n}\n\nexport interface TelemetryState {\n\tbyModel: Record;\n\tusageUnavailable: boolean;\n\tlatestChurn: PrefixChurnReason[];\n}\n\nfunction emptyTotals(): ModelTotals {\n\treturn { responses: 0, hitTokens: 0, missTokens: 0, actualInputCost: 0, estimatedSavings: 0 };\n}\n\nexport function createTelemetryState(): TelemetryState {\n\treturn {\n\t\tbyModel: { \"deepseek-v4-flash\": emptyTotals(), \"deepseek-v4-pro\": emptyTotals() },\n\t\tusageUnavailable: false,\n\t\tlatestChurn: [],\n\t};\n}\n\nexport function recordUsage(\n\tstate: TelemetryState,\n\tmodel: PricedModel | null,\n\tusage: PiUsage,\n): boolean {\n\tif (!model || usage.input + usage.cacheRead === 0) {\n\t\tstate.usageUnavailable = true;\n\t\treturn false;\n\t}\n\tconst totals = state.byModel[model.id];\n\ttotals.responses++;\n\ttotals.hitTokens += usage.cacheRead;\n\ttotals.missTokens += usage.input;\n\ttotals.actualInputCost += usage.cost.input + usage.cost.cacheRead;\n\ttotals.estimatedSavings +=\n\t\t(usage.cacheRead / 1_000_000) * (model.cost.input - model.cost.cacheRead);\n\treturn true;\n}\n\nexport function cacheHitRate(totals: ModelTotals): number | null {\n\tconst input = totals.hitTokens + totals.missTokens;\n\treturn input === 0 ? null : totals.hitTokens / input;\n}\n\nexport function footerText(state: TelemetryState, modelId: DeepPiModelId): string {\n\tconst rate = cacheHitRate(state.byModel[modelId]);\n\treturn rate === null ? \"DeepPi · warming\" : `DeepPi · ${Math.round(rate * 100)}% cache`;\n}\n```\n\n- [x] **Step 4: Write a failing report-format test**\n\nAppend to `tests/telemetry.test.ts`:\n\n```typescript\nimport { formatDeepPiReport } from \"../extensions/deeppi/telemetry.js\";\n\nit(\"renders measured economics and runtime counters\", () => {\n\tconst state = createTelemetryState();\n\trecordUsage(state, pro, {\n\t\tinput: 20_000,\n\t\toutput: 1_000,\n\t\tcacheRead: 80_000,\n\t\tcacheWrite: 0,\n\t\ttotalTokens: 101_000,\n\t\tcost: { input: 0.0348, output: 0.00348, cacheRead: 0.0116, cacheWrite: 0, total: 0.04988 },\n\t});\n\tstate.latestChurn = [\"tool-schema\"];\n\tconst report = formatDeepPiReport({\n\t\teligible: true,\n\t\tmodelId: \"deepseek-v4-pro\",\n\t\ttelemetry: state,\n\t\tloopsGuarded: 2,\n\t\tloopsAborted: 1,\n\t\teditAttempts: 5,\n\t\teditMismatches: 1,\n\t\teditSuccesses: 4,\n\t});\n\texpect(report).toContain(\"Model: deepseek-v4-pro\");\n\texpect(report).toContain(\"Cache hit rate: 80.0%\");\n\texpect(report).toContain(\"Prefix churn: tool-schema\");\n\texpect(report).toContain(\"Loops guarded: 2\");\n});\n```\n\n- [x] **Step 5: Run the report test and verify the missing export failure**\n\nRun:\n\n```bash\nnpx vitest --run tests/telemetry.test.ts\n```\n\nExpected: FAIL because `formatDeepPiReport` is absent.\n\n- [x] **Step 6: Implement the report formatter**\n\nAdd a `ReportInput` interface and formatter to `telemetry.ts`. Use these exact labels so command output remains testable:\n\n```typescript\nexport interface ReportInput {\n\teligible: boolean;\n\tmodelId: DeepPiModelId | null;\n\ttelemetry: TelemetryState;\n\tloopsGuarded: number;\n\tloopsAborted: number;\n\teditAttempts: number;\n\teditMismatches: number;\n\teditSuccesses: number;\n}\n\nexport function formatDeepPiReport(input: ReportInput): string {\n\tif (!input.eligible || !input.modelId) return \"DeepPi is dormant for the active model.\";\n\tconst totals = input.telemetry.byModel[input.modelId];\n\tconst rate = cacheHitRate(totals);\n\tconst churn = input.telemetry.latestChurn.length === 0\n\t\t? \"none\"\n\t\t: input.telemetry.latestChurn.join(\", \");\n\treturn [\n\t\t`Model: ${input.modelId}`,\n\t\t`Responses: ${totals.responses}`,\n\t\t`Cache read: ${totals.hitTokens.toLocaleString()} tokens`,\n\t\t`Uncached input: ${totals.missTokens.toLocaleString()} tokens`,\n\t\t`Cache hit rate: ${rate === null ? \"unavailable\" : `${(rate * 100).toFixed(1)}%`}`,\n\t\t`Actual input cost: $${totals.actualInputCost.toFixed(4)}`,\n\t\t`Estimated savings: $${totals.estimatedSavings.toFixed(4)}`,\n\t\t`Prefix churn: ${churn}`,\n\t\t`Loops guarded: ${input.loopsGuarded}`,\n\t\t`Loops aborted: ${input.loopsAborted}`,\n\t\t`Edit attempts: ${input.editAttempts}`,\n\t\t`Edit mismatches: ${input.editMismatches}`,\n\t\t`Edit successes: ${input.editSuccesses}`,\n\t].join(\"\\n\");\n}\n```\n\n- [x] **Step 7: Run focused and full verification**\n\nRun:\n\n```bash\nnpx vitest --run tests/telemetry.test.ts\nnpm test\nnpm run typecheck\n```\n\nExpected: all commands pass.\n\n- [x] **Step 8: Commit telemetry**\n\n```bash\ngit add extensions/deeppi/telemetry.ts tests/telemetry.test.ts\ngit commit -m \"feat: measure DeepSeek cache economics\"\n```\n\n---\n\n### Task 4: Replace per-call storm tracking with batch-aware retry economy\n\n**Files:**\n- Replace implementation in: `extensions/deeppi/stormbreaker.ts`\n- Create: `tests/stormbreaker.test.ts`\n- Modify shared error helpers in: `extensions/deeppi/utils.ts`\n\n**Interfaces:**\n- Consumes: `isDeepPiModel`.\n- Produces: `StormBreakerState`, `startToolBatch`, `recordToolOutcome`, `resetStormBreaker`, and `registerStormBreaker(pi, eligible)`.\n- Task 6 reads `guardsInjected` and `loopsAborted` for `/deeppi`.\n\n- [x] **Step 1: Write failing batch reducer tests**\n\nCreate `tests/stormbreaker.test.ts`:\n\n```typescript\nimport { describe, expect, it } from \"vitest\";\nimport {\n\tcreateStormBreakerState,\n\trecordToolOutcome,\n\tstartToolBatch,\n} from \"../extensions/deeppi/stormbreaker.js\";\n\nconst calls = [\n\t{ id: \"a\", name: \"read\" },\n\t{ id: \"b\", name: \"grep\" },\n];\n\nfunction failBatch(state: ReturnType, suffix = \"\") {\n\tstartToolBatch(state, calls);\n\texpect(recordToolOutcome(state, { id: \"b\", name: \"grep\", isError: true, text: `denied ${suffix}` }).kind)\n\t\t.toBe(\"pending\");\n\treturn recordToolOutcome(state, { id: \"a\", name: \"read\", isError: true, text: `missing ${suffix}` });\n}\n\nit(\"injects a guard on the third equivalent all-failed batch and aborts the fourth\", () => {\n\tconst state = createStormBreakerState();\n\texpect(failBatch(state).kind).toBe(\"none\");\n\texpect(failBatch(state).kind).toBe(\"none\");\n\texpect(failBatch(state).kind).toBe(\"guard\");\n\texpect(failBatch(state).kind).toBe(\"abort\");\n});\n\nit(\"resets both streaks when any tool succeeds\", () => {\n\tconst state = createStormBreakerState();\n\tfailBatch(state);\n\tfailBatch(state);\n\tstartToolBatch(state, calls);\n\trecordToolOutcome(state, { id: \"a\", name: \"read\", isError: false, text: \"ok\" });\n\texpect(recordToolOutcome(state, { id: \"b\", name: \"grep\", isError: true, text: \"denied\" }).kind)\n\t\t.toBe(\"none\");\n\texpect(state.repeatCount).toBe(0);\n\texpect(state.blockedTurnStreak).toBe(0);\n});\n\nit(\"guards alternating all-failed batches through the blocked-turn streak\", () => {\n\tconst state = createStormBreakerState();\n\texpect(failBatch(state, \"one\").kind).toBe(\"none\");\n\texpect(failBatch(state, \"two\").kind).toBe(\"none\");\n\texpect(failBatch(state, \"three\").kind).toBe(\"guard\");\n});\n```\n\n- [x] **Step 2: Run the reducer tests and verify missing exports**\n\nRun:\n\n```bash\nnpx vitest --run tests/stormbreaker.test.ts\n```\n\nExpected: FAIL because the batch reducer exports are absent.\n\n- [x] **Step 3: Implement order-stable batch collection and escalation**\n\nReplace the current single-record tracking with these state and reducer shapes:\n\n```typescript\nexport interface ExpectedToolCall { id: string; name: string }\nexport interface ToolOutcome extends ExpectedToolCall { isError: boolean; text: string }\nexport type StormDecision =\n\t| { kind: \"pending\" | \"none\" }\n\t| { kind: \"guard\" | \"abort\"; message: string };\n\nexport interface StormBreakerState {\n\texpected: ExpectedToolCall[];\n\toutcomes: Map;\n\tlastSignature: string | null;\n\trepeatCount: number;\n\tblockedTurnStreak: number;\n\tguardsInjected: number;\n\tloopsAborted: number;\n\terrorsEnhanced: number;\n}\n\nexport function createStormBreakerState(): StormBreakerState {\n\treturn {\n\t\texpected: [], outcomes: new Map(), lastSignature: null, repeatCount: 0,\n\t\tblockedTurnStreak: 0, guardsInjected: 0, loopsAborted: 0, errorsEnhanced: 0,\n\t};\n}\n\nexport function startToolBatch(state: StormBreakerState, calls: ExpectedToolCall[]): void {\n\tstate.expected = calls;\n\tstate.outcomes = new Map();\n}\n\nexport function recordToolOutcome(\n\tstate: StormBreakerState,\n\toutcome: ToolOutcome,\n): StormDecision {\n\tif (!state.expected.some((call) => call.id === outcome.id)) return { kind: \"none\" };\n\tstate.outcomes.set(outcome.id, outcome);\n\tif (state.outcomes.size < state.expected.length) return { kind: \"pending\" };\n\tconst ordered = state.expected.map((call) => state.outcomes.get(call.id)!);\n\tstate.expected = [];\n\tstate.outcomes = new Map();\n\tif (ordered.some((value) => !value.isError)) {\n\t\tstate.lastSignature = null;\n\t\tstate.repeatCount = 0;\n\t\tstate.blockedTurnStreak = 0;\n\t\treturn { kind: \"none\" };\n\t}\n\tconst signature = batchSignatureFromOutcomes(ordered);\n\tstate.repeatCount = state.lastSignature === signature ? state.repeatCount + 1 : 1;\n\tstate.lastSignature = signature;\n\tstate.blockedTurnStreak++;\n\tconst level = Math.max(state.repeatCount, state.blockedTurnStreak);\n\tconst lastError = ordered.at(-1)!.text.slice(0, 300);\n\tif (level === 3) {\n\t\tstate.guardsInjected++;\n\t\treturn {\n\t\t\tkind: \"guard\",\n\t\t\tmessage: `[loop guard] Every tool call in this batch failed repeatedly. Change arguments, use another tool, or report the blocker. Last error: ${lastError}`,\n\t\t};\n\t}\n\tif (level >= 4) {\n\t\tstate.loopsAborted++;\n\t\treturn { kind: \"abort\", message: `DeepPi stopped a repeated failed tool batch. Last error: ${lastError}` };\n\t}\n\treturn { kind: \"none\" };\n}\n\nfunction batchSignatureFromOutcomes(outcomes: ToolOutcome[]): string {\n\treturn outcomes.map((outcome) =>\n\t\t`${outcome.name}\\0${errorSignature(outcome.name, outcome.text)}`,\n\t).join(\"\\0\\0\");\n}\n```\n\nDelete `FailureRecord`, threshold configuration, pending-abort state, and `tool_execution_end` tracking. Keep `enhanceError`, `errorSignature`, and `extractErrorText` in `utils.ts` with their existing focused tests moved into this suite.\n\n- [x] **Step 4: Add failing hook tests for expected-call discovery and last-result patching**\n\nExtend `tests/stormbreaker.test.ts` with a minimal hook capture—no shared fake is needed yet:\n\n```typescript\nimport type { ExtensionAPI } from \"@earendil-works/pi-coding-agent\";\nimport {\n\tregisterStormBreaker,\n\ttoolCallsFromMessage,\n} from \"../extensions/deeppi/stormbreaker.js\";\n\nconst assistant = {\n\trole: \"assistant\",\n\tcontent: [\n\t\t{ type: \"toolCall\", id: \"a\", name: \"read\", arguments: {} },\n\t\t{ type: \"toolCall\", id: \"b\", name: \"grep\", arguments: {} },\n\t],\n};\n\nit(\"discovers Pi toolCall blocks in message order\", () => {\n\texpect(toolCallsFromMessage(assistant)).toEqual(calls);\n});\n\nit(\"adds the batch guard only to the result that completes the third batch\", async () => {\n\ttype Hook = (event: any, ctx: any) => Promise | any;\n\tconst hooks = new Map();\n\tconst pi = {\n\t\ton(type: string, hook: Hook) { hooks.set(type, hook); },\n\t} as unknown as ExtensionAPI;\n\tconst state = createStormBreakerState();\n\tregisterStormBreaker(pi, state, () => true);\n\tconst ctx = {\n\t\tmodel: { provider: \"deepseek\", id: \"deepseek-v4-pro\" },\n\t\tabort() {},\n\t\tui: { notify() {} },\n\t};\n\tlet earlyResult: unknown;\n\tlet finalResult: unknown;\n\tfor (let attempt = 0; attempt < 3; attempt++) {\n\t\tawait hooks.get(\"message_end\")!({ message: assistant }, ctx);\n\t\tearlyResult = await hooks.get(\"tool_result\")!({\n\t\t\ttoolCallId: \"b\", toolName: \"grep\", isError: true,\n\t\t\tcontent: [{ type: \"text\", text: \"denied\" }],\n\t\t}, ctx);\n\t\tfinalResult = await hooks.get(\"tool_result\")!({\n\t\t\ttoolCallId: \"a\", toolName: \"read\", isError: true,\n\t\t\tcontent: [{ type: \"text\", text: \"missing\" }],\n\t\t}, ctx);\n\t}\n\texpect(JSON.stringify(earlyResult)).not.toContain(\"[loop guard]\");\n\texpect(JSON.stringify(finalResult)).toContain(\"[loop guard]\");\n});\n```\n\n- [x] **Step 5: Implement message discovery and hook registration**\n\nRegister `message_end` to call `startToolBatch` when an eligible assistant message contains tool calls. Register `tool_result` to enhance error text, feed `recordToolOutcome`, append a guard to the last result, or call `ctx.abort()` and notify on abort:\n\n```typescript\nexport function toolCallsFromMessage(message: unknown): ExpectedToolCall[] {\n\tconst value = message as { role?: unknown; content?: unknown } | undefined;\n\tif (value?.role !== \"assistant\" || !Array.isArray(value.content)) return [];\n\treturn value.content.flatMap((block) => {\n\t\tconst call = block as { type?: unknown; id?: unknown; name?: unknown };\n\t\treturn call.type === \"toolCall\" && typeof call.id === \"string\" && typeof call.name === \"string\"\n\t\t\t? [{ id: call.id, name: call.name }]\n\t\t\t: [];\n\t});\n}\n\npi.on(\"message_end\", async (event, ctx) => {\n\tif (!eligible(ctx.model)) return;\n\tconst calls = toolCallsFromMessage(event.message);\n\tif (calls.length > 0) startToolBatch(state, calls);\n});\n\npi.on(\"tool_result\", async (event, ctx) => {\n\tif (!eligible(ctx.model)) return;\n\tconst raw = extractErrorText(event.content);\n\tconst text = event.isError ? enhanceError(event.toolName, raw) : raw;\n\tif (text !== raw) state.errorsEnhanced++;\n\tconst decision = recordToolOutcome(state, {\n\t\tid: event.toolCallId,\n\t\tname: event.toolName,\n\t\tisError: event.isError,\n\t\ttext,\n\t});\n\tif (decision.kind === \"guard\") {\n\t\treturn { content: [{ type: \"text\" as const, text: `${text}\\n\\n${decision.message}` }] };\n\t}\n\tif (decision.kind === \"abort\") {\n\t\tctx.abort();\n\t\tctx.ui.notify(decision.message, \"warning\");\n\t}\n\tif (event.isError && text !== raw) {\n\t\treturn { content: [{ type: \"text\" as const, text }] };\n\t}\n});\n```\n\n- [x] **Step 6: Run focused and full verification**\n\nRun:\n\n```bash\nnpx vitest --run tests/stormbreaker.test.ts\nnpm test\nnpm run typecheck\n```\n\nExpected: all commands pass.\n\n- [x] **Step 7: Commit retry economy**\n\n```bash\ngit add extensions/deeppi/stormbreaker.ts extensions/deeppi/utils.ts tests/stormbreaker.test.ts\ngit commit -m \"feat: guard repeated failed tool batches\"\n```\n\n---\n\n### Task 5: Make hashline editing eligible-only and atomic\n\n**Files:**\n- Modify: `extensions/deeppi/hashlines.ts`\n- Modify: `extensions/deeppi/utils.ts`\n- Create: `tests/hashlines.test.ts`\n\n**Interfaces:**\n- Consumes: `isDeepPiModel` and the entry point's active-tool gate.\n- Produces: `HashEdit`, `HashlineStats`, `registerHashlines(pi, eligible)`, `validateEdits`, `applyEditsToLines`, and `atomicWriteFile`.\n- Task 6 reads hashline counters for `/deeppi`.\n\n- [x] **Step 1: Move existing pure hashline checks into a focused suite and add atomic-write tests**\n\nCreate `tests/hashlines.test.ts`. Move the existing assertions for `lineHash`, annotation, confused edit arguments, schema, validation, application order, and summaries from the temporary `tests/deeppi.test.ts`. Add a real temporary-file test using Node's test-safe temporary directory:\n\n```typescript\nimport { mkdtemp, readFile, rm, stat, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { afterEach, expect, it } from \"vitest\";\nimport { atomicWriteFile } from \"../extensions/deeppi/hashlines.js\";\n\nconst created: string[] = [];\nafterEach(async () => {\n\tfor (const path of created.splice(0)) await rm(path, { recursive: true });\n});\n\nit(\"atomically replaces content and preserves the file mode\", async () => {\n\tconst dir = await mkdtemp(join(tmpdir(), \"deeppi-hashlines-\"));\n\tcreated.push(dir);\n\tconst path = join(dir, \"sample.ts\");\n\tawait writeFile(path, \"old\\n\", { mode: 0o640 });\n\tawait atomicWriteFile(path, \"new\\n\");\n\texpect(await readFile(path, \"utf8\")).toBe(\"new\\n\");\n\texpect((await stat(path)).mode & 0o777).toBe(0o640);\n});\n```\n\n- [x] **Step 2: Run the focused test and verify `atomicWriteFile` is missing**\n\nRun:\n\n```bash\nnpx vitest --run tests/hashlines.test.ts\n```\n\nExpected: FAIL because `atomicWriteFile` is not exported.\n\n- [x] **Step 3: Implement same-directory atomic replacement with cleanup**\n\nAdd to `extensions/deeppi/hashlines.ts`:\n\n```typescript\nimport { chmod, open, rename, stat, unlink } from \"node:fs/promises\";\nimport { randomUUID } from \"node:crypto\";\nimport { basename, dirname, join } from \"node:path\";\n\nexport async function atomicWriteFile(path: string, content: string): Promise {\n\tconst mode = (await stat(path)).mode & 0o777;\n\tconst temporary = join(dirname(path), `.${basename(path)}.${process.pid}.${randomUUID()}.tmp`);\n\tlet created = false;\n\ttry {\n\t\tconst handle = await open(temporary, \"wx\", mode);\n\t\tcreated = true;\n\t\ttry {\n\t\t\tawait handle.writeFile(content, \"utf8\");\n\t\t\tawait handle.sync();\n\t\t} finally {\n\t\t\tawait handle.close();\n\t\t}\n\t\tawait chmod(temporary, mode);\n\t\tawait rename(temporary, path);\n\t\tcreated = false;\n\t} finally {\n\t\tif (created) await unlink(temporary).catch(() => undefined);\n\t}\n}\n```\n\nReplace the direct `writeFile` in the edit tool with `atomicWriteFile` after every edit validates.\n\n- [x] **Step 4: Add failing eligibility and all-or-nothing tool tests**\n\nExtend the focused suite with a local registered-tool capture:\n\n```typescript\nimport type { ExtensionAPI } from \"@earendil-works/pi-coding-agent\";\nimport {\n\tregisterHashlines,\n} from \"../extensions/deeppi/hashlines.js\";\nimport { lineHash } from \"../extensions/deeppi/utils.js\";\n\nfunction captureEditLines() {\n\tlet tool: any;\n\tconst pi = {\n\t\ton() {},\n\t\tregisterTool(value: any) { tool = value; },\n\t} as unknown as ExtensionAPI;\n\tconst stats = registerHashlines(\n\t\tpi,\n\t\t(model) => model?.provider === \"deepseek\" && model.id === \"deepseek-v4-pro\",\n\t);\n\treturn { stats, tool };\n}\n\nit(\"rejects unsupported models without touching the file\", async () => {\n\tconst dir = await mkdtemp(join(tmpdir(), \"deeppi-hashlines-\"));\n\tcreated.push(dir);\n\tconst path = join(dir, \"sample.ts\");\n\tconst original = \"alpha\\nbeta\\n\";\n\tawait writeFile(path, original);\n\tconst { stats, tool } = captureEditLines();\n\tconst result = await tool.execute(\"call-1\", {\n\t\tpath: \"sample.ts\",\n\t\tedits: [{ from: 1, from_hash: lineHash(\"alpha\"), to: 1, to_hash: lineHash(\"alpha\"), new_text: \"A\" }],\n\t}, new AbortController().signal, undefined, {\n\t\tcwd: dir,\n\t\tmodel: { provider: \"openrouter\", id: \"deepseek/deepseek-v4-pro\" },\n\t});\n\texpect(result.isError).toBe(true);\n\texpect(result.content[0].text).toContain(\"dormant\");\n\texpect(await readFile(path, \"utf8\")).toBe(original);\n\texpect(stats.editSuccesses).toBe(0);\n});\n\nit(\"validates the entire batch before atomically replacing the file\", async () => {\n\tconst dir = await mkdtemp(join(tmpdir(), \"deeppi-hashlines-\"));\n\tcreated.push(dir);\n\tconst path = join(dir, \"sample.ts\");\n\tconst original = \"alpha\\nbeta\\n\";\n\tawait writeFile(path, original);\n\tconst { stats, tool } = captureEditLines();\n\tconst result = await tool.execute(\"call-2\", {\n\t\tpath: \"sample.ts\",\n\t\tedits: [\n\t\t\t{ from: 1, from_hash: lineHash(\"alpha\"), to: 1, to_hash: lineHash(\"alpha\"), new_text: \"A\" },\n\t\t\t{ from: 2, from_hash: \"stale\", to: 2, to_hash: \"stale\", new_text: \"B\" },\n\t\t],\n\t}, new AbortController().signal, undefined, {\n\t\tcwd: dir,\n\t\tmodel: { provider: \"deepseek\", id: \"deepseek-v4-pro\" },\n\t});\n\texpect(result.isError).toBe(true);\n\texpect(await readFile(path, \"utf8\")).toBe(original);\n\texpect(stats.editSuccesses).toBe(0);\n\texpect(stats.hashMismatches).toBe(1);\n});\n```\n\n- [x] **Step 5: Remove generic config/pattern arguments from hashline registration**\n\nChange the registration signature to:\n\n```typescript\nexport interface HashEdit {\n\tfrom: number;\n\tfrom_hash: string;\n\tto: number;\n\tto_hash: string;\n\tnew_text: string;\n}\n\nexport function registerHashlines(\n\tpi: ExtensionAPI,\n\teligible: (model: { provider: string; id: string } | undefined) => boolean,\n): HashlineStats\n```\n\nGate both read annotation and tool execution with `eligible(ctx.model)`. Preserve `event.details` unchanged when returning annotated model content so Pi's built-in renderer retains its normal display data.\n\n- [x] **Step 6: Run focused and full verification**\n\nRun:\n\n```bash\nnpx vitest --run tests/hashlines.test.ts\nnpm test\nnpm run typecheck\n```\n\nExpected: all commands pass.\n\n- [x] **Step 7: Commit atomic hashline editing**\n\n```bash\ngit add extensions/deeppi/hashlines.ts extensions/deeppi/utils.ts tests/hashlines.test.ts\ngit commit -m \"feat: make hashline edits eligible and atomic\"\n```\n\n---\n\n### Task 6: Wire the plugin, current Pi hooks, command, and footer\n\n**Files:**\n- Rewrite: `extensions/deeppi.ts`\n- Create: `tests/fake-pi.ts`\n- Create: `tests/deeppi.integration.test.ts`\n- Modify: `extensions/deeppi/stability.ts`\n- Modify: `extensions/deeppi/telemetry.ts`\n- Modify: `extensions/deeppi/stormbreaker.ts`\n- Delete: `extensions/deeppi/config.ts`\n- Delete: `extensions/deeppi/planmode.ts`\n- Delete: `extensions/deeppi/rewind.ts`\n- Delete: `extensions/deeppi/types.ts` after moving `HashEdit` into `hashlines.ts`\n- Delete: `tests/deeppi.test.ts`\n- Delete: `tests/benchmarks.test.ts`\n\n**Interfaces:**\n- Consumes every module interface from Tasks 1-5.\n- Produces the default Pi extension factory, `/deeppi`, footer behavior, session reset, exact tool activation, and hook-level proof of dormant byte neutrality.\n\n- [x] **Step 1: Create the reusable fake Pi and context**\n\nCreate `tests/fake-pi.ts`:\n\n```typescript\nimport type { ExtensionAPI } from \"@earendil-works/pi-coding-agent\";\n\ntype Handler = (event: any, ctx: any) => Promise | any;\n\nexport class FakePi {\n\thandlers = new Map();\n\tcommands = new Map();\n\ttools = new Map();\n\tactiveTools = [\"read\", \"edit\", \"bash\"];\n\n\ton(type: string, handler: Handler): void {\n\t\tthis.handlers.set(type, [...(this.handlers.get(type) ?? []), handler]);\n\t}\n\tregisterCommand(name: string, command: { handler: Handler }): void {\n\t\tthis.commands.set(name, command);\n\t}\n\tregisterTool(tool: { name: string }): void {\n\t\tthis.tools.set(tool.name, tool);\n\t}\n\tgetActiveTools(): string[] {\n\t\treturn [...this.activeTools];\n\t}\n\tsetActiveTools(names: string[]): void {\n\t\tthis.activeTools = [...names];\n\t}\n\tasync emit(type: string, event: any, ctx: any): Promise {\n\t\tconst results: any[] = [];\n\t\tfor (const handler of this.handlers.get(type) ?? []) results.push(await handler(event, ctx));\n\t\treturn results;\n\t}\n\tasExtensionAPI(): ExtensionAPI {\n\t\treturn this as unknown as ExtensionAPI;\n\t}\n}\n\nexport function fakeContext(model: {\n\tprovider: string;\n\tid: string;\n\tcost?: { input: number; output: number; cacheRead: number; cacheWrite: number };\n} | undefined) {\n\tconst statuses = new Map();\n\tconst notifications: string[] = [];\n\treturn {\n\t\tmodel,\n\t\tcwd: process.cwd(),\n\t\thasUI: true,\n\t\taborted: false,\n\t\tabort() { this.aborted = true; },\n\t\tui: {\n\t\t\tsetStatus(key: string, value: string | undefined) { statuses.set(key, value); },\n\t\t\tnotify(message: string) { notifications.push(message); },\n\t\t},\n\t\tstatuses,\n\t\tnotifications,\n\t};\n}\n```\n\nUse `any` only inside this test double; production modules remain strict.\n\n- [x] **Step 2: Write failing end-to-end hook tests**\n\nCreate `tests/deeppi.integration.test.ts` that imports the default plugin and proves:\n\n```typescript\nimport { describe, expect, it } from \"vitest\";\nimport deepPi from \"../extensions/deeppi.js\";\nimport { FakePi, fakeContext } from \"./fake-pi.js\";\n\nit(\"is dormant and removes only edit_lines for unsupported models\", async () => {\n\tconst fake = new FakePi();\n\tfake.activeTools.push(\"edit_lines\");\n\tdeepPi(fake.asExtensionAPI());\n\tconst ctx = fakeContext({ provider: \"openrouter\", id: \"deepseek/deepseek-v4-pro\" });\n\tawait fake.emit(\"session_start\", {}, ctx);\n\texpect(fake.activeTools).toEqual([\"read\", \"edit\", \"bash\"]);\n\texpect(ctx.statuses.get(\"deeppi\")).toBeUndefined();\n});\n\nit(\"activates edit_lines and reports measured cache usage for Pro\", async () => {\n\tconst fake = new FakePi();\n\tdeepPi(fake.asExtensionAPI());\n\tconst ctx = fakeContext({\n\t\tprovider: \"deepseek\",\n\t\tid: \"deepseek-v4-pro\",\n\t\tcost: { input: 1.74, output: 3.48, cacheRead: 0.145, cacheWrite: 0 },\n\t});\n\tawait fake.emit(\"session_start\", {}, ctx);\n\texpect(fake.activeTools).toContain(\"edit_lines\");\n\texpect(ctx.statuses.get(\"deeppi\")).toBe(\"DeepPi · warming\");\n\tawait fake.emit(\"message_end\", {\n\t\tmessage: {\n\t\t\trole: \"assistant\",\n\t\t\tprovider: \"deepseek\",\n\t\t\tmodel: \"deepseek-v4-pro\",\n\t\t\tcontent: [{ type: \"text\", text: \"done\" }],\n\t\t\tusage: {\n\t\t\t\tinput: 20_000, output: 100, cacheRead: 80_000, cacheWrite: 0, totalTokens: 100_100,\n\t\t\t\tcost: { input: 0.0348, output: 0.000348, cacheRead: 0.0116, cacheWrite: 0, total: 0.046748 },\n\t\t\t},\n\t\t},\n\t}, ctx);\n\texpect(ctx.statuses.get(\"deeppi\")).toBe(\"DeepPi · 80% cache\");\n\tawait fake.commands.get(\"deeppi\")!.handler(\"\", ctx);\n\texpect(ctx.notifications.at(-1)).toContain(\"Cache hit rate: 80.0%\");\n});\n```\n\nAdd the byte-neutrality test to the same file:\n\n```typescript\nit(\"does not transform request bytes for unsupported models\", async () => {\n\tconst fake = new FakePi();\n\tdeepPi(fake.asExtensionAPI());\n\tconst ctx = fakeContext({ provider: \"deepseek\", id: \"deepseek-chat\" });\n\tconst messages = [{ role: \"assistant\", content: [\n\t\t{ type: \"thinking\", thinking: \"must remain\" },\n\t\t{ type: \"text\", text: \"answer\" },\n\t] }];\n\tconst payload = {\n\t\tmodel: \"deepseek-chat\",\n\t\tmessages: [{ role: \"user\", content: \"hello\" }],\n\t\ttools: [\n\t\t\t{ type: \"function\", function: { name: \"write\" } },\n\t\t\t{ type: \"function\", function: { name: \"read\" } },\n\t\t],\n\t};\n\tconst messagesBefore = structuredClone(messages);\n\tconst payloadBefore = structuredClone(payload);\n\tconst contextResults = await fake.emit(\"context\", { messages }, ctx);\n\tconst providerResults = await fake.emit(\"before_provider_request\", { payload }, ctx);\n\texpect(contextResults.every((value) => value === undefined)).toBe(true);\n\texpect(providerResults.every((value) => value === undefined)).toBe(true);\n\texpect(messages).toEqual(messagesBefore);\n\texpect(payload).toEqual(payloadBefore);\n});\n```\n\n- [x] **Step 3: Run the integration test and verify the old entry fails the contract**\n\nRun:\n\n```bash\nnpx vitest --run tests/deeppi.integration.test.ts\n```\n\nExpected: FAIL because the current entry still exposes old commands/config and does not wire telemetry or exact tool activation.\n\n- [x] **Step 4: Add hook registration functions to stability and telemetry**\n\nIn `stability.ts`, export `registerStabilityHooks(pi, state, eligible)`. Register:\n\n- `context`: compute `stabilizeMessages` first, then replace `event.messages` only after the pure transform succeeds;\n- `before_agent_start`: freeze recognized timestamps and return the stable `systemPrompt`;\n- `before_provider_request`: clone/sort `payload.tools`, capture the shape, classify it against `state.previousShape`, update state only after all steps succeed, and return the cloned payload directly (Pi chains the returned payload, not `{ payload }`).\n\nWrap each handler body in `try/catch`; increment `state.transformErrors` and return nothing on failure so Pi retains the original event.\n\nUse this order in the provider hook so no partial mutation leaks on failure:\n\n```typescript\npi.on(\"before_provider_request\", async (event, ctx) => {\n\tif (!eligible(ctx.model)) return;\n\ttry {\n\t\tconst payload = structuredClone(event.payload) as Record;\n\t\tsortProviderTools(payload);\n\t\tconst shape = capturePrefixShape(ctx.model.id, payload);\n\t\tconst churn = state.previousShape ? classifyPrefixChurn(state.previousShape, shape) : [];\n\t\tstate.previousShape = shape;\n\t\tstate.latestChurn = churn;\n\t\treturn payload;\n\t} catch {\n\t\tstate.transformErrors++;\n\t}\n});\n```\n\nIn `telemetry.ts`, export `resetTelemetry(state)` and `registerTelemetryHooks(pi, state, onUpdate)`. On eligible assistant `message_end`, require `event.message.provider === ctx.model.provider` and `event.message.model === ctx.model.id`, call `recordUsage`, then invoke `onUpdate(ctx)`.\n\n- [x] **Step 5: Rewrite the entry point with only approved wiring**\n\nReplace `extensions/deeppi.ts` with the final wiring shape:\n\n```typescript\nimport type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from \"@earendil-works/pi-coding-agent\";\nimport { isDeepPiModel, withEditLinesActive } from \"./deeppi/eligibility.js\";\nimport { createStabilityState, registerStabilityHooks } from \"./deeppi/stability.js\";\nimport { createTelemetryState, footerText, formatDeepPiReport, registerTelemetryHooks, resetTelemetry } from \"./deeppi/telemetry.js\";\nimport { createStormBreakerState, registerStormBreaker, resetStormBreaker } from \"./deeppi/stormbreaker.js\";\nimport { registerHashlines } from \"./deeppi/hashlines.js\";\n\nexport default function deepPi(pi: ExtensionAPI): void {\n\tconst stability = createStabilityState();\n\tconst telemetry = createTelemetryState();\n\tconst storm = createStormBreakerState();\n\tconst hashlines = registerHashlines(pi, isDeepPiModel);\n\n\tfunction syncModel(ctx: ExtensionContext): void {\n\t\tconst eligible = isDeepPiModel(ctx.model);\n\t\tconst current = pi.getActiveTools();\n\t\tconst active = withEditLinesActive(current, eligible);\n\t\tif (active.join(\"\\0\") !== current.join(\"\\0\")) pi.setActiveTools(active);\n\t\tif (ctx.hasUI) {\n\t\t\tctx.ui.setStatus(\"deeppi\", eligible ? footerText(telemetry, ctx.model.id) : undefined);\n\t\t}\n\t}\n\n\tregisterStabilityHooks(pi, stability, isDeepPiModel);\n\tregisterStormBreaker(pi, storm, isDeepPiModel);\n\tregisterTelemetryHooks(pi, telemetry, (ctx) => syncModel(ctx));\n\n\tpi.on(\"session_start\", async (_event, ctx) => {\n\t\tresetTelemetry(telemetry);\n\t\tresetStormBreaker(storm);\n\t\tstability.previousShape = null;\n\t\tstability.latestChurn = [];\n\t\tstability.frozenLines.clear();\n\t\tsyncModel(ctx);\n\t});\n\tpi.on(\"model_select\", async (_event, ctx) => syncModel(ctx));\n\n\tpi.registerCommand(\"deeppi\", {\n\t\tdescription: \"Show direct DeepSeek cache economics and retry statistics\",\n\t\thandler: async (_args: string, ctx: ExtensionCommandContext) => {\n\t\t\ttelemetry.latestChurn = stability.latestChurn;\n\t\t\tctx.ui.notify(formatDeepPiReport({\n\t\t\t\teligible: isDeepPiModel(ctx.model),\n\t\t\t\tmodelId: isDeepPiModel(ctx.model) ? ctx.model.id : null,\n\t\t\t\ttelemetry,\n\t\t\t\tloopsGuarded: storm.guardsInjected,\n\t\t\t\tloopsAborted: storm.loopsAborted,\n\t\t\t\teditAttempts: hashlines.editCalls,\n\t\t\t\teditMismatches: hashlines.hashMismatches,\n\t\t\t\teditSuccesses: hashlines.editSuccesses,\n\t\t\t}), \"info\");\n\t\t},\n\t});\n}\n```\n\nExport only pure functions/types required by the focused tests; remove every old config, plan, and rewind export.\n\n- [x] **Step 6: Delete non-goal modules and legacy duplicated suites**\n\nRun:\n\n```bash\ngit rm extensions/deeppi/config.ts extensions/deeppi/planmode.ts extensions/deeppi/rewind.ts extensions/deeppi/types.ts\ngit rm tests/deeppi.test.ts tests/benchmarks.test.ts\n```\n\nMove `HashEdit` into `hashlines.ts`. Ensure every still-useful pure utility assertion now lives in `stability.test.ts`, `stormbreaker.test.ts`, or `hashlines.test.ts` before deletion.\n\n- [x] **Step 7: Run integration and full verification**\n\nRun:\n\n```bash\nnpx vitest --run tests/deeppi.integration.test.ts\nnpm test\nnpm run typecheck\n```\n\nExpected: all commands pass; no test references `HarnessConfig`, plan mode, rewind, fuzzy matching, or `PI_HARNESS_*`.\n\n- [x] **Step 8: Commit the final plugin core**\n\n```bash\ngit add extensions tests/fake-pi.ts tests/deeppi.integration.test.ts\ngit commit -m \"feat: wire the DeepPi performance core\"\n```\n\n---\n\n### Task 7: Finish package identity, attribution, docs, and paid smoke benchmark\n\n**Files:**\n- Modify: `package.json`\n- Modify: `package-lock.json`\n- Rewrite: `README.md`\n- Modify: `LICENSE`\n- Create: `tests/package.test.ts`\n- Create: `scripts/live-benchmark.mjs`\n- Delete: `PLAN.md`\n- Delete: `assets/deepseek-optimized-screenshot.png`\n\n**Interfaces:**\n- Consumes the completed plugin and `/deeppi` output.\n- Produces the installable Git package, retained attribution, stale-brand regression test, and explicit live cache smoke test.\n\n- [x] **Step 1: Write failing package identity and attribution tests**\n\nCreate `tests/package.test.ts`:\n\n```typescript\nimport { readFile, readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { describe, expect, it } from \"vitest\";\n\nconst extensionsDir = fileURLToPath(new URL(\"../extensions\", import.meta.url));\n\ndescribe(\"DeepPi package identity\", () => {\n\tit(\"uses the final package and extension names\", async () => {\n\t\tconst pkg = JSON.parse(await readFile(new URL(\"../package.json\", import.meta.url), \"utf8\"));\n\t\texpect(pkg.name).toBe(\"deep-pi\");\n\t\texpect(pkg.version).toBe(\"1.0.0\");\n\t\texpect(pkg.pi.extensions).toEqual([\"./extensions/deeppi.ts\"]);\n\t\texpect(pkg.scripts[\"benchmark:live\"]).toBe(\"node scripts/live-benchmark.mjs\");\n\t});\n\n\tit(\"retains upstream and DeepPi copyright notices\", async () => {\n\t\tconst license = await readFile(new URL(\"../LICENSE\", import.meta.url), \"utf8\");\n\t\texpect(license).toContain(\"Copyright (c) 2026, Jason Rimmer\");\n\t\texpect(license).toContain(\"Copyright (c) 2026, Christopher Arter\");\n\t});\n\n\tit(\"contains no stale runtime branding\", async () => {\n\t\tconst files = await readdir(new URL(\"../extensions\", import.meta.url), { recursive: true });\n\t\tconst sources = await Promise.all(files.filter((file) => file.endsWith(\".ts\"))\n\t\t\t.map((file) => readFile(join(extensionsDir, file), \"utf8\")));\n\t\texpect(sources.join(\"\\n\")).not.toMatch(/PI_HARNESS|deepseek-optimized|harnessPlugin/);\n\t});\n});\n```\n\n- [x] **Step 2: Run the package test and verify current identity failures**\n\nRun:\n\n```bash\nnpx vitest --run tests/package.test.ts\n```\n\nExpected: FAIL on the old package name, version, missing DeepPi copyright, and missing benchmark script.\n\n- [x] **Step 3: Update package metadata and the existing lockfile in place**\n\nSet these exact `package.json` fields:\n\n```json\n{\n \"name\": \"deep-pi\",\n \"version\": \"1.0.0\",\n \"description\": \"Direct DeepSeek cache economics, prefix stability, and retry reduction for the Pi coding agent.\",\n \"license\": \"BSD-3-Clause\",\n \"author\": \"Christopher Arter\",\n \"contributors\": [\"Jason Rimmer\"],\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/christopherarter/deep-pi.git\"\n },\n \"homepage\": \"https://github.com/christopherarter/deep-pi#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/christopherarter/deep-pi/issues\"\n },\n \"keywords\": [\n \"pi-package\",\n \"pi\",\n \"deepseek\",\n \"prompt-cache\",\n \"cache-telemetry\",\n \"hashline-editing\"\n ]\n}\n```\n\nKeep the current engine, peers, dev dependencies, file allowlist, and verification scripts. Add:\n\n```json\n\"benchmark:live\": \"node scripts/live-benchmark.mjs\"\n```\n\nIn `package-lock.json`, change only the root `name`/`version` and `packages[\"\"]` `name`/`version` to `deep-pi` and `1.0.0`. Do not regenerate dependencies or discard the user's current lockfile changes.\n\n- [x] **Step 4: Update the BSD notices and replace the README with focused copy**\n\nKeep the full BSD text and use these first two notice lines in `LICENSE`:\n\n```text\nCopyright (c) 2026, Jason Rimmer\nCopyright (c) 2026, Christopher Arter\n```\n\nRewrite `README.md` around this exact structure and claims:\n\n````markdown\n# DeepPi\n\nReasonix-style DeepSeek price/performance for the Pi coding agent.\n\nDeepPi targets the direct DeepSeek API only. It stabilizes cacheable request\nprefixes, reports measured cache economics from Pi's real usage records, and\nreduces paid retries with loop guards and hash-verified edits.\n\n## Supported models\n\n- `deepseek-v4-flash`\n- `deepseek-v4-pro`\n\nDeepPi is dormant for every other provider and model.\n\n## Install\n\n```bash\npi install git:github.com/christopherarter/deep-pi\n```\n\nReload Pi, select a supported direct DeepSeek model, and run `/deeppi`.\n\n## What `/deeppi` measures\n\n- cache-read and uncached input tokens;\n- cache-hit rate;\n- actual input cost from Pi;\n- estimated savings against fully uncached input;\n- detected local prefix churn;\n- guarded retry loops and hashline edit outcomes.\n\nDeepPi does not promise a fixed hit rate. Provider cache expiry and backend\nstate can produce misses even when the local request prefix is stable.\n\n## Development\n\n```bash\nnpm install --ignore-scripts\nnpm run verify\n```\n\nDefault verification never calls an external API. The paid smoke benchmark is\nexplicitly opt-in:\n\n```bash\nDEEPPI_LIVE=1 npm run benchmark:live\n```\n\n## Attribution\n\nDeepPi is derived from\n[`jrimmer/pi-deepseek-optimized`](https://github.com/jrimmer/pi-deepseek-optimized)\nunder the BSD-3-Clause license. The original project implements techniques\ndescribed by Howard Chen and Can Akay; their credits and the original Jason\nRimmer copyright notice are retained.\n\nDeepPi's additions are its exact direct-V4 boundary, measured Pi cache/cost\ntelemetry, prefix-churn diagnostics, batch-aware retry guards, atomic hashline\nedits, removal of destructive rewind behavior, and tests against current Pi\nevent shapes.\n````\n\nDelete `PLAN.md` and the stale branded screenshot rather than shipping an inaccurate image:\n\n```bash\ngit rm PLAN.md assets/deepseek-optimized-screenshot.png\n```\n\n- [x] **Step 5: Create the guarded direct-API benchmark**\n\nCreate `scripts/live-benchmark.mjs` with no imports beyond Node's standard library. Use two repeated-prefix requests per model, disabled thinking, and a 32-token output ceiling:\n\n```javascript\nimport { createInterface } from \"node:readline/promises\";\nimport { stdin as input, stdout as output } from \"node:process\";\n\nconst models = [\"deepseek-v4-flash\", \"deepseek-v4-pro\"];\nconst prices = {\n \"deepseek-v4-flash\": { input: 0.14, output: 0.28 },\n \"deepseek-v4-pro\": { input: 1.74, output: 3.48 },\n};\nconst maxTokens = 32;\nconst prefix = \"DeepPi direct-cache verification prefix. \".repeat(256);\n\nif (process.env.DEEPPI_LIVE !== \"1\") throw new Error(\"Set DEEPPI_LIVE=1 to enable paid API calls.\");\nconst apiKey = process.env.DEEPSEEK_API_KEY;\nif (!apiKey) throw new Error(\"DEEPSEEK_API_KEY is required.\");\n\nconst estimatedInputTokens = Math.ceil(prefix.length / 3);\nconst maximumSpend = models.reduce((sum, model) =>\n sum + (2 * estimatedInputTokens * prices[model].input + 2 * maxTokens * prices[model].output) / 1_000_000,\n0);\nconsole.log(`Models: ${models.join(\", \")}`);\nconsole.log(\"Requests: 4\");\nconsole.log(`Output ceiling: ${maxTokens} tokens/request`);\nconsole.log(`Estimated maximum spend at current documented prices: $${maximumSpend.toFixed(4)}`);\n\nif (process.env.DEEPPI_LIVE_CONFIRM !== \"I_ACCEPT_COST\") {\n const terminal = createInterface({ input, output });\n const answer = await terminal.question(\"Type YES to send paid requests: \");\n terminal.close();\n if (answer !== \"YES\") throw new Error(\"Cancelled before sending requests.\");\n}\n\nasync function complete(model, messages) {\n const response = await fetch(\"https://api.deepseek.com/chat/completions\", {\n method: \"POST\",\n headers: { authorization: `Bearer ${apiKey}`, \"content-type\": \"application/json\" },\n body: JSON.stringify({ model, messages, max_tokens: maxTokens, thinking: { type: \"disabled\" } }),\n });\n const body = await response.json();\n if (!response.ok) throw new Error(`${model} returned ${response.status}: ${JSON.stringify(body)}`);\n return body;\n}\n\nlet failed = false;\nfor (const model of models) {\n const messages = [\n { role: \"system\", content: prefix },\n { role: \"user\", content: \"Reply with exactly OK.\" },\n ];\n const first = await complete(model, messages);\n const second = await complete(model, [\n ...messages,\n first.choices[0].message,\n { role: \"user\", content: \"Reply with exactly OK again.\" },\n ]);\n const hit = second.usage?.prompt_cache_hit_tokens ?? 0;\n const miss = second.usage?.prompt_cache_miss_tokens ?? 0;\n console.log(`${model}: hit=${hit} miss=${miss}`);\n if (hit === 0) failed = true;\n}\nif (failed) throw new Error(\"At least one model reported zero cache-hit tokens on its repeated-prefix request.\");\n```\n\nThe script may contain only this direct API host and must never print the API key or authorization header.\n\n- [x] **Step 6: Run package and default release verification**\n\nRun:\n\n```bash\nnpx vitest --run tests/package.test.ts\nnpm run verify\nnpm pack --dry-run\ngit diff --check\nrg -n 'PI_HARNESS|deepseek-optimized|harnessPlugin|PlanMode|RewindState' extensions tests package.json package-lock.json\n```\n\nExpected:\n\n- package test and `npm run verify` pass;\n- `git diff --check` prints nothing;\n- stale runtime-brand scan returns no matches;\n- `npm pack --dry-run` lists `extensions/deeppi.ts`, `extensions/deeppi/`, `README.md`, `LICENSE`, and `tsconfig.json`, with no `PLAN.md`, stale screenshot, test, or benchmark script.\n\nConfirm the one intentional upstream name remains in attribution:\n\n```bash\nrg -n 'jrimmer/pi-deepseek-optimized' README.md\n```\n\nExpected: exactly one attribution match.\n\n- [x] **Step 7: Commit package completion**\n\n```bash\ngit add package.json package-lock.json README.md LICENSE tests/package.test.ts scripts/live-benchmark.mjs\ngit add -u PLAN.md assets/deepseek-optimized-screenshot.png\ngit commit -m \"feat: publish the DeepPi package identity\"\n```\n\n- [x] **Step 8: Record final handoff evidence**\n\nRun:\n\n```bash\ngit status --short --branch\ngit log -8 --oneline\nnpm run verify\n```\n\nExpected: only the pre-existing `.pi-subagents/` remains untracked; the recent history contains the approved design plus the seven task commits; verification passes without network access.\n"}}, "docs/superpowers/plans/2026-08-06-deeppi-adversarial-regressions.md": {"c2e9a4a125f3b971a8ef8aa82aff833ca00d8343": {"t": 1786068557.0051672, "n": 11428, "h": "c685471f57e3b5df", "c": "# DeepPi Adversarial Regression Tests Implementation Plan\n\n> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.\n\n**Goal:** Add nine deterministic tests that expose the reviewed DeepPi correctness bugs and remain red until production code fixes them.\n\n**Architecture:** Extend the four existing module test files. Exercise exported functions directly where that is the real boundary, and capture Pi hooks where the bug depends on Pi's event contract. Make no production-code changes.\n\n**Tech Stack:** TypeScript, Vitest, Node.js `fs/promises`, Pi `ExtensionAPI` types.\n\n## Global Constraints\n\n- Add tests only; do not modify `extensions/`, dependencies, package metadata, or existing assertions.\n- Add exactly nine regression cases: two stability, one telemetry, two stormbreaker, and four hashlines.\n- A correct handoff is intentionally red: `npm run typecheck` passes, 34 existing tests pass, and the nine new assertions fail for their stated reason.\n- Use only local deterministic inputs and temporary files. No network, timers, sleeps, or race-dependent scheduling.\n- Preserve `.pi-subagents/` untouched and untracked.\n- Prefix shell commands with `rtk` per the repository instructions.\n\n---\n\n### Task 1: Add the nine red regression tests\n\n**Files:**\n\n- Modify: `tests/stability.test.ts`\n- Modify: `tests/telemetry.test.ts`\n- Modify: `tests/stormbreaker.test.ts`\n- Modify: `tests/hashlines.test.ts`\n\n- [ ] **Step 1: Add the two stability regressions**\n\nAdd the Pi API type and hook exports to `tests/stability.test.ts`:\n\n```ts\nimport type { ExtensionAPI } from \"@earendil-works/pi-coding-agent\";\nimport {\n\tcreateStabilityState,\n\tfreezeSessionTimestamps,\n\tregisterStabilityHooks,\n\tstabilizeMessages,\n\ttype TimestampState,\n} from \"../extensions/deeppi/stability.js\";\n```\n\nAppend these tests:\n\n```ts\nit(\"returns pruned messages through Pi's context result contract\", async () => {\n\ttype Hook = (event: any, ctx: any) => Promise | any;\n\tconst hooks = new Map();\n\tconst pi = {\n\t\ton(type: string, hook: Hook) { hooks.set(type, hook); },\n\t} as unknown as ExtensionAPI;\n\tconst state = createStabilityState();\n\tregisterStabilityHooks(pi, state, () => true);\n\tconst messages = [{\n\t\trole: \"assistant\",\n\t\tcontent: [\n\t\t\t{ type: \"thinking\", thinking: \"private\" },\n\t\t\t{ type: \"text\", text: \"answer\" },\n\t\t],\n\t}];\n\tconst result = await hooks.get(\"context\")!({ messages }, {\n\t\tmodel: { provider: \"deepseek\", id: \"deepseek-v4-pro\" },\n\t});\n\tconst nextMessages = result?.messages ?? messages;\n\texpect(nextMessages[0].content).toEqual([{ type: \"text\", text: \"answer\" }]);\n});\n\nit(\"does not freeze generic user-authored Date lines\", () => {\n\tconst state: TimestampState = { frozenLines: new Map() };\n\tfreezeSessionTimestamps(\"Date: release-candidate-1\", state);\n\texpect(freezeSessionTimestamps(\"Date: release-candidate-2\", state))\n\t\t.toBe(\"Date: release-candidate-2\");\n});\n```\n\nThe first test must reproduce Pi's actual chaining rule: only a returned `{ messages }` value changes the next context. Do not inspect the mutated event object.\n\nRun:\n\n```bash\nrtk npx vitest --run tests/stability.test.ts\n```\n\nExpected: the two new tests fail. The existing stability tests pass. The first failure retains the thinking block; the second returns `Date: release-candidate-1`.\n\n- [ ] **Step 2: Add the provider-scoping telemetry regression**\n\nAdd the Pi API type and `registerTelemetryHooks` import to `tests/telemetry.test.ts`:\n\n```ts\nimport type { ExtensionAPI } from \"@earendil-works/pi-coding-agent\";\nimport {\n\tcacheHitRate,\n\tcreateTelemetryState,\n\tfooterText,\n\trecordUsage,\n\tregisterTelemetryHooks,\n} from \"../extensions/deeppi/telemetry.js\";\n```\n\nAppend this test:\n\n```ts\nit(\"ignores supported-looking model IDs from unsupported providers\", async () => {\n\ttype Hook = (event: any, ctx: any) => Promise | any;\n\tconst hooks = new Map();\n\tconst pi = {\n\t\ton(type: string, hook: Hook) { hooks.set(type, hook); },\n\t} as unknown as ExtensionAPI;\n\tconst state = createTelemetryState();\n\tregisterTelemetryHooks(pi, state, () => {});\n\tawait hooks.get(\"message_end\")!({\n\t\tmessage: {\n\t\t\trole: \"assistant\",\n\t\t\tprovider: \"openrouter\",\n\t\t\tmodel: \"deepseek-v4-pro\",\n\t\t\tusage: {\n\t\t\t\tinput: 10,\n\t\t\t\toutput: 1,\n\t\t\t\tcacheRead: 20,\n\t\t\t\tcacheWrite: 0,\n\t\t\t\ttotalTokens: 31,\n\t\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t\t},\n\t\t},\n\t}, {\n\t\tmodel: { provider: \"openrouter\", id: \"deepseek-v4-pro\" },\n\t});\n\texpect(state.byModel[\"deepseek-v4-pro\"].responses).toBe(0);\n});\n```\n\nRun:\n\n```bash\nrtk npx vitest --run tests/telemetry.test.ts\n```\n\nExpected: the new test fails with one response recorded. Existing telemetry tests pass.\n\n- [ ] **Step 3: Add the two stormbreaker regressions**\n\nAppend this small capture helper and the tests to `tests/stormbreaker.test.ts`:\n\n```ts\nfunction captureStormBreakerHooks() {\n\ttype Hook = (event: any, ctx: any) => Promise | any;\n\tconst hooks = new Map();\n\tconst pi = {\n\t\ton(type: string, hook: Hook) { hooks.set(type, hook); },\n\t} as unknown as ExtensionAPI;\n\tregisterStormBreaker(pi, createStormBreakerState(), () => true);\n\treturn hooks;\n}\n\nit(\"ends a blocked streak when an assistant turn makes no tool calls\", async () => {\n\tconst hooks = captureStormBreakerHooks();\n\tlet aborted = false;\n\tconst ctx = {\n\t\tmodel: { provider: \"deepseek\", id: \"deepseek-v4-pro\" },\n\t\tabort() { aborted = true; },\n\t\tui: { notify() {} },\n\t};\n\tconst failedTool = async () => {\n\t\tawait hooks.get(\"message_end\")!({\n\t\t\tmessage: {\n\t\t\t\trole: \"assistant\",\n\t\t\t\tcontent: [{ type: \"toolCall\", id: \"a\", name: \"read\", arguments: {} }],\n\t\t\t},\n\t\t}, ctx);\n\t\treturn hooks.get(\"tool_result\")!({\n\t\t\ttoolCallId: \"a\",\n\t\t\ttoolName: \"read\",\n\t\t\tisError: true,\n\t\t\tcontent: [{ type: \"text\", text: \"missing\" }],\n\t\t}, ctx);\n\t};\n\tawait failedTool();\n\tawait failedTool();\n\tawait hooks.get(\"message_end\")!({\n\t\tmessage: { role: \"assistant\", content: [{ type: \"text\", text: \"new task\" }] },\n\t}, ctx);\n\tconst unrelatedResult = await failedTool();\n\texpect(JSON.stringify(unrelatedResult)).not.toContain(\"[loop guard]\");\n\texpect(aborted).toBe(false);\n});\n\nit(\"preserves actionable error text beyond 500 characters\", async () => {\n\tconst hooks = captureStormBreakerHooks();\n\tconst ctx = {\n\t\tmodel: { provider: \"deepseek\", id: \"deepseek-v4-pro\" },\n\t\tabort() {},\n\t\tui: { notify() {} },\n\t};\n\tawait hooks.get(\"message_end\")!({\n\t\tmessage: {\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [{ type: \"toolCall\", id: \"a\", name: \"read\", arguments: {} }],\n\t\t},\n\t}, ctx);\n\tconst originalContent = [{\n\t\ttype: \"text\",\n\t\ttext: `${\"x\".repeat(600)}ACTIONABLE_TAIL`,\n\t}];\n\tconst result = await hooks.get(\"tool_result\")!({\n\t\ttoolCallId: \"a\",\n\t\ttoolName: \"read\",\n\t\tisError: true,\n\t\tcontent: originalContent,\n\t}, ctx);\n\tconst visibleContent = result?.content ?? originalContent;\n\texpect(JSON.stringify(visibleContent)).toContain(\"ACTIONABLE_TAIL\");\n});\n```\n\nRun:\n\n```bash\nrtk npx vitest --run tests/stormbreaker.test.ts\n```\n\nExpected: both new tests fail. The unrelated third failure receives `[loop guard]`, and the returned error content omits `ACTIONABLE_TAIL`. Existing stormbreaker tests pass.\n\n- [ ] **Step 4: Add the four hashline regressions**\n\nExtend the imports in `tests/hashlines.test.ts`:\n\n```ts\nimport { lstat, mkdtemp, readFile, rm, stat, symlink, writeFile } from \"node:fs/promises\";\nimport {\n\tatomicWriteFile,\n\tregisterHashlines,\n\tvalidateEdits,\n} from \"../extensions/deeppi/hashlines.js\";\n```\n\nAppend these tests:\n\n```ts\nit(\"rejects overlapping edit ranges\", () => {\n\tconst lines = [\"A\", \"B\", \"C\"];\n\tconst error = validateEdits(lines, [\n\t\t{ from: 1, from_hash: lineHash(\"A\"), to: 2, to_hash: lineHash(\"B\"), new_text: \"X\" },\n\t\t{ from: 2, from_hash: lineHash(\"B\"), to: 3, to_hash: lineHash(\"C\"), new_text: \"Y\" },\n\t]);\n\texpect(error).toMatch(/overlap/i);\n});\n\nit(\"does not replace a symlink while leaving its target stale\", async () => {\n\tconst dir = await mkdtemp(join(tmpdir(), \"deeppi-hashlines-\"));\n\tcreated.push(dir);\n\tconst target = join(dir, \"target.ts\");\n\tconst link = join(dir, \"link.ts\");\n\tawait writeFile(target, \"old\\n\");\n\tawait symlink(target, link);\n\tlet rejected = false;\n\ttry {\n\t\tawait atomicWriteFile(link, \"new\\n\");\n\t} catch {\n\t\trejected = true;\n\t}\n\texpect((await lstat(link)).isSymbolicLink()).toBe(true);\n\texpect(await readFile(target, \"utf8\")).toBe(rejected ? \"old\\n\" : \"new\\n\");\n});\n\nit(\"rejects an atomic replacement when the source changed since validation\", async () => {\n\tconst dir = await mkdtemp(join(tmpdir(), \"deeppi-hashlines-\"));\n\tcreated.push(dir);\n\tconst path = join(dir, \"sample.ts\");\n\tawait writeFile(path, \"snapshot\\n\");\n\tconst snapshot = await readFile(path, \"utf8\");\n\tawait writeFile(path, \"newer external content\\n\");\n\ttype GuardedAtomicWrite = (path: string, content: string, expectedContent: string) => Promise;\n\tlet rejected = false;\n\ttry {\n\t\tawait (atomicWriteFile as GuardedAtomicWrite)(path, \"agent edit\\n\", snapshot);\n\t} catch {\n\t\trejected = true;\n\t}\n\texpect(rejected).toBe(true);\n\texpect(await readFile(path, \"utf8\")).toBe(\"newer external content\\n\");\n});\n\nit(\"does not give known distinct line content the same hash\", () => {\n\texpect(lineHash(\"critical setting = false\"))\n\t\t.not.toBe(lineHash(\"critical setting = true # 7571\"));\n});\n```\n\nThe symlink assertion permits either safe behavior: follow and update the target while preserving the link, or reject without changing either object. It forbids replacing the link itself. The guarded-write cast intentionally describes the smallest required API extension; the current two-argument function ignores the third argument and fails the test without a type error.\n\nRun:\n\n```bash\nrtk npx vitest --run tests/hashlines.test.ts\n```\n\nExpected: all four new tests fail. Existing hashline tests pass.\n\n- [ ] **Step 5: Verify the intentional red handoff**\n\nRun type checking:\n\n```bash\nrtk npm run typecheck\n```\n\nExpected: exit 0.\n\nRun the focused suites:\n\n```bash\nrtk npx vitest --run tests/stability.test.ts tests/telemetry.test.ts tests/stormbreaker.test.ts tests/hashlines.test.ts\n```\n\nExpected: exactly nine failed tests, all matching the assertions above. No uncaught exceptions, type failures, missing hooks, or cleanup failures.\n\nRun the full suite:\n\n```bash\nrtk npm test\n```\n\nExpected: exit nonzero with exactly 34 passed and nine failed tests. Record this as the desired handoff state; do not weaken assertions or change production code to make it green.\n\n- [ ] **Step 6: Commit the red regression suite**\n\nInspect scope:\n\n```bash\nrtk git status --short\nrtk git diff --check\nrtk git diff -- tests/stability.test.ts tests/telemetry.test.ts tests/stormbreaker.test.ts tests/hashlines.test.ts docs/superpowers/plans/2026-08-06-deeppi-adversarial-regressions.md\n```\n\nStage only the plan and four test files, leaving `.pi-subagents/` untouched:\n\n```bash\nrtk git add docs/superpowers/plans/2026-08-06-deeppi-adversarial-regressions.md tests/stability.test.ts tests/telemetry.test.ts tests/stormbreaker.test.ts tests/hashlines.test.ts\nrtk git commit -m \"test: expose DeepPi correctness regressions\"\n```\n\nHandoff with the commit hash, the nine failing test names, and the two loop commands:\n\n```bash\nrtk npm run typecheck\nrtk npm test\n```\n\nThe fixing agent's completion condition is both commands exiting 0 without modifying or deleting these regression assertions.\n"}}}}