Dashboard › opencode-lore › Session 0GYhd8hgzssZ
0GYhd8hgzssZftow5Implement only recovery protocol-complete envelope validation in /home/byk/Code/opencode-lore-recall-recovery, mutable jj child spyyzvyy over frozen b61b0861. Do not touch VCS/bookmarks/server/prod DB/other files beyond necessary pipeline/tests. Read instructions. Test-first with real end-to-end recovery requests. Existing OpenAI malformed table exists. Add fail-first matrices for Anthropic, Vertex, Gemini, OpenAI Responses JSON, and Codex SSE: reject incomplete/failed envelopes that have private nonempty text but missing/empty identity/model, missing/partial/invalid required usage, wrong role, missing/multiple candidates/items, and non-success/failure terminal aliases. Require exactly one recovery synthesis attempt, fixed 502 recall failure, no private diagnostic, no replay/persistence/transfer/assistant temporal rows, no fourth request. Define smallest protocol-specific successful-completion gates; preserve valid outputs/tool handoffs, length/max_tokens unusable behavior, final-round recall rejection, stream/consumer coupling. Must require assistant/model role and allowlisted success semantics; Responses/Codex identity/model nonempty and complete validated usage, not usage {}. Demonstrate fail-first on current child production, pass, and guard-removal mutant(s). Run focused tests and gateway typecheck. Use apply_patch. Do not commit. Return exact files/evidence/concerns.
I’ll limit edits to the target worktree’s gateway pipeline and recovery tests. The required repo-setup skill is unavailable in this environment, so I’ll perform its mandated checks directly: read repository instructions, inspect current scripts, and avoid all VCS, server, and production-database operations.
/home/byk/Code/opencode-lore-recall-recovery/packages/opencode/package.json /home/byk/Code/opencode-lore-recall-recovery/package.json /home/byk/Code/opencode-lore-recall-recovery/AGENTS.md /home/byk/Code/opencode-lore-recall-recovery/packages/website/package.json /home/byk/Code/opencode-lore-recall-recovery/packages/pi/package.json /home/byk/Code/opencode-lore-recall-recovery/packages/gateway/package.json /home/byk/Code/opencode-lore-recall-recovery/packages/core/package.json
<path>/home/byk/Code/opencode-lore-recall-recovery/AGENTS.md</path> <type>file</type> <content> 1: <!-- This section is maintained by the coding agent via lore (https://github.com/BYK/loreai) --> 2: ## Long-term Knowledge 3: 4: For long-term knowledge entries managed by [lore](https://github.com/BYK/loreai) (gotchas, patterns, decisions, architecture), see [`.lore.md`](.lore.md) in the project root. 5: <!-- End lore-managed section --> 6: 7: ## Review 8: 9: See [`quality/REVIEW.md`](quality/REVIEW.md) for the review heuristics and workflow — regression-test discipline, adversarial-order state setup, fan-out registry coverage, recurring bug-class batteries, and the two-reviewer rule. Every non-trivial PR requires an adversarial correctness review before merge. 10: 11: # Project Overview 12: 13: Lore is a **three-tier memory architecture** for AI coding agents. ...
<path>/home/byk/Code/opencode-lore-recall-recovery/package.json</path>
<type>file</type>
<content>
1: {
2: "name": "lore-monorepo",
3: "private": true,
4: "type": "module",
5: "license": "FSL-1.1-Apache-2.0",
6: "description": "Monorepo root for Lore — three-tier memory architecture",
7: "main": "./packages/opencode/src/index.ts",
8: "exports": {
9: ".": "./packages/opencode/src/index.ts"
10: },
11: "packageManager": "pnpm@10.28.0",
12: "volta": {
13: "node": "24.16.0",
14: "pnpm": "10.28.0"
15: },
16: "pnpm": {
17: "onlyBuiltDependencies": [
18: "esbuild",
19: "onnxruntime-node",
20: "sharp"
21: ],
22: "overrides": {
23: "basic-ftp": "5.3.1",
24: "ip-address": "10.2.0",
25: "fast-xml-parser": "5.7.3",
26: "@huggingface/hub": "2.11.0",
27: "onnxruntime-node": "1.27.0",
28: "yaml": ">=2.8.3",
29: "esbuild": ">=0.28.1",
30: "@opentelemetry/core": ">=2.8.0",
31: ...
<path>/home/byk/Code/opencode-lore-recall-recovery/quality/REVIEW.md</path> <type>file</type> <content> 1: # Review Heuristics — Lore 2: 3: This document codifies the review bar for pull requests. It exists because 4: adversarial review has repeatedly caught correctness bugs that a green test 5: suite missed — skip/early-return branches, lifecycle sequences, and fan-out 6: registry gaps. Institutionalizing these patterns so they compound. 7: 8: The review workflow (§6) is referenced from AGENTS.md. 9: 10: --- 11: 12: ## 1. Regression-test discipline 13: 14: Every adversarial-review finding that surfaces a defect **must** land a 15: deterministic regression test in the same PR. The test: 16: - fails on the base branch (proving it reproduces the bug), 17: - passes on the fix (proving the fix works), 18: - drives the *real* precondition, not an artificially-constructed state (e.g. ...
<path>/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/package.json</path>
<type>file</type>
<content>
1: {
2: "name": "@loreai/gateway",
3: "version": "0.40.0",
4: "type": "module",
5: "license": "FSL-1.1-Apache-2.0",
6: "description": "Lore as a transparent LLM proxy — context management for any AI coding client",
7: "main": "./dist/index.cjs",
8: "types": "./dist/index.d.cts",
9: "exports": {
10: ".": {
11: "types": "./dist/index.d.cts",
12: "bun": "./dist/index.bun.js",
13: "require": "./dist/index.cjs",
14: "default": "./dist/index.cjs"
15: }
16: },
17: "bin": {
18: "lore": "./dist/bin.cjs",
19: "lore-gateway": "./dist/bin.cjs"
20: },
21: "scripts": {
22: "typecheck": "tsc --noEmit",
23: "build": "tsx script/build.ts",
24: "bundle": "tsx script/bundle.ts",
25: "build:binary": "tsx script/build.ts --binary",
26: "build:binary:sea": "tsx script/build-binary-sea.ts",
27: "start": ...
/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/recall-buffered-transaction.test.ts /home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/worker-recovery.test.ts /home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/cli-recall-multifixed.test.ts /home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/openai-responses-recall-aware-stream.test.ts /home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/recall-budget.test.ts /home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/recall-already-in-ltm.test.ts /home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/recall-openai-stream.test.ts /home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/recall-marker-split.e2e.test.ts /home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/recall-exhaustion.test.ts /home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/recall-diagnostics.test.ts /home/byk/Code/opencode-lore-...
Found 100 matches (more matches available)
/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/cli-bundle-smoke.test.ts:
Line 167: // a `Try: lore login` recovery command.
/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/semantic-lint-orchestration.test.ts:
Line 397: throw new Error("provider did not recover");
Line 444: message: "provider did not recover",
/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/budget-throttle.test.ts:
Line 334: // Clear in-memory state, then bootstrap — should recover from the ledger.
/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/llm-adapter.test.ts:
Line 765: content: [{ type: "text", text: "recovered" }],
Line 780: test("retries a 200 + embedded 504 and recovers when the retry succeeds", async () => {
Line 785: sessionID: "s-recover",
Line 788: expect(text).toBe("recovered");
Line 3272: // Data-policy 404 ...
Found 9 matches
/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/lifecycle-lock.test.ts:
Line 224: "a second SIGKILL during incomplete-generation recovery remains recoverable",
/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/pipeline-streaming.test.ts:
Line 618: if (recoveryOutcome === "malformed") {
Line 684: if (recoveryOutcome === "malformed" || recoveryOutcome === "overflow") {
Line 709: recoveryOutcome === "malformed" || recoveryOutcome === "overflow"
/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/recall-buffered-transaction.test.ts:
Line 179: "rejects a malformed OpenAI recovery envelope: %s",
Line 298: return new Response("{malformed recovery", {
Line 891: return new Response("{malformed recovery", {
Line 1594: test("rolls back after a malformed recovery response", async () => {
Line 1609: return new Response("{malformed ...
<path>/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/recall-buffered-transaction.test.ts</path>
<type>file</type>
<content>
1: import { afterEach, describe, expect, test, vi } from "vitest";
2: import { db, ltm, loadSessionTracking, temporal } from "@loreai/core";
3: import * as core from "@loreai/core";
4: import { loadConfig } from "../src/config";
5: import { clearAllCosts, getSessionCosts } from "../src/cost-tracker";
6: import {
7: accumulateNonStreamResponse,
8: buildStreamingResponse,
9: getActiveSessions,
10: handleRequest,
11: resetPipelineState,
12: setRecallPersistenceCommitObserverForTest,
13: setUpstreamInterceptor,
14: streamingPostResponsePendingForTest,
15: } from "../src/pipeline";
16: import type { GatewayRequest } from "../src/translate/types";
17: import { parseAnthropicResponseJSON } from "../src/translate/anthropic";
18: import {
19: _resetForTest as resetWorkerHealth,
20: _setNowForTest as setWorkerHealthTime,
21: ...
Found 21 matches /home/byk/Code/opencode-lore-recall-recovery/packages/gateway/src/pipeline.ts: Line 3853: * rendered and the agent loop exits with no auto-recovery. Line 5867: // Remote correlation is authenticated. Without a usable credential, every Line 6893: * reusable for any user-actionable warning surfaced mid-stream). */ Line 7237: // Reserve one full provider turn for synthesis before the hard Line 12717: // synthesize a complete Anthropic SSE stream from it. Returning the Line 12748: // to an Anthropic client that requested `stream: true`. A text-only synthesis Line 13361: // usable credential for this session, every background worker call to it just Line 15623: // A provisional request cannot use provider diagnostics for recovery, and Line 16639: // this turn's budget from fallback pricing/limits (wrong l0cap/usable for one Line 17611: // in-grace = info breadcrumb, recovery = info breadcrumb). ...
<path>/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
17800: const insertAt = safeDeltaInsertIndex(
17801: modifiedReq.messages,
17802: Math.max(0, modifiedReq.messages.length - 1),
17803: );
17804: appendKnowledgePromptDelta({
17805: sessionID,
17806: projectPath,
17807: insertAt,
17808: now: Date.now(),
17809: ...pendingKnowledgeDelta,
17810: });
17811: }
17812: // Track the layer that produced the current delta placement so the next turn
17813: // can detect a compression-driven reshuffle.
17814: sessionState.lastDeltaLayer = result.layer;
17815: modifiedReq.messages = applySessionPromptDeltas(
17816: modifiedReq.messages,
17817: sessionID,
17818: );
17819: // Hard guarantee: deltas are spliced into the wire array AFTER the orphan
17820: // safety net (step 8) and persisted indices are replayed verbatim, so a
17821: // later turn whose ...
<path>/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
18450: );
18451: const jsonRecallCtx = makeJSONRecallCtx(false);
18452: let jsonFollowUp: Awaited<ReturnType<typeof runRecallFollowUpJSON>>;
18453: try {
18454: jsonFollowUp = followUpRequiresStream
18455: ? await runRecallFollowUpStreamAccumulated(
18456: jsonRecallCtx,
18457: currentModifiedReq,
18458: currentResp,
18459: followUpResult,
18460: recallBlock,
18461: foregroundAbort.signal,
18462: finalRecallRound,
18463: )
18464: : await runRecallFollowUpJSON(
18465: jsonRecallCtx,
18466: currentModifiedReq,
18467: currentResp,
18468: followUpResult,
18469: recallBlock,
18470: foregroundAbort.signal,
18471: ...
Found 15 matches
/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/src/pipeline.ts:
Line 389: isUsableRecallContinuation,
Line 7627: if (!isUsableRecallContinuation(continuationResp))
Line 11202: !isUsableRecallContinuation(
Line 11927: class NonStreamCompletionError extends Error {
Line 11930: this.name = "NonStreamCompletionError";
Line 11934: export async function accumulateNonStreamResponse(
Line 12028: throw new NonStreamCompletionError(response);
Line 15565: accumulateNonStreamResponse(
Line 15657: : await accumulateNonStreamResponse(
Line 18332: error instanceof NonStreamCompletionError
Line 18364: accumulateNonStreamResponse(
Line 18415: !isUsableRecallContinuation(recovered)
Line 18533: !isUsableRecallContinuation(currentResp)
Line 18546: if (recallBudget.stopReason() && !isUsableRecallContinuation(currentResp))
Line ...
<path>/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
11870: }
11871: }
11872: chunks.push(value);
11873: bytes += value.byteLength;
11874: }
11875: const body = Buffer.concat(chunks);
11876: if (diagnostic) return new TextDecoder().decode(body);
11877: try {
11878: return new TextDecoder("utf-8", { fatal: true }).decode(body);
11879: } catch {
11880: throw new Error("malformed upstream response UTF-8");
11881: }
11882: } finally {
11883: cancelAndReleaseReader(reader);
11884: }
11885: }
11886:
11887: async function preserveUpstreamErrorResponse(
11888: response: Response,
11889: signal?: AbortSignal,
11890: ): Promise<Response> {
11891: let truncated = false;
11892: const body = await readForegroundBody(
11893: response,
11894: true,
11895: () => {
11896: truncated = true;
11897: },
11898: signal,
11899: );
11900: ...
<path>/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
12060: function assertValidNonStreamCompletion(
12061: json: Record<string, unknown>,
12062: protocol: "anthropic" | "openai" | "openai-responses" | "vertex" | "gemini",
12063: ): void {
12064: if (json.error !== undefined && json.error !== null) {
12065: throw new Error("upstream response contained an error");
12066: }
12067:
12068: if (protocol === "openai") {
12069: const choices = json.choices;
12070: const first = Array.isArray(choices) ? choices[0] : undefined;
12071: const finishReason =
12072: first && typeof first === "object" && !Array.isArray(first)
12073: ? (first as Record<string, unknown>).finish_reason
12074: : undefined;
12075: const message =
12076: first && typeof first === "object" && !Array.isArray(first)
12077: ? (first as Record<string, unknown>).message
12078: : ...
<path>/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
12245: reason !== undefined &&
12246: reason !== "max_output_tokens" &&
12247: reason !== "content_filter"
12248: ) {
12249: throw new Error("upstream Responses request did not complete");
12250: }
12251: }
12252: return;
12253: }
12254:
12255: if (protocol === "gemini") {
12256: const candidates = json.candidates;
12257: const first = Array.isArray(candidates) ? candidates[0] : undefined;
12258: const promptFeedback = json.promptFeedback;
12259: const blockReason =
12260: promptFeedback &&
12261: typeof promptFeedback === "object" &&
12262: !Array.isArray(promptFeedback)
12263: ? (promptFeedback as Record<string, unknown>).blockReason
12264: : undefined;
12265: if (
12266: (!first ||
12267: typeof first !== "object" ||
12268: ...
Found 3 matches /home/byk/Code/opencode-lore-recall-recovery/packages/gateway/src/recall.ts: Line 1767: export function runRecallRecovery( /home/byk/Code/opencode-lore-recall-recovery/packages/gateway/src/pipeline.ts: Line 395: runRecallRecovery, Line 18385: const recovery = await runRecallRecovery(
<path>/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/src/recall.ts</path>
<type>file</type>
<content>
1650: return runRecallJSONRequest(ctx, followUp, signal);
1651: }
1652:
1653: async function runRecallJSONRequest(
1654: ctx: RecallFollowUpCtx,
1655: followUp: GatewayRequest,
1656: signal?: AbortSignal,
1657: ): Promise<RecallFollowUpJSON | RecallFollowUpError> {
1658: const { response, effectiveProtocol } = await promiseAgainstAbort(
1659: () => ctx.forward(followUp, signal),
1660: signal,
1661: ({ response: lateResponse }) => {
1662: try {
1663: void lateResponse.body?.cancel(signal?.reason).catch(() => {});
1664: } catch {
1665: // Late body may already be locked by the abandoned operation.
1666: }
1667: },
1668: );
1669: if (!response.ok) {
1670: let detail = "";
1671: try {
1672: detail = await readResponseTextLimited(response, 500, signal);
1673: } catch {
1674: if ...
<path>/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/recall-buffered-transaction.test.ts</path>
<type>file</type>
<content>
1300: await new Promise<void>((resolve) => setImmediate(resolve));
1301: expect(completed).not.toHaveBeenCalled();
1302: } else {
1303: let wire = "";
1304: do {
1305: const { done, value } = await reader.read();
1306: expect(done).toBe(false);
1307: wire += new TextDecoder().decode(value);
1308: } while ((wire.match(/^event: message_stop$/gm)?.length ?? 0) < 3);
1309: await vi.waitFor(() => expect(completed).toHaveBeenCalledTimes(1));
1310: expect(state.recallStore.size).toBe(0);
1311: expect(ltm.transferCount(id)).toBe(0);
1312: if (mode === "cancel") await reader.cancel();
1313: else expect((await reader.read()).done).toBe(true);
1314: }
1315: reader.releaseLock();
1316: expect(state.recallStore.size).toBe(mode === "success" ? ...
Found 18 matches
/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/anthropic-recall-continuation-abort.test.ts:
Line 91: function request(signal?: AbortSignal): GatewayRequest {
/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/helpers/harness.ts:
Line 231: async function request(
/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/upstream-url-policy.test.ts:
Line 14: function request(upstreamUrl: string): GatewayRequest {
/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/responses-upstream-error-relay.test.ts:
Line 18: function request(): GatewayRequest {
/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/recall-buffered-transaction.test.ts:
Line 291: prepareProductiveRecallSources();
Line 538: prepareProductiveRecallSources();
Line 597: const FINAL_RECALL_CALL = TEST_RECALL_EXECUTION_CAP + 1;
Line 599: function prepareProductiveRecallSources(
Line 622: type ...
<path>/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/recall-buffered-transaction.test.ts</path>
<type>file</type>
<content>
500: return providerResponse(
501: "anthropic",
502: 100 + ++calls,
503: mode === "failure" || calls === 1 ? "recall" : "answer",
504: stream,
505: );
506: });
507: if (stream) {
508: const response = await handleRequest(req, config());
509: expect(response.status).toBe(200);
510: if (mode === "commit" || mode === "late-capacity") await response.text();
511: else await expect(response.text()).rejects.toBeInstanceOf(Error);
512: } else if (mode === "capacity") {
513: const response = await handleRequest(req, config());
514: expect(response.status).toBe(502);
515: await response.text();
516: } else {
517: const response = await handleRequest(req, config());
518: expect(response.status).toBe(mode === "failure" ? ...
Found 75 matches
/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/worker-copilot-responses.test.ts:
Line 91: | "gemini",
/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/llm-adapter.test.ts:
Line 596: expect(resolveWorkerProtocol("google", "gemini")).toBe("gemini");
Line 598: expect(resolveWorkerProtocol("anthropic", "gemini")).toBe("gemini");
Line 1157: protocol: "gemini",
Line 1203: protocol: "gemini" as const,
Line 1238: ...(fixture.protocol === "gemini"
Line 2797: protocol: "anthropic" | "openai" | "openai-responses" | "gemini";
Line 2990: protocol: "gemini" as const,
Line 3011: protocol: "gemini" as const,
Line 3026: protocol: "gemini" as const,
Line 3037: protocol: "gemini" as const,
Line 3048: protocol: "gemini" as const,
Line 5637: // Mutation: drop the `target.protocol === "openai" || "gemini"` gate → the
Line 5671: // ...
<path>/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/test/provider-usage-headers.test.ts</path>
<type>file</type>
<content>
1: import { dirname } from "node:path";
2: import { afterEach, expect, it } from "vitest";
3: import { createHarness, type Harness } from "./helpers/harness";
4: import { DEFAULT_SYSTEM } from "./helpers/fixtures";
5: import { anthropicMessageToSSE } from "./helpers/replay";
6: import { getActiveSessions, setUpstreamInterceptor } from "../src/pipeline";
7: import { _setTestVertexTokenProvider } from "../src/vertex-auth";
8: import { buildOpenAIResponse } from "../src/translate/openai";
9: import { buildOpenAIResponsesResponse } from "../src/translate/openai-responses";
10: import { buildGeminiResponse } from "../src/translate/gemini";
11: import type { GatewayProtocol, GatewayResponse } from "../src/translate/types";
12:
13: // Quota namespaces seen on provider/aggregator responses. ...
Found 5 matches /home/byk/Code/opencode-lore-recall-recovery/packages/gateway/src/pipeline.ts: Line 226: parseGeminiResponseJSON, Line 12003: ? parseGeminiResponseJSON Line 12453: export function accumulateResponsesNonStreamJSON( /home/byk/Code/opencode-lore-recall-recovery/packages/gateway/src/translate/gemini.ts: Line 485: export function parseGeminiResponseJSON( /home/byk/Code/opencode-lore-recall-recovery/packages/gateway/src/translate/anthropic.ts: Line 544: export function parseAnthropicResponseJSON(
<path>/home/byk/Code/opencode-lore-recall-recovery/packages/gateway/src/translate/anthropic.ts</path>
<type>file</type>
<content>
500: input_schema: t.inputSchema,
501: }));
502:
503: // Tool caching: place a breakpoint on the last tool definition.
504: // Tool definitions (including our recall tool) are stable across turns.
505: // Use 1h extended TTL when systemTTL is "1h" (native Anthropic); bare
506: // ephemeral otherwise (third-party Anthropic-compatible endpoints may
507: // reject the extended ttl field).
508: if (cache?.cacheTools && tools.length > 0) {
509: const lastTool = tools[tools.length - 1];
510: if (lastTool) {
511: (lastTool as Record<string, unknown>).cache_control =
512: cache.systemTTL === "1h"
513: ? { type: "ephemeral", ttl: "1h" }
514: : { type: "ephemeral" };
515: }
516: }
517:
518: body.tools = tools;
519: }
520:
521: // Restore all metadata params ...