Dashboard › opencode-lore › Session 07vY1cn8TTH4
07vY1cn8TTH4VeGncIndependent READ-ONLY security/privacy review of immutable provider candidate in /home/byk/Code/opencode-lore-provider-error. Base literal 2cbf40060c67df229731cf1b9e34d5bf22ec2145; head stable change lpmvqrurxwlm, commit 0dd569b520bad37adbaea230f32100c7f83f463c; expected plain range-diff SHA-256 3458ce2dc248950b13dc69dda91a07f95a2dcd49f128f2f4ec8e218a6d68b46e. Do not edit/format/install/VCS/server/network/production DB or rerun exhaustive suite. Read AGENTS.md, quality/REVIEW.md, scripts. Verify exact identity/status/conflicts/six changed files/hash start/end. Inspect all changed lines and relevant callbacks/logging/persistence. Attack malformed non-JSON error/response.error, raw/extension-bearing response.in_progress, failure aliases/status/error/usage/source sequences, terminal metadata poisoning, callback/rollback/telemetry errors, Codex quota events before failure, recall-bearing failed output, cancellation/backpressure, persistence/accounting. Verify final head fixes prior findings: trusted created-state in-progress projection in plain and recall-aware routes; shared failure prevalidation before mutation; exactly one fixed openai-responses provider failure log only after acceptance; no provider/callback free-form content in logs/Sentry; valid failed usage accounted route-independently; fixed public envelope and empty failed callback output; no failed continuation becomes completed. Evaluate supplied fail-first/mutation evidence and exhaustive 10,364-test pass. Run only focused checks if essential. Report PASS/CONCERN/MUST-FIX with exact current file:line and exploit. Never empty. End exactly MERGE or DO-NOT-MERGE.
<skill_content name="jj-guide"> # Skill: jj-guide # jj Guide for AI Agents Jujutsu (jj) is a Git-compatible VCS with mutable commits, automatic snapshotting, no staging area, and first-class conflicts. This skill teaches you how to use it safely from a non-interactive agent environment. If `.jj/` exists in the repo root, this is a jj repo. **Use `jj` commands, not `git`.** In a colocated repo (`.jj/` *and* `.git/`), git tools can read the state, but mutations should go through `jj` so the operation log stays consistent. ## Critical Rules - **NEVER** use interactive flags (`-i`, `--interactive`). TUI prompts hang in agent environments. This applies to `jj split -i`, `jj squash -i`, `jj commit -i`, `jj resolve`, `jj diffedit`, etc. - **ALWAYS** pass `-m "msg"` when describing/committing. Without `-m`, an editor opens and hangs. - **VERIFY** mutations with `jj st` and `jj log` after `squash`, `abandon`, `rebase`, `restore`, `commit`. ...
/home/byk/Code/opencode-lore-provider-error The working copy has no changes. Working copy (@) : qzwttkwl d3b014cf (empty) fix(responses): isolate failure telemetry Parent commit (@-): lpmvqrur 0dd569b5 fix/responses-provider-failures | fix(responses): unify provider failure handling Warning: These bookmarks have conflicts: fix/responses-private-references Hint: Use `jj bookmark list` to see details. Use `jj bookmark set <name> -r <rev>` to resolve. qzwttkwltwzroqvkvvuroqutmtumrwop d3b014cfcbb932e4d7a0c4cce52c2a5303432850 parent=0dd569b520bad37adbaea230f32100c7f83f463c empty=true conflict=false description=fix(responses): isolate failure telemetry lpmvqrurxwlmrmwnyllmxlvkmplvwnlz 0dd569b520bad37adbaea230f32100c7f83f463c parent=24880457763b6f10831856d01c41bd72d62ddc28 empty=false conflict=false description=fix(responses): unify provider failure handling pxrvwsvvkmpoxnsqmrkwrnlqvvkoltwz 2cbf40060c67df229731cf1b9e34d5bf22ec2145 parent=e977b4b1da8f8197c3238466d41de0bccd8eb054 ...
<path>/home/byk/Code/opencode-lore-provider-error/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-provider-error/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-provider-error/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-provider-error/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": "tsx ...
No files found
packages/gateway/src/pipeline.ts | 369 +++++- packages/gateway/src/stream/openai-responses.ts | 1090 ++++++++++++------- ...st/openai-responses-recall-aware-stream.test.ts | 1245 ++++++++++++++++++++- ...es/gateway/test/openai-responses-stream.test.ts | 1044 +++++++++++++++++- packages/gateway/test/pipeline-streaming.test.ts | 147 +- packages/gateway/test/recall-codex-stream.test.ts | 3 +- 6 files changed, 3398 insertions(+), 500 deletions(-) lpmvqrurxwlm 0dd569b520ba fix(responses): unify provider failure handling wswlsmrnuzlq 24880457763b fix(responses): reject non-monotonic provider failures plzxzousrzuv a1020a45be13 fix(responses): preserve trusted failure metadata skwrwnvkvulp 01a6e06b08ba fix(responses): make provider failure settlement atomic xqmskzvmnqkr b1bc7cd46c4e fix(responses): complete provider failure sanitization qnlnmzlxyynv 29dee093d7ce fix(responses): bind sanitized failures to trusted state prpmozzzqvkt d385b39653b0 fix(responses): ...
...output truncated...
Full output saved to: /home/byk/.local/share/opencode/tool-output/tool_0abcb20e7001GQ5RyS6H1vW7LG
1065: ...(state.codexRateLimits
1066: ? { codexRateLimits: structuredClone(state.codexRateLimits) }
1067: : {}),
1068: };
1069: }
1070:
903 1071: // ---------------------------------------------------------------------------
904 1072: // Stream accumulator (buffered)
905 1073: // ---------------------------------------------------------------------------
...
942 1110: if (!response || typeof response !== "object" || Array.isArray(response)) {
943 1111: throw new Error("malformed Responses terminal event");
944 1112: }
1113: if (event === "response.created" && state.created) {
1114: malformed();
1115: } else if (event === "response.in_progress" && !state.created) {
1116: malformed();
1117: }
945 1118: if (state.id && response.id !== ...
<path>/home/byk/.local/share/opencode/tool-output/tool_0abcb20e7001GQ5RyS6H1vW7LG</path>
<type>file</type>
<content>
1: Modified regular file packages/gateway/src/stream/openai-responses.ts:
2: ...
3: 48 48: export interface ResponsesAccState {
4: 49 49: id: string;
5: 50 50: model: string;
6: 51: created: boolean;
7: 52: createdAt?: number;
8: 53: lastAcceptedSequenceNumber?: number;
9: 51 54: stopReason: string;
10: 52 55: usage: GatewayUsage;
11: 53 56: terminalEvent?:
12: ...
13: 557 560: return {
14: 558 561: id: "",
15: 559 562: model: "",
16: 563: created: false,
17: 560 564: stopReason: "end_turn",
18: 561 565: usage: { inputTokens: 0, outputTokens: 0 },
19: 562 566: items: new Map(),
20: ... ...
<path>/home/byk/.local/share/opencode/tool-output/tool_0abcb20e7001GQ5RyS6H1vW7LG</path>
<type>file</type>
<content>
1081: 2526: !responsesDoneItemMatchesAdded(completedSnapshot, accumulated)
1082: 2527: ) {
1083: 2528: throw new Error("malformed Responses terminal event");
1084: 2529: }
1085: 2530: assertResponsesDoneMatchesAccumulatedState(
1086: 2531: state,
1087: 2532: outputIndex,
1088: 2533: completedSnapshot,
1089: 2534: terminalContentParts,
1090: 2535: );
1091: 2536: applyResponsesEvent(state, "response.output_item.done", {
1092: 2537: output_index: outputIndex,
1093: 2538: item: completedSnapshot,
1094: 2539: });
1095: 2540: ...
Modified regular file packages/gateway/src/pipeline.ts:
...
203 203: streamResponsesPassthrough,
204 204: translateAnthropicStreamToResponses,
205 205: applyResponsesEvent,
206: cloneResponsesAccState,
206 207: finalizeResponsesAcc,
208: finalizeUnsuccessfulResponsesAcc,
207 209: formatResponsesEvent,
208 210: makeResponsesAccState,
209 211: mapStatusFromStopReason,
...
212 214: isValidResponsesReasoningEncryptedContent,
213 215: responsesDoneItemMatchesAdded,
214 216: responsesTerminalItemMatches,
217: restoreResponsesAccState,
215 218: normalizeCodexResponsesEvent,
219: projectResponsesInProgressEvent,
220: RESPONSES_PROVIDER_FAILURE_LOG,
221: sanitizeResponsesProviderFailureTerminal,
222: validateResponsesProviderFailureTerminal,
223: validateResponsesSourceSequence,
216 224: ResponsesTerminalError,
217 225: type ResponsesAccState,
218 226: } from ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts</path>
<type>file</type>
<content>
560: return {
561: id: "",
562: model: "",
563: created: false,
564: stopReason: "end_turn",
565: usage: { inputTokens: 0, outputTokens: 0 },
566: items: new Map(),
567: rawItems: new Map(),
568: itemIndexById: new Map(),
569: callIndexById: new Map(),
570: effectiveToolIndexById: new Map(),
571: nextOutputIndex: 0,
572: activeTextItems: new Set(),
573: activeToolItems: new Set(),
574: unboundTextItems: new Set(),
575: unboundToolItems: new Set(),
576: textDoneItems: new Set(),
577: refusalDoneItems: new Set(),
578: argumentDoneItems: new Set(),
579: };
580: }
581:
582: export function cloneResponsesAccState(
583: state: ResponsesAccState,
584: ): ResponsesAccState {
585: return structuredClone(state);
586: }
587:
588: export function restoreResponsesAccState(
589: state: ...
Found 12 matches
/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts:
Line 18679: if (currentResp.codexRateLimits?.length) {
Line 18680: continuationResp.codexRateLimits = [
Line 18681: ...currentResp.codexRateLimits,
Line 18682: ...(continuationResp.codexRateLimits ?? []),
/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/translate/types.ts:
Line 349: codexRateLimits?: Array<Record<string, unknown>>;
/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/translate/openai-responses.ts:
Line 1281: for (const quota of resp.codexRateLimits ?? []) {
/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts:
Line 63: codexRateLimits?: Array<Record<string, unknown>>;
Line 729: (state.codexRateLimits ??= []).push(quota);
Line 1048: ...(state.codexRateLimits
Line 1049: ? { codexRateLimits: state.codexRateLimits }
...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts</path>
<type>file</type>
<content>
1075: function validatePublicResponsesEvent(
1076: state: ResponsesAccState,
1077: event: string,
1078: parsed: Record<string, unknown>,
1079: maxSparseIndex: number,
1080: ): void {
1081: const outputIndex = parsed.output_index;
1082: const validOutputIndex =
1083: Number.isSafeInteger(outputIndex) &&
1084: (outputIndex as number) >= 0 &&
1085: (outputIndex as number) < maxSparseIndex;
1086: const item = validOutputIndex
1087: ? state.items.get(outputIndex as number)
1088: : undefined;
1089: const malformed = (): never => {
1090: throw new Error("malformed Responses stream event");
1091: };
1092:
1093: if (parsed.type !== undefined && parsed.type !== event) malformed();
1094: if (
1095: parsed.sequence_number !== undefined &&
1096: (!Number.isSafeInteger(parsed.sequence_number) ||
1097: ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts</path>
<type>file</type>
<content>
1740: ) {
1741: if (itemId === undefined) {
1742: outputIndex = soleCodexItem(codexItemSet(state, kind));
1743: } else {
1744: const unbound = soleCodexItem(codexItemSet(state, kind, true));
1745: if (unbound !== undefined) {
1746: outputIndex = unbound;
1747: bindCodexItemId(state, outputIndex, itemId);
1748: } else if (codexItemSet(state, kind).size > 0) {
1749: malformedResponsesEvent();
1750: }
1751: }
1752: }
1753: outputIndex ??= nextResponsesOutputIndex(state, maxSparseIndex);
1754:
1755: const existing = state.rawItems.get(outputIndex);
1756: if (event === "response.output_item.added" && existing) {
1757: malformedResponsesEvent();
1758: }
1759: if (event === "response.output_item.done" && existing) {
1760: if (
1761: existing.type !== item.type ...
Found 100 matches (more matches available)
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/pipeline-streaming.test.ts:
Line 180: response: { id, model: "gpt-5.6-sol", status: "in_progress" },
Line 189: status: "in_progress",
Line 232: response: { id, model: "gpt-5.6-sol", status: "in_progress" },
Line 236: item: { ...item, arguments: "", status: "in_progress" },
Line 262: response: { id, model: "gpt-5.6-sol", status: "in_progress" },
Line 409: throw new DOMException("upstream cancelled", "AbortError");
Line 686: wire: 'event: response.created\ndata: {"type":"response.created","response":{"id":"resp_stalled","model":"gpt-test","status":"in_progress"}}\n\n',
Line 699: cancelled: () => boolean;
Line 701: let cancelled = false;
Line 711: cancelled = true;
Line 717: return { response, cancelled: () => cancelled };
Line 768: let cancelled = 0;
Line 778: ...
Found 100 matches (more matches available)
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/claude-usage-provisional.test.ts:
Line 21: it(`preserves quota during real Claude session header migration (stream=${stream}, status=${status})`, async () => {
Line 33: ? new Response("private upstream quota detail", {
Line 83: expect(body).not.toContain("private upstream quota detail");
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/llm-adapter.test.ts:
Line 165: test("keeps diagnostic error bodies capped at 64 KiB", async () => {
Line 195: test("replacement-decodes malformed diagnostic UTF-8", async () => {
Line 251: test("empty worker diagnostics never include response values", () => {
Line 253: const diagnostic = describeEmptyWorkerResponse({
Line 258: expect(diagnostic).not.toContain(sentinel);
Line 259: expect(diagnostic).toContain("finish_reason=unknown");
Line 1105: async (_terminal, ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/openai-responses-stream.test.ts</path>
<type>file</type>
<content>
560: expect(result.id).toBe("resp_codex");
561: expect(result.model).toBe("gpt-5.5");
562: expect(result.stopReason).toBe("end_turn");
563: expect(result.usage?.inputTokens).toBe(30);
564: expect(result.usage?.outputTokens).toBe(2);
565: });
566:
567: test("maps Codex `response.incomplete` to max_tokens stop reason", async () => {
568: const response = buildSSEResponse([
569: {
570: event: "response.incomplete",
571: data: {
572: type: "response.incomplete",
573: response: {
574: id: "resp_inc",
575: model: "gpt-5.5",
576: status: "incomplete",
577: usage: { input_tokens: 40, output_tokens: 100 },
578: },
579: },
580: },
581: ]);
582:
583: const result = await ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/openai-responses-stream.test.ts</path>
<type>file</type>
<content>
4230: const events = [
4231: {
4232: event: "response.output_item.added",
4233: data: { item: { type: "message", id: "codex-sparse" } },
4234: },
4235: {
4236: event: "response.output_text.delta",
4237: data: { item_id: "codex-sparse", delta: "ok" },
4238: },
4239: {
4240: event: "response.completed",
4241: data: { response: { status: "completed" } },
4242: },
4243: ];
4244: const codex = await streamResponsesPassthrough(
4245: buildSSEResponse(events),
4246: () => {},
4247: undefined,
4248: "codex",
4249: ).text();
4250: expect(codex).toContain('"delta":"ok"');
4251: expect(codex).not.toContain("response.failed");
4252:
4253: const publicOutput = await streamResponsesPassthrough(
4254: ...
Found 7 matches
/home/byk/Code/opencode-lore-provider-error/packages/core/src/log.ts:
Line 51: error(message: string, attrs?: Record<string, unknown>): void;
Line 467: console.error("[lore]", ...safeArgs(args));
Line 476: console.error("[lore] WARN:", ...safeArgs(args));
Line 491: if (!readStderrSilenced()) console.error("[lore]", ...safeArgs(args));
Line 497: export function error(...args: unknown[]): void {
Line 499: if (!readStderrSilenced()) console.error("[lore]", ...safeArgs(args));
Line 500: sink?.error(msg);
<path>/home/byk/Code/opencode-lore-provider-error/packages/core/src/log.ts</path>
<type>file</type>
<content>
400: if (!logPathResolved) {
401: logPath = resolveLogPath();
402: logPathResolved = true;
403: }
404: return logPath;
405: }
406:
407: /** Rotate the log file if it exceeds the size cap. */
408: function maybeRotate(): void {
409: if (!logPath) return;
410: let fd: number | undefined;
411: try {
412: // Tighten the active file before it becomes the rotated backup.
413: fd = openLogFileForAppend(logPath);
414: const stat = fstatSync(fd);
415: if (stat.size > LOG_MAX_BYTES) {
416: closeSync(fd);
417: fd = undefined;
418: const backup = `${logPath}.1`;
419: removeExistingRotationBackup(backup);
420: renameSync(logPath, backup);
421: // Another process may have raced the rename. Validate what now occupies
422: // the backup name before leaving it as persistent sensitive data. ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/core/src/log.ts</path>
<type>file</type>
<content>
80: export function traceDbQuery<T>(sql: string, fn: () => T): T {
81: return sink?.withDbSpan ? sink.withDbSpan(sql, fn) : fn();
82: }
83:
84: // ---------------------------------------------------------------------------
85: // Helpers
86: // ---------------------------------------------------------------------------
87:
88: // Match the gateway config's `isTruthy` semantics: only "1" or "true" enable
89: // debug. The naive `!!process.env.LORE_DEBUG` treated `LORE_DEBUG=0` and
90: // `LORE_DEBUG=false` as ENABLED (non-empty strings are truthy), which meant a
91: // user who set `LORE_DEBUG=0` to silence Lore still got `[lore]` status lines
92: // printed to stderr — fatal inside a full-screen TUI (e.g. the Pi agent).
93: const isDebug =
94: process.env.LORE_DEBUG === "1" ||
95: process.env.LORE_DEBUG?.toLowerCase() === "true";
96:
97: // ...
Found 45 matches
/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts:
Line 2223: log.error(RESPONSES_PROVIDER_FAILURE_LOG);
Line 2835: log.error("openai-responses passthrough onComplete error:", err);
Line 2909: log.error(
Line 3540: log.error("openai-responses stream translation error:", err);
/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts:
Line 940: log.error(
Line 1052: * callback before closing so registration is atomic with terminal delivery,
Line 1122: log.error("streaming post-response drop cleanup failed:", error);
Line 1172: log.error("streaming post-response processing failed:", error);
Line 2601: Sentry.captureException(
Line 4005: log.error("knowledge import error:", e);
Line 4109: log.error(
Line 4203: log.error(`workspace knowledge import error (${subDir}):`, e);
Line 4249: ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
9580: syntheticIdentities.add(syntheticId);
9581: };
9582:
9583: // --- Keepalive (same as streamResponsesPassthrough) ---
9584: const KEEPALIVE_INACTIVITY_MS = 30_000;
9585: const keepaliveComment = encoder.encode(`: keepalive\n\n`);
9586: let keepaliveTimer: ReturnType<typeof setTimeout> | null = null;
9587: let completed = false;
9588: let completionAttempted = false;
9589: let nextSequenceNumber = 0;
9590:
9591: const sequenceChunk = (chunk: Uint8Array): Uint8Array => {
9592: const text = new TextDecoder().decode(chunk);
9593: if (!text.startsWith("event: ")) return chunk;
9594: let output = "";
9595: for (const frame of text.split("\n\n")) {
9596: if (!frame) continue;
9597: const lines = frame.split("\n");
9598: const eventLine = lines.find((line) => line.startsWith("event: "));
9599: const dataLines ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts</path> <type>file</type> <content> 10020: if (keepaliveTimer) clearTimeout(keepaliveTimer); 10021: keepaliveTimer = null; 10022: }; 10023: let principalReader: ReadableStreamDefaultReader<Uint8Array> | null = 10024: null; 10025: let principalTransportRetries = 0; 10026: let principalRetrySucceededReported = false; 10027: let principalReadFinished = false; 10028: let continuationAttempted = false; 10029: let continuationFailureCategory: 10030: | RecallContinuationFailureCategory 10031: | undefined; 10032: let continuationFailureReported = false; 10033: let recallDetected = false; 10034: let providerFailureSeen = false; 10035: let continuationProviderFailureSeen = false; 10036: let rollbackPendingPrincipalTerminal: (() => void) | undefined; 10037: type ...
Found 100 matches (more matches available)
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/auth.test.ts:
Line 97: // (reading 'x-api-key')" (Sentry LOREAI-GATEWAY-28). Guard returns null.
Line 98: test("returns null for null/undefined headers instead of throwing", () => {
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/doctor.test.ts:
Line 506: it("runs without throwing on a clean HOME (no gateway)", async () => {
Line 570: it("returns null when the request throws", async () => {
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/delta-upgrade-telemetry.test.ts:
Line 15: import * as Sentry from "@sentry/bun";
Line 23: vi.mocked(Sentry.startSpan).mockImplementation(async (_opts, cb) =>
Line 28: } as unknown as Sentry.Span),
Line 37: .mocked(Sentry.metrics.distribution)
Line 49: vi.mocked(Sentry.isInitialized).mockReturnValue(true);
Line 95: ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/openai-responses-recall-aware-stream.test.ts</path>
<type>file</type>
<content>
9080: anchorText: buildAnchor("private query"),
9081: resultText: "private recall result",
9082: commit: () => commits++,
9083: rollback: () => rollbacks++,
9084: }),
9085: runFollowUp: async () => ({
9086: reader: failedFollowUp.body!.getReader(),
9087: }),
9088: },
9089: );
9090: if (!client.body) throw new Error("test response has no body");
9091:
9092: await failureReported;
9093: await client.body.cancel();
9094: await new Promise((resolve) => setImmediate(resolve));
9095:
9096: expect(failures).toEqual(["follow_up_failed"]);
9097: expect([commits, rollbacks, rollbacksAtComplete]).toEqual([0, 1, [1]]);
9098: expect(completions).toEqual([
9099: {
9100: successful: false,
9101: response: ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/openai-responses-recall-aware-stream.test.ts</path>
<type>file</type>
<content>
250: new ReadableStream<Uint8Array>({
251: start(controller) {
252: controller.enqueue(
253: new TextEncoder().encode(
254: created("resp_cancel_terminal", "gpt-5.6-terra") +
255: completed("resp_cancel_terminal", {
256: input_tokens: 1,
257: output_tokens: 0,
258: }),
259: ),
260: );
261: },
262: pull() {
263: return new Promise(() => {});
264: },
265: cancel() {
266: upstreamCancelled = true;
267: },
268: }),
269: { headers: { "content-type": "text/event-stream" } },
270: );
271: let completeCalls = 0;
272: const client = streamResponsesRecallAware(upstream, {
273: onComplete: () => completeCalls++,
274: ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
10870: if (held.transactional) {
10871: transactionalEvents.push(held.chunk);
10872: } else {
10873: queueTransactional(held.chunk);
10874: }
10875: }
10876: heldContinuationEvents.length = 0;
10877: deferredContinuationBytes = 0;
10878: };
10879: let continuationRecallBytes = 0;
10880: const promoteContinuationCandidate = (
10881: outputIndex: number,
10882: ): void => {
10883: const bytes =
10884: contUnresolvedToolBytes.get(outputIndex) ?? 0;
10885: ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
11260: ...cparsed,
11261: output_index: shiftedOutputIndex(
11262: ci,
11263: contIndex,
11264: ),
11265: }),
11266: ),
11267: );
11268: if (
11269: contRecallIndices.size > 0 ||
11270: contUnresolvedToolIndices.size > 0
11271: ) {
11272: holdContinuation(shifted);
11273: } else queueTransactional(shifted);
11274: } else if (ce !== "message") {
11275: const chunk = ...
Found 71 matches
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/llm-adapter.test.ts:
Line 6624: const capturedLogs: string[] = [];
Line 6634: capturedLogs.length = 0;
Line 6638: info: (message) => capturedLogs.push(message),
Line 6639: warn: (message) => capturedLogs.push(message),
Line 6640: error: (message) => capturedLogs.push(message),
Line 6642: capturedLogs.push(
Line 6698: const logDump = capturedLogs.join("\n");
Line 6746: const output = capturedLogs.join("\n");
Line 6780: const output = capturedLogs.join("\n");
Line 6801: expect(capturedLogs.join("\n")).not.toContain(thrownMarker);
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/openai-responses-stream.test.ts:
Line 624: const capturedLogs: string[] = [];
Line 626: info: (message) => capturedLogs.push(message),
Line 627: warn: (message) => capturedLogs.push(message),
Line 628: ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/openai-responses-recall-aware-stream.test.ts</path>
<type>file</type>
<content>
8840: const client = streamResponsesRecallAware(
8841: streamFrom([
8842: created("resp_recall_execution_failure", "gpt-5.6-terra"),
8843: recallCall(0, { query: "private query" }),
8844: completed("resp_recall_execution_failure"),
8845: ]),
8846: {
8847: onComplete: () => {},
8848: onRecall: async () => {
8849: throw new Error("private callback failure");
8850: },
8851: runFollowUp: async () => {
8852: throw new Error("should not run");
8853: },
8854: },
8855: );
8856:
8857: const out = await drain(client);
8858: expect(out).toContain(PUBLIC_RECALL_ERROR);
8859: expect(out).not.toContain("private callback failure");
8860: expect(out).not.toContain("private query");
8861: ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
11707: try {
11708: for (;;) {
11709: try {
11710: await runPrincipalAttempt();
11711: break;
11712: } catch (error) {
11713: const isPrincipalTransportFailure =
11714: error instanceof SSEStreamTransportError &&
11715: !principalReadFinished &&
11716: !continuationAttempted;
11717: const shouldRetryPrincipal =
11718: isPrincipalTransportFailure &&
11719: error.kind === "read" &&
11720: !principalEventEmitted &&
11721: !ordinaryToolEmitted &&
11722: !signal.aborted &&
11723: opts.retryPrincipal !== undefined &&
11724: principalTransportRetries < maxPrincipalTransportRetries;
11725: if ...
Found 6 matches
/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts:
Line 8020: const transactionRollbacks: Array<() => void> = [];
Line 8036: const rollbackTransaction = (): void => {
Line 8038: for (const rollback of transactionRollbacks.splice(0).reverse()) {
Line 10726: transactionRollbacks.push(executed.rollback);
Line 11516: transactionRollbacks.push(nextExecuted.rollback);
Line 11637: transactionRollbacks.length = 0;
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
7980: lifecycle: OutputLifecycle,
7981: ): Array<Record<string, unknown>> =>
7982: Array.from(lifecycle.content)
7983: .sort(([left], [right]) => left - right)
7984: .filter(([, part]) => part.valueDone || part.partDone)
7985: .map(([, part]) =>
7986: part.kind === "refusal"
7987: ? { type: "refusal", refusal: part.authoritativeValue }
7988: : { type: "output_text", text: part.authoritativeValue },
7989: );
7990: const seedTextParts = (
7991: parts: unknown,
7992: target: Map<number, TextPartLifecycle>,
7993: allowedKinds: ReadonlySet<string>,
7994: description: string,
7995: ): void => {
7996: if (parts === undefined) return;
7997: if (!Array.isArray(parts)) {
7998: throw new Error(`Responses ${description} must be an array`);
7999: }
8000: for (const [index, ...
Resume the exact immutable provider security review. Your last output was only a Lore context warning and is not a verdict. Preserve all work. Recover context with lore recall --project /home/byk/Code/opencode-lore --scope project --limit 15 --json or GET http://127.0.0.1:3207/ui/search?q=provider+security+0dd569b5&project=/home/byk/Code/opencode-lore&scope=project; do not use the broken recall tool. Re-verify literal base 2cbf40060c67df229731cf1b9e34d5bf22ec2145, head lpmvqrur/0dd569b520bad37adbaea230f32100c7f83f463c, patch hash 3458ce2dc248950b13dc69dda91a07f95a2dcd49f128f2f4ec8e218a6d68b46e, then finish the substantive read-only security review requested previously. Do not edit/VCS/server/network/DB. Return PASS/CONCERN/MUST-FIX with exact file:line and end exactly MERGE or DO-NOT-MERGE. Never return only a warning or empty output.
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts</path>
<type>file</type>
<content>
2770: return false;
2771: }
2772: };
2773: const waitForDemand = async (): Promise<void> => {
2774: while (
2775: !downstreamCancelled &&
2776: !externalAborted &&
2777: (controller.desiredSize ?? 1) <= 0
2778: ) {
2779: await new Promise<void>((resolve) => {
2780: resumeDemand = resolve;
2781: });
2782: }
2783: if (externalAborted) throw signal?.reason;
2784: };
2785: const safeClose = (): void => {
2786: if (downstreamCancelled || settled) return;
2787: settled = true;
2788: cleanup();
2789: try {
2790: controller.close();
2791: } catch {
2792: // Already closed/cancelled
2793: }
2794: };
2795: const safeError = (error: unknown): void => ...
No files found
Found 8 matches /home/byk/Code/opencode-lore-provider-error/packages/gateway/src/llm-adapter.ts: Line 83: validateResponsesUsage, Line 2685: const validatedUsage = validateResponsesUsage( /home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts: Line 243: validateResponsesUsage, Line 12761: const usage = validateResponsesUsage( /home/byk/Code/opencode-lore-provider-error/packages/gateway/src/usage-validation.ts: Line 204: export function validateResponsesUsage( /home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts: Line 35: validateResponsesUsage, Line 910: const respUsage = validateResponsesUsage( Line 2050: validateResponsesUsage(parsed.response.usage, "malformed Responses usage");
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/usage-validation.ts</path>
<type>file</type>
<content>
160: total !== undefined &&
161: (prompt === undefined || completion === undefined)
162: ) {
163: invalid(message);
164: }
165: const componentTotal = safeTokenSum([prompt, completion], message);
166: // Cache counts are subsets of prompt_tokens; reasoning/audio/prediction
167: // counts are subsets of completion_tokens. They must not be added again.
168: if (total !== undefined && componentTotal !== total) invalid(message);
169:
170: const promptDetails = validateOpenAIDetails(
171: value.prompt_tokens_details,
172: prompt,
173: ["cached_tokens", "cache_write_tokens"],
174: message,
175: );
176: if (promptDetails) {
177: const cached = tokenCount(promptDetails.cached_tokens, message);
178: const cacheWrite = tokenCount(promptDetails.cache_write_tokens, message);
179: validateSubset([cached, ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts</path>
<type>file</type>
<content>
2105: allowFailureTerminal?: boolean;
2106: /** Buffered callers that run successful-turn side effects must reject
2107: * incomplete terminals rather than treating a parsed body as completion. */
2108: requireCompletedTerminal?: boolean;
2109: /** Internal state injection used by validated true passthrough. */
2110: state?: ResponsesAccState;
2111: onReader?: (reader: ReadableStreamDefaultReader<Uint8Array>) => void;
2112: } = {},
2113: ): Promise<GatewayResponse> {
2114: const state = opts.state ?? ...
Found 21 matches
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/llm-adapter.test.ts:
Line 1968: "event: response.output_text.delta\ndata: {not-json}\n\n",
Line 2285: (sentinel: string) => `event: ${sentinel}\ndata: {not-json}\n\n`,
Line 6727: new Response(`${bodyMarker} not-json`, {
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/lint-action-report.test.ts:
Line 933: body: "not-json",
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/openai-responses-recall-aware-stream.test.ts:
Line 2147: "event: response.completed\ndata: {not-json}\n\n",
Line 2167: expect(out).not.toContain("{not-json}");
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/worker-model.test.ts:
Line 311: new Response(`${bodyMarker} not-json`, {
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/warmup-execute.test.ts:
Line 190: Promise.resolve(new ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/translate/openai-responses.ts</path>
<type>file</type>
<content>
1260: `event: ${eventType}\ndata: ${JSON.stringify(data)}\n\n`,
1261: ),
1262: );
1263: }
1264:
1265: // response.created
1266: emit("response.created", {
1267: type: "response.created",
1268: response: {
1269: id: respId,
1270: object: "response",
1271: created_at: created,
1272: model: resp.model,
1273: status: "in_progress",
1274: output: [],
1275: usage: null,
1276: },
1277: });
1278:
1279: // Buffered Codex responses still carry subscription windows and credits.
1280: // These values are independent of the token usage Lore may rescale.
1281: for (const quota of resp.codexRateLimits ?? []) {
1282: emit("codex.rate_limits", quota);
1283: }
1284:
1285: // ...
Found 4 matches
/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts:
Line 7802: export function streamResponsesRecallAware(
Line 15475: return streamResponsesPassthrough(
Line 18893: streamResponsesRecallAware(upstreamResponse, {
Line 19101: streamResponsesPassthrough(
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
18830: ) {
18831: dropStreamingFinalizer();
18832: return;
18833: }
18834: accountUnsuccessfulResponse(
18835: resp,
18836: sessionState.sessionID,
18837: sessionState.resolvedConversationTTL,
18838: genAiSpan,
18839: endGenAiSpan,
18840: () => {
18841: sessionState._dirty = true;
18842: },
18843: );
18844: },
18845: dropStreamingFinalizer,
18846: true,
18847: requestCredentialFingerprint(req.rawHeaders, config) ?? ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
18735: };
18736: const finishWithRecall = async (resp: GatewayResponse): Promise<Response> => {
18737: try {
18738: const response = await awaitForeground(finalizeWithRecall(resp));
18739: bufferedRecallDiagnostics.finish(response.ok ? "completed" : "failed");
18740: return finishForeground(response);
18741: } catch (error) {
18742: rollbackRecallPersistence();
18743: bufferedRecallDiagnostics.finish(
18744: foregroundAbort.signal.aborted ? "aborted" : "failed",
18745: );
18746: throw error;
18747: }
18748: };
18749: function finishStreaming(resp: GatewayResponse): void {
18750: if (streamingFinalizerRegistered) return;
18751: streamingFinalizerRegistered = true;
18752: scheduleStreamingPostResponse(
18753: sessionState.sessionID,
18754: requestGeneration,
18755: async ...
Found 1 matches /home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts: Line 13480: function accountUnsuccessfulResponse(
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
13430: loreConfig().curator.onIdle &&
13431: containsGitCommit(req)
13432: ) {
13433: const modelInputCost =
13434: getModelEntrySync(
13435: getWorkerModel(sessionState.lastUpstream)?.modelID ?? "unknown",
13436: ).cost?.input ?? 3;
13437: const curationMultiplier =
13438: modelInputCost >= 5 ? 3 : modelInputCost >= 1 ? 2 : 1;
13439: const effectiveAfterTurns =
13440: loreConfig().curator.afterTurns * curationMultiplier;
13441: if (sessionState.turnsSinceCuration < effectiveAfterTurns) {
13442: log.info(
13443: `commit detected in session ${sessionID.slice(0, 16)} — triggering curation`,
13444: );
13445: sessionState.turnsSinceCuration = effectiveAfterTurns;
13446: }
13447: }
13448:
13449: // --- Schedule background work (fire-and-forget) ...
Found 1 matches /home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts: Line 13137: function accountConversationUsage(
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
13095:
13096: // Track cold-cache turns for auto-TTL upgrade (rolling 20-turn window)
13097: const cacheRead = usage.cacheReadInputTokens ?? 0;
13098: const cacheCreation = usage.cacheCreationInputTokens ?? 0;
13099: const isColdTurn = cacheRead === 0 && cacheCreation > 0;
13100: if (!sessionState.coldCacheWindow) sessionState.coldCacheWindow = [];
13101: sessionState.coldCacheWindow.push(isColdTurn);
13102: if (sessionState.coldCacheWindow.length > 20) {
13103: sessionState.coldCacheWindow.shift();
13104: }
13105: }
13106:
13107: // --- Finalize gen_ai.chat span (after cache analytics enrichment) ---
13108: // Ended here (before recordCacheUsage, matching the original inlined order)
13109: // so the extraction is ordering-identical: recordCacheUsage is pure
13110: // session-state bookkeeping that never touches the ...
Found 2 matches
/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/sentry.ts:
Line 110: export function setSentryCacheContext(usage: {
Line 408: export function emitCostMetric(
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/sentry.ts</path>
<type>file</type>
<content>
90:
91: if (opts.model) {
92: Sentry.setTag("model", opts.model);
93: }
94: if (opts.projectPath) {
95: const projectHash = createHash("sha256")
96: .update(opts.projectPath)
97: .digest("hex")
98: .slice(0, 16);
99: Sentry.setTag("project_hash", projectHash);
100: }
101: }
102:
103: // ---------------------------------------------------------------------------
104: // Cache context
105: // ---------------------------------------------------------------------------
106:
107: /**
108: * Record cache metrics on the current Sentry scope after upstream response.
109: */
110: export function setSentryCacheContext(usage: {
111: inputTokens: number;
112: outputTokens: number;
113: cacheReadInputTokens?: number;
114: cacheCreationInputTokens?: number;
115: }): void {
116: if (!Sentry.isInitialized()) return;
117:
118: const ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/sentry.ts</path>
<type>file</type>
<content>
390: if (!Sentry.isInitialized()) return;
391: Sentry.metrics.count("lore.cache_warmup.hit", 1, {
392: attributes: { model, ttl },
393: });
394: }
395:
396: /**
397: * Emit a metric when the circuit breaker trips.
398: */
399: export function emitWarmupCircuitBreakerMetric(): void {
400: if (!Sentry.isInitialized()) return;
401: Sentry.metrics.count("lore.cache_warmup.circuit_breaker_tripped", 1, {});
402: }
403:
404: // ---------------------------------------------------------------------------
405: // LLM cost estimation
406: // ---------------------------------------------------------------------------
407:
408: export function emitCostMetric(
409: model: string,
410: usage: AnthropicUsage,
411: callType: "conversation" | "direct" | "batch",
412: ttl?: "5m" | "1h",
413: ): void {
414: if (!Sentry.isInitialized()) return;
415:
416: // ...
Found 1 matches /home/byk/Code/opencode-lore-provider-error/packages/gateway/src/cost-tracker.ts: Line 664: export function recordConversationCost(
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
1020: recallPersistenceCommitObserver = undefined;
1021: provisionalFinalizerPauseForTest = undefined;
1022: foregroundErrorBodyTimeoutMs = FOREGROUND_ERROR_BODY_TIMEOUT_MS;
1023: if (stopFileWatcher) {
1024: stopFileWatcher();
1025: stopFileWatcher = null;
1026: }
1027: if (stopIdleScheduler) {
1028: stopIdleScheduler();
1029: stopIdleScheduler = null;
1030: }
1031: if (stopSyncScheduler) {
1032: // Awaits a final best-effort push so local changes reach the server on exit.
1033: await stopSyncScheduler();
1034: stopSyncScheduler = null;
1035: }
1036: _lastSeenSessionModel = null;
1037: _firstTurnConfirmed = false;
1038: resetWorkerModelState();
1039: resetBackgroundLimiter();
1040: }
1041:
1042: /** Per-session state tracked across requests. ...
Modified regular file packages/gateway/test/openai-responses-stream.test.ts:
...
8 8: * - Stop reason mapping from status
9 9: * - Mixed text + function_call output
10 10: */
11 : import { describe, test, expect, vi } from "vitest";
11: import { log } from "@loreai/core";
12: import { afterEach, describe, test, expect, vi } from "vitest";
12 13: import {
13 14: accumulateResponsesSSEStream,
14 15: isSupportedResponsesOutputItemType,
15 16: isValidResponsesOutputItemStatus,
17: makeResponsesAccState,
16 18: responsesDoneItemMatchesAdded,
17 19: responsesTerminalItemMatches,
18 20: SUPPORTED_RESPONSES_OUTPUT_ITEM_TYPES,
...
23 25: import type { GatewayResponse } from "../src/translate/types";
24 26: import { validateResponsesUsage } from "../src/usage-validation";
25 27:
28: const silentLogSink = {
29: info: () => {},
30: warn: () => {},
31: ...
...output truncated...
Full output saved to: /home/byk/.local/share/opencode/tool-output/tool_0abd8659d0012agnQNhou8Y9c0
415: const capturedLogs: string[] = [];
416: log.registerSink({
417: info: (message) => capturedLogs.push(message),
418: warn: (message) => capturedLogs.push(message),
419: error: (message) => capturedLogs.push(message),
420: captureException: (error) => capturedLogs.push(String(error)),
421: });
422: const completions: Array<{
423: response: GatewayResponse;
424: successful: boolean;
425: }> = [];
426: const client = streamResponsesRecallAware(
427: streamFrom([
428: sseEvent("response.created", {
429: sequence_number: 7,
430: response: {
431: id: "resp_principal_diagnostic",
432: created_at: 456,
...
<path>/home/byk/.local/share/opencode/tool-output/tool_0abd8659d0012agnQNhou8Y9c0</path> <type>file</type> <content> 1: Modified regular file packages/gateway/test/openai-responses-recall-aware-stream.test.ts: 2: ... 3: 173 173: const PUBLIC_RECALL_ERROR = "Lore could not continue the response after recall"; 4: 174 174: const PUBLIC_GATEWAY_ERROR = "Gateway request failed"; 5: 175 175: 6: 176: const nonMonotonicProviderFailures = ( 7: 177: [ 8: 178: ["response.failed", "response.failed", "failed"], 9: 179: ["failed response.done", "response.done", "failed"], 10: 180: ["cancelled response.done", "response.done", "cancelled"], 11: 181: ["error", "error", undefined], 12: 182: ["response.error", "response.error", undefined], 13: 183: ] as const 14: 184: ).flatMap(([alias, event, status]) => 15: 185: ([10, 9] as const).map( 16: 186: (sequence) => [alias, sequence, event, status] as ...
<path>/home/byk/.local/share/opencode/tool-output/tool_0abd8659d0012agnQNhou8Y9c0</path>
<type>file</type>
<content>
1134: 8946: failureStatus === undefined
1135: 8947: ? {
1136: 8948: sequence_number: failureSequence,
1137: 8949: error: { type: "provider_error", message: secret },
1138: 8950: diagnostics: { detail: secret },
1139: 8951: }
1140: 8952: : {
1141: 8953: sequence_number: failureSequence,
1142: 8954: provider_trace: secret,
1143: 8955: response: {
1144: 8956: id: "resp_non_monotonic_continuation_failure",
1145: 8957: model: secret,
1146: 8958: status: failureStatus,
1147: 8959: output: [],
1148: 8960: usage: { input_tokens: 101, output_tokens: 37 },
1149: 8961: error: { type: ...
Modified regular file packages/gateway/test/pipeline-streaming.test.ts:
...
85 85: import { translateAnthropicStreamToOpenAI } from "../src/stream/openai";
86 86: import { translateAnthropicStreamToResponses } from "../src/stream/openai-responses";
87 87: import { translateAnthropicStreamToGemini } from "../src/stream/gemini";
88: import { setRecallContinuationFailureHook } from "../src/recall-continuation-failure";
88 89: import {
89 90: makeConversationFixtures,
90 91: STANDARD_TOOLS,
...
726 727: afterEach(() => harness?.teardown());
727 728: afterEach(() => vi.mocked(getDegradationWarning).mockReset());
728 729: afterEach(() => vi.mocked(Sentry.startInactiveSpan).mockReset());
730: afterEach(() => setRecallContinuationFailureHook(undefined));
729 731:
730 732: it("does not deadlock when an OpenAI translator drops Anthropic lifecycle frames", async () => {
731 733: const anthropic = buildStreamingResponse(
...
Found 100 matches (more matches available)
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/llm-adapter.test.ts:
Line 5744: test("false for a generic 400 (bad param / quota) — must not swap the model", () => {
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/claude-usage-provisional.test.ts:
Line 21: it(`preserves quota during real Claude session header migration (stream=${stream}, status=${status})`, async () => {
Line 33: ? new Response("private upstream quota detail", {
Line 83: expect(body).not.toContain("private upstream quota detail");
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/lint-action-report.test.ts:
Line 731: new Error("billing_not_configured: quota exceeded"),
Line 733: ).toEqual({ status: 402, message: "insufficient credit or Copilot quota" });
/home/byk/Code/opencode-lore-provider-error/packages/gateway/test/claude-usage-headers.test.ts:
Line 13: const ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/recall-continuation-failure.ts</path>
<type>file</type>
<content>
1: export const RECALL_CONTINUATION_FAILURE_CATEGORIES = [
2: "recall_execution",
3: "follow_up_setup",
4: "follow_up_transport",
5: "follow_up_protocol",
6: "follow_up_failed",
7: "follow_up_missing_output",
8: "follow_up_incomplete_arguments",
9: "parallel_recall",
10: "nested_recall_incomplete",
11: "nested_recall_execution",
12: "depth_exhausted",
13: "missing_recall_block",
14: "resource_limit",
15: "delivery",
16: "unexpected",
17: ] as const;
18:
19: export type RecallContinuationFailureCategory =
20: (typeof RECALL_CONTINUATION_FAILURE_CATEGORIES)[number];
21:
22: type RecallContinuationFailureHook = (
23: category: RecallContinuationFailureCategory,
24: ) => void;
25:
26: let failureHook: RecallContinuationFailureHook | undefined;
27:
28: export class RecallContinuationFailure extends Error {
29: ...
Found 13 matches /home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts: Line 599: export const RESPONSES_PROVIDER_FAILURE_LOG = Line 607: export function sanitizeResponsesProviderFailureTerminal( Line 656: export function projectResponsesInProgressEvent( Line 875: const sanitizedFailure = sanitizeResponsesProviderFailureTerminal( Line 966: return finalizeUnsuccessfulResponsesAcc(state); Line 1055: export function finalizeUnsuccessfulResponsesAcc( Line 2053: export function validateResponsesProviderFailureTerminal( Line 2176: const sanitizedFailure = sanitizeResponsesProviderFailureTerminal( Line 2198: validateResponsesProviderFailureTerminal( Line 2223: log.error(RESPONSES_PROVIDER_FAILURE_LOG); Line 2642: ? JSON.stringify(projectResponsesInProgressEvent(parsed, state)) Line 2865: finish(false, finalizeUnsuccessfulResponsesAcc(state)); Line ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts</path>
<type>file</type>
<content>
560: return {
561: id: "",
562: model: "",
563: created: false,
564: stopReason: "end_turn",
565: usage: { inputTokens: 0, outputTokens: 0 },
566: items: new Map(),
567: rawItems: new Map(),
568: itemIndexById: new Map(),
569: callIndexById: new Map(),
570: effectiveToolIndexById: new Map(),
571: nextOutputIndex: 0,
572: activeTextItems: new Set(),
573: activeToolItems: new Set(),
574: unboundTextItems: new Set(),
575: unboundToolItems: new Set(),
576: textDoneItems: new Set(),
577: refusalDoneItems: new Set(),
578: argumentDoneItems: new Set(),
579: };
580: }
581:
582: export function cloneResponsesAccState(
583: state: ResponsesAccState,
584: ): ResponsesAccState {
585: return structuredClone(state);
586: }
587:
588: export function restoreResponsesAccState(
589: state: ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts</path>
<type>file</type>
<content>
1015: let input: unknown = {};
1016: if (item.args) {
1017: try {
1018: input = JSON.parse(item.args);
1019: } catch {
1020: input = item.args;
1021: }
1022: }
1023: content.push({
1024: type: "tool_use",
1025: id: item.callId || item.id,
1026: name: item.name,
1027: input,
1028: });
1029: }
1030: }
1031:
1032: let stopReason = state.stopReason;
1033: // If we saw tool_use, map stop reason accordingly
1034: if (content.some((b) => b.type === "tool_use") && stopReason === "end_turn") {
1035: stopReason = "tool_use";
1036: }
1037:
1038: return {
1039: id: state.id,
1040: model: state.model,
1041: content,
1042: rawOutputItems: Array.from(state.rawItems.entries())
1043: .sort(([a], [b]) => a - b)
1044: ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts</path>
<type>file</type>
<content>
2010: : event === "response.incomplete"
2011: ? status === "incomplete"
2012: : status === "completed" || status === "incomplete"
2013: : event === "response.completed"
2014: ? status === "completed" || status === "incomplete"
2015: : event === "response.incomplete"
2016: ? status === "incomplete"
2017: : status === "completed" || status === "incomplete";
2018: if (!valid) throw new Error("Responses terminal event/status mismatch");
2019: if (status === "incomplete") {
2020: if (validation === "public" || requireKnownIncompleteReason) {
2021: if (
2022: details?.reason !== undefined &&
2023: details.reason !== "max_output_tokens" &&
2024: details.reason !== "content_filter"
2025: ) {
2026: throw new Error("malformed Responses terminal ...
Found 6 matches
/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts:
Line 9152: const validateResponseLifecycle = (
Line 9186: if (event === "response.in_progress") {
Line 9194: throw new Error("response.in_progress has invalid status");
Line 9200: throw new Error("response.in_progress must have empty output");
Line 11251: ce === "response.in_progress"
Line 11682: event === "response.in_progress"
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
9100: );
9101: if (
9102: (contentState.authoritativeValueSeen &&
9103: contentState.authoritativeValue !== finalValue) ||
9104: (contentState.finalValue !== undefined &&
9105: contentState.finalValue !== finalValue) ||
9106: (contentState.partFinalValue !== undefined &&
9107: contentState.partFinalValue !== finalValue)
9108: ) {
9109: throw new Error(
9110: `Responses output_item.done changed reasoning content for index ${outputIndex}:${contentIndex}`,
9111: );
9112: }
9113: }
9114: }
9115: }
9116: lifecycle.outputDone = true;
9117: }
9118: }
9119: return outputIndex;
9120: };
9121: const ...
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
9230: status !== "cancelled")
9231: ) {
9232: throw new Error("Responses terminal event contradicts response status");
9233: }
9234: if (status === "incomplete") {
9235: const details = response?.incomplete_details;
9236: if (
9237: details !== undefined &&
9238: details !== null &&
9239: (typeof details !== "object" || Array.isArray(details))
9240: ) {
9241: throw new Error("malformed Responses terminal event");
9242: }
9243: const reason =
9244: details && typeof details === "object" && !Array.isArray(details)
9245: ? (details as Record<string, unknown>).reason
9246: : undefined;
9247: if (
9248: reason !== undefined &&
9249: reason !== "max_output_tokens" &&
9250: reason !== ...
Found 11 matches
/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts:
Line 221: sanitizeResponsesProviderFailureTerminal,
Line 10034: let providerFailureSeen = false;
Line 10288: sanitizeResponsesProviderFailureTerminal(event, parsed, state);
Line 10317: providerFailureSeen = true;
Line 10619: sanitizeResponsesProviderFailureTerminal(
Line 10966: sanitizeResponsesProviderFailureTerminal(
Line 11857: !providerFailureSeen &&
Line 11861: const failedResponse = providerFailureSeen
Line 11924: if (providerFailureSeen) finish(failedResponse, false);
Line 11943: output: providerFailureSeen
Line 11966: if (!providerFailureSeen && !continuationProviderFailureSeen) {
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
10000: try {
10001: controller.error(error);
10002: } catch {
10003: // Already closed/cancelled.
10004: }
10005: };
10006:
10007: const resetKeepalive = (): void => {
10008: if (keepaliveTimer) clearTimeout(keepaliveTimer);
10009: keepaliveTimer = setTimeout(function tick() {
10010: if (cancelled || signal.aborted) return;
10011: if ((controller.desiredSize ?? 1) > 0) {
10012: void safeEnqueue(keepaliveComment);
10013: }
10014: if (!signal.aborted) {
10015: keepaliveTimer = setTimeout(tick, KEEPALIVE_INACTIVITY_MS);
10016: }
10017: }, KEEPALIVE_INACTIVITY_MS);
10018: };
10019: const clearKeepalive = (): void => {
10020: if (keepaliveTimer) ...
<skill_content name="jj-guide"> # Skill: jj-guide # jj Guide for AI Agents Jujutsu (jj) is a Git-compatible VCS with mutable commits, automatic snapshotting, no staging area, and first-class conflicts. This skill teaches you how to use it safely from a non-interactive agent environment. If `.jj/` exists in the repo root, this is a jj repo. **Use `jj` commands, not `git`.** In a colocated repo (`.jj/` *and* `.git/`), git tools can read the state, but mutations should go through `jj` so the operation log stays consistent. ## Critical Rules - **NEVER** use interactive flags (`-i`, `--interactive`). TUI prompts hang in agent environments. This applies to `jj split -i`, `jj squash -i`, `jj commit -i`, `jj resolve`, `jj diffedit`, etc. - **ALWAYS** pass `-m "msg"` when describing/committing. Without `-m`, an editor opens and hangs. - **VERIFY** mutations with `jj st` and `jj log` after `squash`, `abandon`, `rebase`, `restore`, `commit`. ...
lpmvqrurxwlm 0dd569b520bad37adbaea230f32100c7f83f463c fix(responses): unify provider failure handling pxrvwsvvkmpo 2cbf40060c67df229731cf1b9e34d5bf22ec2145 feat(cch): add seeds for Claude Code up to 2.1.272 (#1780) acdb51a9d2d335d0c4da3523c236a1c12bd583a69ed9e803f6187464cb486546 - packages/gateway/src/pipeline.ts packages/gateway/src/stream/openai-responses.ts packages/gateway/test/openai-responses-recall-aware-stream.test.ts packages/gateway/test/openai-responses-stream.test.ts packages/gateway/test/pipeline-streaming.test.ts packages/gateway/test/recall-codex-stream.test.ts
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts</path>
<type>file</type>
<content>
692: /**
693: * Apply one parsed Responses SSE event to the accumulation state. Never touches
694: * I/O — safe to call while forwarding the same event verbatim to the client.
695: */
696: export function applyResponsesEvent(
697: state: ResponsesAccState,
698: event: string,
699: parsed: Record<string, unknown>,
700: ): void {
701: const response = isRecord(parsed.response) ? parsed.response : undefined;
702: const providerFailure =
703: event === "response.failed" ||
704: (event === "response.done" &&
705: (response?.status === "failed" || response?.status === "cancelled"));
706: if (
707: !providerFailure &&
708: Number.isSafeInteger(parsed.sequence_number) &&
709: (parsed.sequence_number as number) >= 0
710: ) {
711: state.lastAcceptedSequenceNumber = parsed.sequence_number as number;
712: }
713:
714: ...
3458ce2dc248950b13dc69dda91a07f95a2dcd49f128f2f4ec8e218a6d68b46e - The working copy has no changes. Working copy (@) : qzwttkwl d3b014cf (empty) fix(responses): isolate failure telemetry Parent commit (@-): lpmvqrur 0dd569b5 fix/responses-provider-failures | fix(responses): unify provider failure handling Warning: These bookmarks have conflicts: fix/responses-private-references Hint: Use `jj bookmark list` to see details. Use `jj bookmark set <name> -r <rev>` to resolve. lpmvqrurxwlm 0dd569b520bad37adbaea230f32100c7f83f463c false fix(responses): unify provider failure handling wswlsmrnuzlq 24880457763b6f10831856d01c41bd72d62ddc28 false fix(responses): reject non-monotonic provider failures plzxzousrzuv a1020a45be1382893a183e2ff39506e78a08fb76 false fix(responses): preserve trusted failure metadata skwrwnvkvulp 01a6e06b08ba1b54f42c5b4c757ec449eb8e8490 false fix(responses): make provider failure settlement atomic xqmskzvmnqkr b1bc7cd46c4eb09f23a7a5c6db257c380401ca02 false ...
...output truncated...
Full output saved to: /home/byk/.local/share/opencode/tool-output/tool_0abe048e0001lvhEZGmVFvNenF
2263: const doneItem =
2264: opts.validation === "codex"
2265: ? completeCodexMessageSnapshot(
2266: parsed.item as Record<string, unknown>,
2267: outputIndex,
2268: terminalContentParts,
2269: )
2270: : (parsed.item as Record<string, unknown>);
2271: parsed.item = doneItem;
2272: assertResponsesDoneMatchesAccumulatedState(
2273: state,
2274: outputIndex,
2275: doneItem,
2276: terminalContentParts,
2277: );
2278: }
2279: if (opts.validation && sourceSequenceNumber !== undefined) {
2280: lastSequenceNumber = sourceSequenceNumber;
2281: }
...
Found 3 matches
/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts:
Line 9621: const finish = (resp: GatewayResponse, successful: boolean): boolean => {
Line 15191: const finish = (operation: () => void): void => {
Line 15271: const finish = () => {
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
9570: item.id === syntheticId ||
9571: (item.type === "tool_use" && item.callId === syntheticId),
9572: ) ||
9573: [...acc.rawItems.values()].some(
9574: (item) => item.id === syntheticId || item.call_id === syntheticId,
9575: ),
9576: )
9577: ) {
9578: throw new Error("duplicate synthetic Responses item identity");
9579: }
9580: syntheticIdentities.add(syntheticId);
9581: };
9582:
9583: // --- Keepalive (same as streamResponsesPassthrough) ---
9584: const KEEPALIVE_INACTIVITY_MS = 30_000;
9585: const keepaliveComment = encoder.encode(`: keepalive\n\n`);
9586: let keepaliveTimer: ReturnType<typeof setTimeout> | null = null;
9587: let completed = false;
9588: let completionAttempted = false;
9589: let nextSequenceNumber = 0;
9590:
9591: const sequenceChunk = ...
Found 8 matches
/home/byk/Code/opencode-lore-provider-error/packages/core/src/log.ts:
Line 13: * An optional {@link LogSink} can be registered via {@link registerSink}.
Line 66: export function registerSink(s: LogSink): void {
Line 81: return sink?.withDbSpan ? sink.withDbSpan(sql, fn) : fn();
Line 468: sink?.info(msg);
Line 477: sink?.warn(msg);
Line 492: sink?.warn(msg);
Line 500: sink?.error(msg);
Line 504: if (err) sink?.captureException(sanitizedError(err));
<path>/home/byk/Code/opencode-lore-provider-error/packages/core/src/log.ts</path>
<type>file</type>
<content>
450: fd = openLogFileForAppend(path);
451: writeFileSync(fd, line, "utf8");
452: } catch {
453: // Silently degrade — logging failure shouldn't crash the app
454: } finally {
455: if (fd !== undefined) closeSync(fd);
456: }
457: }
458:
459: // ---------------------------------------------------------------------------
460: // Public API
461: // ---------------------------------------------------------------------------
462:
463: /** Log an informational status message. Suppressed unless LORE_DEBUG=1. */
464: export function info(...args: unknown[]): void {
465: const msg = redactSensitiveLogText(formatArgs(args));
466: if (isDebug && !readStderrSilenced())
467: console.error("[lore]", ...safeArgs(args));
468: sink?.info(msg);
469: writeToFile("info", msg);
470: }
471:
472: /** Log a warning. Suppressed unless LORE_DEBUG=1. ...
lpmvqrurxwlm 0dd569b520bad37adbaea230f32100c7f83f463c fix(responses): unify provider failure handling pxrvwsvvkmpo 2cbf40060c67df229731cf1b9e34d5bf22ec2145 feat(cch): add seeds for Claude Code up to 2.1.272 (#1780) 3458ce2dc248950b13dc69dda91a07f95a2dcd49f128f2f4ec8e218a6d68b46e - packages/gateway/src/pipeline.ts packages/gateway/src/stream/openai-responses.ts packages/gateway/test/openai-responses-recall-aware-stream.test.ts packages/gateway/test/openai-responses-stream.test.ts packages/gateway/test/pipeline-streaming.test.ts packages/gateway/test/recall-codex-stream.test.ts The working copy has no changes. Working copy (@) : qzwttkwl d3b014cf (empty) fix(responses): isolate failure telemetry Parent commit (@-): lpmvqrur 0dd569b5 fix/responses-provider-failures | fix(responses): unify provider failure handling Warning: These bookmarks have conflicts: fix/responses-private-references Hint: Use `jj bookmark list` to see details. Use `jj bookmark set <name> -r <rev>` to resolve.
<path>/home/byk/Code/opencode-lore-provider-error/packages/core/src/log.ts</path>
<type>file</type>
<content>
280: }
281: }
282:
283: function openLogFileForAppend(path: string): number {
284: let existing: Stats | undefined;
285: try {
286: existing = lstatSync(path);
287: if (!existing.isFile() || existing.isSymbolicLink()) {
288: throw new Error(`Refusing non-regular log file: ${path}`);
289: }
290: assertCurrentOwner(existing, path);
291: } catch (error) {
292: if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
293: }
294:
295: // O_NONBLOCK prevents a raced-in FIFO from blocking before fstat rejects it.
296: const fd = openSync(
297: path,
298: constants.O_WRONLY |
299: constants.O_APPEND |
300: constants.O_CREAT |
301: constants.O_NONBLOCK |
302: NO_FOLLOW,
303: LOG_FILE_MODE,
304: );
305: try {
306: const info = fstatSync(fd);
307: if (!info.isFile())
308: throw new ...
Found 11 matches /home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts: Line 616: const diagnostic = event === "error" || event === "response.error"; Line 2196: const diagnostic = event === "error" || event === "response.error"; Line 3004: default: Line 3646: default: /home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/anthropic.ts: Line 1100: default: Line 1444: * @param recallToolName - The name of the recall tool to intercept (default: "recall") Line 1894: default: Line 1941: default: Line 2086: default: Line 2135: default: /home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai.ts: Line 68: default:
<path>/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts</path>
<type>file</type>
<content>
1070:
1071: // ---------------------------------------------------------------------------
1072: // Stream accumulator (buffered)
1073: // ---------------------------------------------------------------------------
1074:
1075: function validatePublicResponsesEvent(
1076: state: ResponsesAccState,
1077: event: string,
1078: parsed: Record<string, unknown>,
1079: maxSparseIndex: number,
1080: ): void {
1081: const outputIndex = parsed.output_index;
1082: const validOutputIndex =
1083: Number.isSafeInteger(outputIndex) &&
1084: (outputIndex as number) >= 0 &&
1085: (outputIndex as number) < maxSparseIndex;
1086: const item = validOutputIndex
1087: ? state.items.get(outputIndex as number)
1088: : undefined;
1089: const malformed = (): never => {
1090: throw new Error("malformed Responses stream event");
1091: ...
Found 100 matches (more matches available)
/home/byk/Code/opencode-lore-provider-error/packages/gateway/src/stream/openai-responses.ts:
Line 8: * response.created → response.in_progress →
Line 12: * response.completed
Line 57: | "response.completed"
Line 58: | "response.incomplete"
Line 59: | "response.failed";
Line 614: ): { event: "response.failed"; parsed: Record<string, unknown> } | undefined {
Line 620: event === "response.failed" &&
Line 624: event === "response.done" &&
Line 631: event: "response.failed",
Line 633: type: "response.failed",
Line 655: /** Project an in-progress lifecycle frame from trusted response.created state. */
Line 662: type: "response.in_progress",
Line 703: event === "response.failed" ||
Line 704: (event === "response.done" &&
Line 732: case "response.created": {
Line 748: case "response.in_progress":
Line 864: // `response.done` / ...
2cbf40060c67df229731cf1b9e34d5bf22ec2145lpmvqrur / 0dd569b520bad37adbaea230f32100c7f83f463c3458ce2dc248950b13dc69dda91a07f95a2dcd49f128f2f4ec8e218a6d68b46eDiagnostics can still break failure delivery, accounting, and rollback.
The new provider-failure branches call log.error() directly:
packages/gateway/src/stream/openai-responses.ts:2223packages/gateway/src/pipeline.ts:10315packages/gateway/src/pipeline.ts:10994The logger invokes the registered sink without containment at packages/core/src/log.ts:500. If sink.error() throws:
onValidatedEvent (openai-responses.ts:2224-2228). Its catch logs through the same failing sink at openai-responses.ts:2909-2914, then the outer rejection errors the client stream at openai-responses.ts:2956. The client loses the fixed failure terminal and unsuccessful accounting.providerFailureSeen and calling finish() (pipeline.ts:10316-10319). The outer path can throw again while logging at pipeline.ts:11838-11840, reaching controller.error() at pipeline.ts:11973-11980.pipeline.ts:10995-10998), allowing diagnostics to change rollback, failure classification, and completion behavior.This violates the hard rule that telemetry and diagnostics never alter responses. Wrap these fixed-message reports in a non-throwing helper. Add adversarial tests with a throwing log sink for plain, principal, and continuation paths. Assert one sanitized terminal, unsuccessful accounting exactly once, rollback exactly once where applicable, and no private provider data. ...
Date: Sep 16, 2026 * 🔴 (19:59) User specified that `error` logs are “Always visible — these indicate real failures.” * 🟡 (19:59) `packages/core/src/log.ts:496-504` implements `error(...args: unknown[])`: formats and redacts the message with `redactSensitiveLogText(formatArgs(args))`, writes `[lore]` to stderr unless `readStderrSilenced()` is true, reports through `sink?.error(msg)`, persists vi…
Date: Sep 16, 2026 * 🔴 (19:58) User specified that diagnostics must “never include response values”; `packages/gateway/test/llm-adapter.test.ts` enforces this in `empty worker diagnostics never include response values`, where the sentinel is absent and `finish_reason=unknown` is present, alongside tests ensuring malformed JSON and worker diagnostics do not expose response content, provider bodie…
Date: Sep 16, 2026 * 🔴 (19:57) User stated failed usage/accounting never depends on client demand, reflected by `// Failed usage/accounting never depends on client demand.` in `packages/gateway/src/stream/openai-responses.ts` around lines 2863-2865; on `response.failed`, `finish(false, finalizeUnsuccessfulResponsesAcc(state))` runs before `await waitForDemand()`. * 🟡 (19:57) `packages/gateway/s…
Date: Sep 16, 2026 * 🔴 (19:57) User stated failed output is never authoritative and must not reach accounting hooks, reflected by the exact comment `/** Failed output is never authoritative and must not reach accounting hooks. */` in `packages/gateway/src/stream/openai-responses.ts` around line 1054. * 🔴 (19:57) User’s gateway design specifies a single provider-failure payload as the only failu…
Date: Sep 16, 2026 * 🔴 (19:57) User stated failed usage/accounting never depends on client demand, reflected by the comment `// Failed usage/accounting never depends on client demand.` in `packages/gateway/src/stream/openai-responses.ts` around line 2864. * 🟡 (19:57) Truncated candidate diff output was saved to `/home/byk/.local/share/opencode/tool-output/tool_0abcb20e7001GQ5RyS6H1vW7LG`.
Date: Sep 16, 2026 * 🔴 (19:55) User stated this repository uses Jujutsu when `.jj/` exists: use `jj` rather than `git` for mutations; never use interactive flags; always pass `-m "msg"` when describing/committing; verify mutations with `jj st` and `jj log`; prefer stable letter-based change IDs over hexadecimal commit IDs; never rebase or describe immutable commits. * 🔴 (19:55) User stated `jj`…
Date: Sep 16, 2026 * 🔴 [requested-review] (19:51) User requested an independent READ-ONLY security/privacy review of the immutable provider candidate in `/home/byk/Code/opencode-lore-provider-error`. * 🔴 (19:51) User specified candidate identity: base literal `2cbf40060c67df229731cf1b9e34d5bf22ec2145`; head stable change `lpmvqrurxwlm`; commit `0dd569b520bad37adbaea230f32100c7f83f463c`; expecte…