Dashboard › opencode-lore › Session 1alis89VRJ96
1alis89VRJ96CkaFGPerform an independent immutable security/pentest review in /home/byk/Code/opencode-lore-responses-projection-security. Candidate stable change kwmswwmtzlnxuvpkqymrwrxttlwowsys, exact head 6d9f8d6a8a1953c655061bd8e37b33c91788d498, base exact commit 2cbf40060c67df229731cf1b9e34d5bf22ec2145, expected plain jj diff --from main@origin --to kwmswwmt | sha256sum c447298696afdce49d888cc6c8e107cdf2aac3a973d5adfe9e2578d25bcaaa95. Exactly two paths may differ: packages/gateway/src/pipeline.ts and packages/gateway/test/openai-responses-recall-aware-stream.test.ts. Read AGENTS.md, quality/REVIEW.md, relevant scripts, every changed line and relevant validators/accumulators/translators/callback/log/persistence paths. Do not edit/format/install/mutate VCS, access server/network/production DB, or duplicate exhaustive validation. Verify identity/hash/status/conflicts/paths at start and end. Adversarially test/reason about privacy leakage through nonsemantic frames, valid-event cross-field aliases, nested item/action/result/output/annotation/logprob/usage/incomplete/error extensions, provider failures, callback rawOutputItems, terminal rebuilding, item references, hidden recall IDs/query/result/coverage, sparse index collisions/reordering, synthetic anchors, malformed JSON, unsafe numbers, retries, cancellation/backpressure, resource/CPU bounds, test-only hook exposure, logging/Sentry failures, and exact-once rollback/accounting. Ensure every accepted event accumulates privately before suppression and no hidden source coverage or diagnostics escape. Evaluate failing-first and guard-removal evidence; run only focused checks if needed. Report findings ordered by severity as PASS/CONCERN/MUST-FIX with exact current file:line evidence, attack path, and residual risk. Never return empty/progress/context-warning-only output; if normal recall warns, use lore recall --project /home/byk/Code/opencode-lore --scope project --limit 20 <query>. 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`. ...
<path>/home/byk/Code/opencode-lore-responses-projection-security</path> <type>directory</type> <entries> .craft.yml .git .github/ .gitignore .jj/ .lore.md .oxfmtrc.json .oxlintrc.json AGENTS.md CHANGELOG.md codecov.yml LICENSE node_modules/ package.json packages/ patches/ pnpm-lock.yaml pnpm-workspace.yaml quality/ README.md scripts/ stryker.config.mjs supabase/ tsconfig.base.json tsconfig.json vitest.config.ts vitest.evals.config.ts vitest.mutation.config.ts (28 entries) </entries>
<path>/home/byk/Code/opencode-lore-responses-projection-security/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-responses-projection-security/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-responses-projection-security/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: ...
/home/byk/Code/opencode-lore-responses-projection-security The working copy has no changes. Working copy (@) : muqyuuym 60d399b5 (empty) (no description set) Parent commit (@-): kwmswwmt 6d9f8d6a fix/responses-hidden-output* | fix(responses): sanitize projected output 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.
kwmswwmtzlnxuvpkqymrwrxttlwowsys 6d9f8d6a8a1953c655061bd8e37b33c91788d498 parents=f30236708bc928ee2e12739d1de7a7d21871c7d2 conflict=false description=fix(responses): sanitize projected output lnvrxqoqsqutpvpxvnppskkmmmsztwus f30236708bc928ee2e12739d1de7a7d21871c7d2 parents=a3fa555bdcabb376aa33278bdb76007269f1940a conflict=false description=fix(responses): complete hidden-output state pxrvwsvvkmpoxnsqmrkwrnlqvvkoltwz 2cbf40060c67df229731cf1b9e34d5bf22ec2145 parents=e977b4b1da8f8197c3238466d41de0bccd8eb054 conflict=false description=feat(cch): add seeds for Claude Code up to 2.1.272 (#1780)
c447298696afdce49d888cc6c8e107cdf2aac3a973d5adfe9e2578d25bcaaa95 -
packages/gateway/src/pipeline.ts packages/gateway/test/openai-responses-recall-aware-stream.test.ts packages/gateway/src/pipeline.ts | 1074 ++++++++++++++++++++-- ...st/openai-responses-recall-aware-stream.test.ts | 1028 ++++++++++++++++++++- 2 files changed, 1994 insertions(+), 108 deletions(-) kwmswwmtzlnx 6d9f8d6a8a1953c655061bd8e37b33c91788d498 conflict=false fix(responses): sanitize projected output lnvrxqoqsqut f30236708bc928ee2e12739d1de7a7d21871c7d2 conflict=false fix(responses): complete hidden-output state zlsmzkntqzzx a3fa555bdcabb376aa33278bdb76007269f1940a conflict=false fix(responses): harden hidden-output projection ozrmvotwxzuy 583020fad43e1481470aac2588251b8636d16251 conflict=false fix(responses): stabilize sparse principal projection unznwpylspzq ab979df5cddfec3952680e423e39564664e881fe conflict=false fix(responses): project hidden output consistently pxrvwsvvkmpo 2cbf40060c67df229731cf1b9e34d5bf22ec2145 conflict=false feat(cch): add seeds for ...
...output truncated...
Full output saved to: /home/byk/.local/share/opencode/tool-output/tool_0acde2f2c001FXZ27wjacAwaay
+ if (!isSemanticResponsesEvent(ce)) {
+ // Always accumulate into the internal state for postResponse.
+ applyResponsesEvent(contState, ce, cparsed);
+ continue;
+ }
const contNormalizationState = normalizeCodexEvent(
contState,
ce,
@@ -10835,6 +11725,10 @@
) {
preserveStreamedReasoning(contState, ci);
}
+ const clientParsed = projectResponsesEventForClient(
+ ce,
+ cparsed,
+ );
let resolvedVisibleTool = false;
if ...
<path>/home/byk/.local/share/opencode/tool-output/tool_0acde2f2c001FXZ27wjacAwaay</path> <type>file</type> <content> 1: diff --git a/packages/gateway/src/pipeline.ts b/packages/gateway/src/pipeline.ts 2: index 004e03b3e2..c8188a29f2 100644 3: --- a/packages/gateway/src/pipeline.ts 4: +++ b/packages/gateway/src/pipeline.ts 5: @@ -7826,6 +7826,8 @@ 6: }) => Promise<Response>; 7: /** Test-only override for the stream inactivity deadline. */ 8: sseInactivityMs?: number; 9: + /** Test-only observer for public output-index projection writes. */ 10: + onProjectionWriteForTest?: () => void; 11: /** 12: * Called when a `recall` function_call is fully parsed. Runs the recall 13: * (LTM search + optional LLM result) and returns the pieces needed to 14: @@ -8057,6 +8059,597 @@ 15: const sseInactivityMs = opts.sseInactivityMs ?? ...
<path>/home/byk/.local/share/opencode/tool-output/tool_0acde2f2c001FXZ27wjacAwaay</path>
<type>file</type>
<content>
1410: return new Response(events.join(""), {
1411: @@ -65,6 +69,48 @@
1412: return out;
1413: }
1414:
1415: +function responseEvents(output: string): Array<{
1416: + event: string;
1417: + data: Record<string, unknown>;
1418: +}> {
1419: + return [...output.matchAll(/^event: (.+)\ndata: (.+)$/gm)].flatMap(
1420: + ([, event, data]) => {
1421: + try {
1422: + const parsed = JSON.parse(data) as unknown;
1423: + return parsed && typeof parsed === "object" && !Array.isArray(parsed)
1424: + ? [{ event, data: parsed as Record<string, unknown> }]
1425: + : [];
1426: + } catch {
1427: + return [];
1428: + }
1429: + },
1430: + );
1431: +}
1432: +
1433: +function expectVisibleOutputIndicesToMatchTerminal(output: string): void {
1434: + const events = responseEvents(output);
1435: + const terminal = ...
Found 100 matches (more matches available)
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/sentry.ts:
Line 15: setRecallContinuationFailureHook,
Line 710: setRecallContinuationFailureHook(
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/translate/types.ts:
Line 346: rawOutputItems?: Array<Record<string, unknown>>;
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/translate/openai-responses.ts:
Line 1163: const output: Array<Record<string, unknown>> = resp.rawOutputItems
Line 1164: ? [...resp.rawOutputItems]
Line 1169: if (!resp.rawOutputItems) {
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/recall.ts:
Line 1217: (resp.rawOutputItems?.some(hasResponsesRefusal) ?? false)
Line 1274: const rawPrefixBlocks: GatewayContentBlock[] = (resp.rawOutputItems ?? [])
Line 1721: for (const item of resp.rawOutputItems ?? ...
Found 28 matches
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/stream/openai.ts:
Line 84: export function translateAnthropicStreamToOpenAI(
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/stream/openai-responses.ts:
Line 95: export const SUPPORTED_RESPONSES_OUTPUT_ITEM_TYPES = [
Line 238: export function isSupportedResponsesOutputItemType(
Line 244: export function isValidResponsesOutputItemStatus(
Line 338: export function isValidResponsesReasoningEncryptedContent(
Line 349: export function responsesDoneItemMatchesAdded(
Line 401: export function responsesTerminalItemMatches(
Line 556: export function makeResponsesAccState(): ResponsesAccState {
Line 582: export function applyResponsesEvent(
Line 815: export function finalizeResponsesAcc(
Line 1750: export function normalizeCodexResponsesEvent(
Line 2383: export function formatResponsesEvent(event: string, data: string): string {
...
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/pipeline.ts</path> <type>file</type> <content> 7760: }, 7761: streamSignal, 7762: recallPersistence.rollback, 7763: ); 7764: } 7765: 7766: /** 7767: * True-streaming, recall-aware variant of `streamResponsesPassthrough` for the 7768: * OpenAI Responses API (codex/ChatGPT) — used when the request carries the 7769: * gateway-injected `recall` tool but the client speaks the Responses API. 7770: * 7771: * Unlike the buffered `accumulateResponsesSSEStream` path (which withholds ALL 7772: * client bytes until the entire slow reasoning-heavy upstream completes — the 7773: * cause of opencode's 10s `ProviderHeaderTimeoutError`), this function forwards 7774: * every upstream SSE event to the client AS IT ARRIVES, while transparently 7775: * intercepting a `recall` `function_call` output item: 7776: * 7777: * - **No recall**: forwards everything unchanged (identical to 7778: * ...
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
8660: detailLimit?: number;
8661: };
8662: const parseRecallArguments = (value: unknown): RecallArguments => {
8663: if (typeof value !== "string") {
8664: throw new Error(
8665: "invalid recall function arguments: expected JSON string",
8666: );
8667: }
8668: let input: unknown;
8669: try {
8670: input = JSON.parse(value);
8671: } catch {
8672: throw new Error("invalid recall function arguments: malformed JSON");
8673: }
8674: if (!input || typeof input !== "object" || Array.isArray(input)) {
8675: throw new Error("invalid recall function arguments: expected object");
8676: }
8677: const record = input as Record<string, unknown>;
8678: const allowed = new Set([
8679: "query",
8680: "scope",
8681: "id",
8682: "ids",
8683: ...
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
10031: !responsesTerminalItemMatches(actual, streamed)
10032: ) {
10033: throw new Error("Responses terminal output changed streamed item");
10034: }
10035: if (!isReference && actual.type === "reasoning") {
10036: if (!lifecycle) {
10037: throw new Error(
10038: `missing Responses lifecycle for index ${outputIndex}`,
10039: );
10040: }
10041: assertTerminalReasoningMatchesLifecycle(lifecycle, actual, outputIndex);
10042: }
10043: if (!isReference) {
10044: acc.rawItems.set(outputIndex, { ...streamed, ...actual });
10045: }
10046: expectedIndex = matchIndex + 1;
10047: }
10048: };
10049: type ReferenceLifecycle = { id: string; done: boolean };
10050: const consumeReferenceEvent = (
10051: acc: ResponsesAccState,
10052: ...
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
10931: }
10932: }
10933: };
10934: const promoteDeferredCandidate = (outputIndex: number): void => {
10935: hiddenRecallBytes += unresolvedToolBytes.get(outputIndex) ?? 0;
10936: unresolvedToolBytes.delete(outputIndex);
10937: if (hiddenRecallBytes > maxHiddenRecallBytes) {
10938: throw new SSEStreamLimitError(
10939: "recall stream exceeded deferred event limit",
10940: );
10941: }
10942: };
10943:
10944: resetKeepalive();
10945: for await (const { event, data } of parseSSEStream(reader, {
10946: maxFrames: maxSSEFrames,
10947: inactivityMs: sseInactivityMs,
10948: signal,
10949: frameCounter,
10950: })) {
10951: ...
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
12062: contState.rawItems.size === 0
12063: ) {
12064: throw new RecallContinuationFailure(
12065: "follow_up_missing_output",
12066: );
12067: }
12068: if (
12069: continuationFollowUpInput.finalRecallRound &&
12070: contPending.length === 0 &&
12071: !isUsableRecallContinuation(
12072: finalizeResponsesAcc(contState),
12073: )
12074: ) {
12075: throw new RecallContinuationFailure(
12076: "follow_up_missing_output",
12077: );
12078: }
12079: ...
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/stream/openai-responses.ts</path> <type>file</type> <content> 1: /** 2: * OpenAI Responses API SSE stream accumulator. 3: * 4: * Parses upstream Responses API streaming events and accumulates the full 5: * response into a `GatewayResponse`. The Responses API uses a different 6: * SSE event lifecycle than Anthropic: 7: * 8: * response.created → response.in_progress → 9: * response.output_item.added → response.output_text.delta (repeated) → 10: * response.output_item.done → response.function_call_arguments.delta → 11: * response.function_call_arguments.done → 12: * response.completed 13: * 14: * Reuses `parseSSEStream` from the Anthropic stream module since the 15: * underlying SSE wire format is the same. ...
Found 10 matches
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/translate/types.ts:
Line 349: codexRateLimits?: Array<Record<string, unknown>>;
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/translate/openai-responses.ts:
Line 1281: for (const quota of resp.codexRateLimits ?? []) {
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/stream/openai-responses.ts:
Line 60: codexRateLimits?: Array<Record<string, unknown>>;
Line 602: (state.codexRateLimits ??= []).push(quota);
Line 897: ...(state.codexRateLimits
Line 898: ? { codexRateLimits: state.codexRateLimits }
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/pipeline.ts:
Line 19320: if (currentResp.codexRateLimits?.length) {
Line 19321: continuationResp.codexRateLimits = [
Line 19322: ...currentResp.codexRateLimits,
Line 19323: ...
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/translate/openai-responses.ts</path>
<type>file</type>
<content>
1130: } else {
1131: // Re-emit opaque blocks as message content parts (e.g. input_image).
1132: appendItem({
1133: type: "message",
1134: role: msg.role === "assistant" ? "assistant" : "user",
1135: content: [block.raw],
1136: });
1137: }
1138: }
1139: }
1140: }
1141:
1142: return items;
1143: }
1144:
1145: // ---------------------------------------------------------------------------
1146: // GatewayResponse → OpenAI Responses API response
1147: // ---------------------------------------------------------------------------
1148:
1149: export function buildOpenAIResponsesResponse(
1150: resp: GatewayResponse,
1151: wasStreaming: boolean,
1152: ): Response {
1153: if (wasStreaming) {
1154: return ...
Found 2 matches
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/pipeline.ts:
Line 7794: export function streamResponsesRecallAware(
Line 19534: streamResponsesRecallAware(upstreamResponse, {
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
19220: currentModifiedReq,
19221: currentResp,
19222: followUpResult,
19223: recallBlock,
19224: foregroundAbort.signal,
19225: finalRecallRound,
19226: )
19227: : await runRecallFollowUpJSON(
19228: jsonRecallCtx,
19229: currentModifiedReq,
19230: currentResp,
19231: followUpResult,
19232: recallBlock,
19233: foregroundAbort.signal,
19234: finalRecallRound,
19235: );
19236: } catch (fetchErr) {
19237: if (
19238: foregroundAbort.signal.aborted ||
19239: (fetchErr instanceof Error && fetchErr.name === "AbortError")
19240: ) {
19241: throw fetchErr;
19242: }
19243: if (
19244: ...
Found 7 matches
/home/byk/Code/opencode-lore-responses-projection-security/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-responses-projection-security/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-responses-projection-security/packages/core/src/log.ts</path>
<type>file</type>
<content>
1: /**
2: * Lightweight logger that suppresses informational messages by default.
3: *
4: * In TUI mode, all stderr output renders as red "error" text — confusing
5: * for routine status messages like "incremental distillation" or "pruned
6: * temporal messages". Only actual errors should be visible by default.
7: *
8: * Set LORE_DEBUG=1 to see informational messages (useful when debugging
9: * the plugin itself).
10: *
11: * ## Sink registration
12: *
13: * An optional {@link LogSink} can be registered via {@link registerSink}.
14: * When registered, every log call (regardless of `isDebug`) also forwards
15: * to the sink. This is used by the gateway to bridge logs → Sentry without
16: * adding a Sentry dependency to `@loreai/core`. ...
Found 100 matches (more matches available)
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/test/content-passthrough.test.ts:
Line 11: * tool on a PNG returned "Tool ran without output or errors").
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/test/compaction.test.ts:
Line 564: expect(response.usage).toBeDefined();
Line 565: expect(response.usage?.inputTokens).toBeTypeOf("number");
Line 566: expect(response.usage?.outputTokens).toBeTypeOf("number");
Line 580: expect(response.usage?.outputTokens).toBe(50);
Line 581: expect(response.usage?.inputTokens).toBe(0);
Line 587: expect(response.usage?.outputTokens).toBe(1);
Line 858: // Per-model client usage scaling
Line 927: const usage = { input_tokens: 100, output_tokens: 50 };
Line 928: expect(scaleUsageForClient(usage, 150_300)).toBe(usage);
Line 1005: // usage above the client's ~167K auto-compact threshold. ...
Found 63 matches
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/test/openai-responses-recall-aware-stream.test.ts:
Line 523: expect(completedResponse?.rawOutputItems).toContainEqual(
Line 1790: expect(completedResponse?.rawOutputItems).toContainEqual(
Line 1839: type: "item_reference",
Line 1911: name: "message annotations",
Line 1923: content: [{ type: "output_text", text: "answer", annotations: [] }],
Line 2022: expect(completedResponse?.rawOutputItems).toEqual([item]);
Line 2025: test("never forwards response-side item_reference lifecycle events", async () => {
Line 2033: type: "item_reference",
Line 2040: type: "item_reference",
Line 2049: output: [{ type: "item_reference", id: "msg_server_only" }],
Line 2064: expect(out).not.toContain("item_reference");
Line 2066: ...
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/test/openai-responses-recall-aware-stream.test.ts</path>
<type>file</type>
<content>
1750: output: [
1751: {
1752: type: "function_call",
1753: id: "fc_terminal_name",
1754: call_id: "call_terminal_name",
1755: name: "recall",
1756: arguments: "{}",
1757: status: "completed",
1758: },
1759: ],
1760: },
1761: }),
1762: ]),
1763: {
1764: validation: "codex",
1765: onComplete: (response) => {
1766: completedResponse = response;
1767: },
1768: onRecall: async () => {
1769: recallCalls++;
1770: return { anchorText: "", resultText: "" };
1771: },
1772: runFollowUp: async () => {
1773: throw new Error("should not run");
1774: },
1775: ...
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/test/openai-responses-recall-aware-stream.test.ts</path>
<type>file</type>
<content>
5020: {
5021: onComplete: () => {},
5022: onRecall: async () => {
5023: recalled++;
5024: return { anchorText: "", resultText: "" };
5025: },
5026: runFollowUp: async () => {
5027: throw new Error("should not run");
5028: },
5029: },
5030: );
5031:
5032: expect(await drain(client)).toContain(PUBLIC_RECALL_ERROR);
5033: expect(recalled).toBe(0);
5034: });
5035:
5036: test("rejects impossible cache usage before recall side effects", async () => {
5037: let recalled = 0;
5038: const client = streamResponsesRecallAware(
5039: streamFrom([
5040: created("resp_cache_usage_overflow", "gpt-5.6-terra"),
5041: recallCall(0, { query: "usage" }),
5042: completed("resp_cache_usage_overflow", ...
Found 11 matches
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/test/openai-responses-recall-aware-stream.test.ts:
Line 8230: created("resp_private_diagnostic_followup", "gpt-5.6-terra"),
Line 8234: textItem(0, "safe answer", "msg_private_diagnostic_answer"),
Line 8235: completed("resp_private_diagnostic_followup"),
Line 8239: created("resp_private_diagnostic_principal", "gpt-5.6-terra"),
Line 8244: completed("resp_private_diagnostic_principal"),
Line 8320: private_extension: privateEventExtension,
Line 8337: private_extension: privateItemExtension,
Line 8393: private_extension: privateNestedExtension,
Line 8483: ["object", '{"private_extension":"private created-at object"}'],
Line 8539: `{"type":"response.completed","response":{"id":"resp_invalid_created_at_visible","model":"gpt-5.6-terra","created_at":{"private":"created-at ...
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/usage-validation.ts</path>
<type>file</type>
<content>
1: /** Runtime validation for provider-reported token usage. */
2:
3: export function isRecord(value: unknown): value is Record<string, unknown> {
4: return !!value && typeof value === "object" && !Array.isArray(value);
5: }
6:
7: function invalid(message: string): never {
8: throw new Error(message);
9: }
10:
11: function tokenCount(
12: value: unknown,
13: message: string,
14: allowNull = false,
15: ): number | undefined {
16: if (value === undefined || (allowNull && value === null)) return undefined;
17: if (!Number.isSafeInteger(value) || (value as number) < 0) invalid(message);
18: return value as number;
19: }
20:
21: /** Add validated token counts without allowing a safe-integer overflow. ...
Found 1 matches
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/recall-diagnostics.ts:
Line 8: export function createRecallDiagnostics(enabled = true) {
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/recall-diagnostics.ts</path>
<type>file</type>
<content>
1: import { createHash } from "node:crypto";
2: import { log, type RecallCoverage } from "@loreai/core";
3:
4: /** Keep request-local diagnostic state bounded while observing chains beyond ten rounds. */
5: export const MAX_RECALL_DIAGNOSTIC_ROUNDS = 64;
6:
7: /** Request-local comparisons only. Fingerprints and recall content never leave this closure. */
8: export function createRecallDiagnostics(enabled = true) {
9: const inputs = new Set<string>();
10: const results = new Set<string>();
11: const pairs = new Set<string>();
12: const coverage = new Set<string>();
13: const started = performance.now();
14: let finished = false;
15: let rounds = 0;
16: let detailCalls = 0;
17: let emptyBodies = 0;
18: let resultBytes = 0;
19: const fingerprint = (value: string) =>
20: ...
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/sentry.ts</path>
<type>file</type>
<content>
660:
661: /**
662: * Derive the (storage_mode, vec_available) tag pair from a read cohort so a
663: * healthy vec0 host is separable from a silently degraded JS-fallback host:
664: * - vec0 → storage=vec0, vec_available=true
665: * - degraded → storage=vec0, vec_available=false (vec0 layout, no ext)
666: * - blob-native → storage=blob, vec_available=true
667: * - blob-js → storage=blob, vec_available=false
668: */
669: export function vecCohortTags(readMode: VecReadLatencySample["readMode"]): {
670: read_mode: string;
671: storage_mode: string;
672: vec_available: string;
673: } {
674: const storageVec = readMode === "vec0" || readMode === "degraded";
675: const native = readMode === "vec0" || readMode === "blob-native";
676: return {
677: read_mode: readMode,
678: storage_mode: storageVec ? ...
No files found
No files found
<path>/home/byk/Code/opencode-lore-responses-projection-security/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: ...
<path>/home/byk/Code/opencode-lore-responses-projection-security/vitest.config.ts</path>
<type>file</type>
<content>
1: import { defineConfig } from "vitest/config";
2: import path from "node:path";
3:
4: export default defineConfig({
5: // Alias @loreai/core and @loreai/gateway for test imports.
6: // MUST be at the top level of the vite config — putting this under
7: // `test.resolve.alias` does NOT work (vite's resolver is a top-level
8: // option, not a test.* option). The previous placement silently
9: // resolved to the stale dist build, masking real test failures.
10: resolve: {
11: alias: {
12: "@loreai/core": path.resolve(__dirname, "packages/core/src"),
13: "@loreai/gateway": path.resolve(__dirname, "packages/gateway/src"),
14: },
15: },
16: test: {
17: // Run all packages' tests
18: include: [
19: "packages/core/test/**/*.test.ts",
20: // Fast, pure unit tests for the eval suite's own logic (scorers,
21: // ...
<path>/home/byk/Code/opencode-lore-responses-projection-security/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 ...
Found 18 matches
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/test/openai-responses-recall-aware-stream.test.ts:
Line 30: captureException: () => {},
Line 36: log.registerSink(silentLogSink);
Line 730: log.registerSink({
Line 734: captureException: () => {},
Line 793: log.registerSink({
Line 797: captureException: () => {},
Line 832: log.registerSink({
Line 836: captureException: () => {},
Line 898: log.registerSink({
Line 902: captureException: () => {},
Line 951: log.registerSink({
Line 955: captureException: () => {},
Line 1159: log.registerSink({
Line 1163: captureException: () => {},
Line 8787: log.registerSink({
Line 8791: captureException: () => {},
Line 9303: log.registerSink({
Line 9307: captureException: () => {},
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/test/openai-responses-recall-aware-stream.test.ts</path>
<type>file</type>
<content>
1: /**
2: * Unit tests for `streamResponsesRecallAware` — the true-streaming,
3: * recall-aware OpenAI Responses (codex/ChatGPT) streamer.
4: *
5: * Regression for the "Provider response headers timed out after 10000ms" issue:
6: * the buffered `accumulateResponsesSSEStream` path withholds ALL client bytes
7: * until the entire (slow, reasoning-heavy) upstream completes, so opencode's
8: * 10s `ProviderHeaderTimeoutError` fired on ChatGPT sessions. This streamer
9: * forwards events live while transparently intercepting a `recall`
10: * function_call (emit marker, run follow-up, rebuild the terminal
11: * `response.completed`).
12: */
13: import { log } from "@loreai/core";
14: import { afterEach, describe, test, expect, vi } from "vitest";
15: import { streamResponsesRecallAware } from "../src/pipeline";
16: ...
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/test/openai-responses-recall-aware-stream.test.ts</path>
<type>file</type>
<content>
8750: completed("resp_allowlisted_principal"),
8751: ]),
8752: {
8753: validation: "codex",
8754: onComplete: (response) => {
8755: completedResponse = response;
8756: },
8757: onRecall: async ({ query }) => ({
8758: anchorText: buildAnchor(query),
8759: resultText: "private recall result",
8760: }),
8761: runFollowUp: async () => ({ reader: followUpBody.getReader() }),
8762: },
8763: );
8764:
8765: const out = await drain(client);
8766: expect(out).toContain("allowlisted answer");
8767: expect(out.match(/^event: response\.completed$/gm)).toHaveLength(1);
8768: expect(out).not.toContain("event: response.custom");
8769: if (testCase.eventSecret) {
8770: ...
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/test/openai-responses-recall-aware-stream.test.ts</path>
<type>file</type>
<content>
9250: test("retains reasoning items in the rebuilt terminal", async () => {
9251: const followUp = streamFrom([
9252: created("resp_followup", "gpt-5.6-terra"),
9253: textItem(0, "answer"),
9254: completed("resp_followup"),
9255: ]);
9256: const client = streamResponsesRecallAware(
9257: streamFrom([
9258: created("resp_reasoning", "gpt-5.6-terra"),
9259: sseEvent("response.output_item.added", {
9260: output_index: 0,
9261: item: { type: "reasoning", id: "rs_0", summary: [] },
9262: }),
9263: recallCall(1, { query: "architecture" }),
9264: sseEvent("response.output_item.done", {
9265: output_index: 0,
9266: item: {
9267: type: "reasoning",
9268: id: "rs_0",
9269: ...
/home/byk/Code/opencode-lore-responses-projection-security/AGENTS.md
RUN v4.1.8 /home/byk/Code/opencode-lore-responses-projection-security
Test Files 1 passed (1)
Tests 34 passed | 200 skipped (234)
Start at 01:14:18
Duration 11.55s (transform 7.10s, setup 1.16s, import 9.36s, tests 667ms, environment 0ms)
Found 3 matches /home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/pipeline.ts: Line 13810: function postResponseForTenant( Line 14178: postResponseForTenant( Line 19428: const persisted = postResponseForTenant(
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/pipeline.ts</path>
<type>file</type>
<content>
13740: const isColdTurn = cacheRead === 0 && cacheCreation > 0;
13741: if (!sessionState.coldCacheWindow) sessionState.coldCacheWindow = [];
13742: sessionState.coldCacheWindow.push(isColdTurn);
13743: if (sessionState.coldCacheWindow.length > 20) {
13744: sessionState.coldCacheWindow.shift();
13745: }
13746: }
13747:
13748: // --- Finalize gen_ai.chat span (after cache analytics enrichment) ---
13749: // Ended here (before recordCacheUsage, matching the original inlined order)
13750: // so the extraction is ordering-identical: recordCacheUsage is pure
13751: // session-state bookkeeping that never touches the span, and ending the span
13752: // first means a throw in recordCacheUsage can't leak an unfinished span.
13753: if (genAiSpan) {
13754: if (endSpan) endSpan();
13755: else genAiSpan.end();
13756: ...
Found 1 matches
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/turn-temporal.ts:
Line 36: export function storeTurnTemporal(input: {
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/turn-temporal.ts</path>
<type>file</type>
<content>
1: import {
2: ensureProject,
3: temporal,
4: withSavepoint,
5: type LoreMessageWithParts,
6: } from "@loreai/core";
7: import { isRecallMarker } from "./recall";
8: import {
9: gatewayMessagesToLore,
10: updateAssistantMessageTokens,
11: } from "./temporal-adapter";
12: import type { GatewayContentBlock, GatewayUsage } from "./translate/types";
13:
14: /** Owned snapshot, captured before tool resolution or gradient mutates history. */
15: export interface TurnTemporalInput {
16: readonly latestUser?: LoreMessageWithParts;
17: /** Absolute request length, even when only one message is retained. */
18: readonly assistantIndex: number;
19: readonly checkpoint?: { claim(): boolean; publish(): void };
20: }
21:
22: export function captureTurnTemporalInput(
23: messages: LoreMessageWithParts[],
24: assistantIndex = ...
Found 2 matches
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/temporal-adapter.ts:
Line 91: case "opaque": {
Line 199: case "opaque":
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/temporal-adapter.ts</path>
<type>file</type>
<content>
65: * Feed content blocks into a hash. Recursive for tool_result sub-blocks.
66: * Every block type — including opaque — contributes to the hash so messages
67: * differing only in image/audio/document content produce distinct IDs
68: * (prevents gradient fingerprint collisions and cache-bust misattribution).
69: */
70: function hashBlocks(
71: h: ReturnType<typeof createHash>,
72: blocks: GatewayContentBlock[],
73: ): void {
74: for (const block of blocks) {
75: switch (block.type) {
76: case "text":
77: h.update(`text:${block.text}`);
78: break;
79: case "thinking":
80: h.update(`thinking:${block.thinking}`);
81: break;
82: case "tool_use":
83: h.update(
84: `tool_use:${block.id}:${block.name}:${JSON.stringify(block.input)}`,
85: );
86: break;
87: ...
No files found
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/index.ts</path>
<type>file</type>
<content>
1: /**
2: * Lore Gateway — package entry point.
3: *
4: * Library exports for programmatic use, plus `runCli()` for the CLI binary.
5: *
6: * Library usage:
7: * import { startServer, loadConfig } from "@loreai/gateway";
8: *
9: * CLI usage (via bin wrapper):
10: * lore start
11: * lore run claude
12: */
13: import "../instrument";
14: import { fileURLToPath } from "node:url";
15:
16: // ---------------------------------------------------------------------------
17: // Library API
18: // ---------------------------------------------------------------------------
19:
20: export { loadConfig, DEFAULT_PORTS, DEFAULT_PORT } from "./config";
21: export type { GatewayConfig } from "./config";
22: export { startServer } from "./server";
23: export { handleRequest, resetPipelineState } from "./pipeline";
24: export { readPortFile } from ...
No files found
Found 100 matches (more matches available)
/home/byk/Code/opencode-lore-responses-projection-security/packages/pi/test/internal.test.ts:
Line 20: captureException: vi.fn(),
Line 24: log.registerSink(silentSink);
Line 275: log.registerSink({
Line 279: captureException: vi.fn(),
Line 300: log.registerSink({
Line 304: captureException: vi.fn(),
Line 317: log.registerSink({
Line 321: captureException: vi.fn(),
Line 392: log.registerSink({
Line 396: captureException: vi.fn(),
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/test/cache-stability.e2e.test.ts:
Line 1982: captureException: () => {},
Line 1988: captureException: () => {},
Line 1990: log.registerSink(captureSink);
Line 2053: log.registerSink(silentSink);
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/instrument.ts:
Line 200: log.registerSink({
Line 204: ...
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/instrument.ts</path>
<type>file</type>
<content>
175: // Drop transient network errors that are not actionable bugs.
176: // Each exception in the chain is tested independently so a real bug
177: // wrapping a transient cause isn't accidentally silenced.
178: beforeSend(event) {
179: if (event.message === "Recall continuation failed") {
180: return isolateRecallContinuationEvent(event);
181: }
182: return eventHasTransientError(event) ? null : scrubTelemetryEvent(event);
183: },
184:
185: // Final boundary: sanitize every envelope item, including payload types
186: // added by future SDK integrations that do not pass through hooks above.
187: transport(options) {
188: return wrapTelemetryTransport(makeTransport(options));
189: },
190: };
191: }
192:
193: if (sentryEnabled && !Sentry.isInitialized()) {
194: ...
Commit ID: ab979df5cddfec3952680e423e39564664e881fe
Change ID: unznwpylspzqykmnpxwnnswmnzpspxzq
Author : Burak Yigit Kaya <ben@byk.im> (2026-09-12 22:22:40)
Committer: Burak Yigit Kaya <ben@byk.im> (2026-09-15 22:20:26)
fix(responses): project hidden output consistently
packages/gateway/src/pipeline.ts | 247 ++++++++++---
...est/openai-responses-recall-aware-stream.test.ts | 395 ++++++++++++++++++++--
2 files changed, 581 insertions(+), 61 deletions(-)
Commit ID: 583020fad43e1481470aac2588251b8636d16251
Change ID: ozrmvotwxzuykyvutstpwpzukpptktxv
Author : Burak Yigit Kaya <ben@byk.im> (2026-09-16 13:14:24)
Committer: Burak Yigit Kaya <ben@byk.im> (2026-09-16 13:43:03)
fix(responses): stabilize sparse principal projection
packages/gateway/src/pipeline.ts | 101 +++++++++++++---------
...est/openai-responses-recall-aware-stream.test.ts | 51 +++++++++++
2 files changed, 112 insertions(+), 40 deletions(-)
Commit ID: ...
Found 15 matches
/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/test/openai-responses-recall-aware-stream.test.ts:
Line 3413: test("rejects terminal omission of added-only provisional reasoning in Codex recall-aware mode", async () => {
Line 3605: test("rejects unfinished reasoning omitted from output_item.done", async () => {
Line 3608: created("resp_summary_unfinished", "gpt-5.6-terra"),
Line 3611: item: { type: "reasoning", id: "rs_summary_unfinished", summary: [] },
Line 3615: item_id: "rs_summary_unfinished",
Line 3621: item: { type: "reasoning", id: "rs_summary_unfinished", summary: [] },
Line 3623: completed("resp_summary_unfinished"),
Line 3637: test("rejects unfinished reasoning when output_item.done omits summary", async () => {
Line 4219: test("accepts reasoning summary prefixes extended by deltas", async () => {
Line 7381: test("does not relabel malformed ...
<path>/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/test/openai-responses-recall-aware-stream.test.ts</path>
<type>file</type>
<content>
3360: },
3361: }),
3362: { headers: { "content-type": "text/event-stream" } },
3363: );
3364: const firstFollowUp = streamFrom([
3365: created("resp_chained_retry_first", "gpt-5.6-terra"),
3366: textItem(0, "first continuation preamble"),
3367: recallCall(1, { query: "second recall" }, "fc_second", "call_second"),
3368: completed("resp_chained_retry_first"),
3369: ]);
3370: const recoveredSecondFollowUp = streamFrom([
3371: created("resp_chained_retry_recovered", "gpt-5.6-terra"),
3372: textItem(0, "chained recovered answer", "msg_chained_retry_recovered"),
3373: completed("resp_chained_retry_recovered"),
3374: ]);
3375: const inputs: string[] = [];
3376: let followUps = 0;
3377: const client = streamResponsesRecallAware(
3378: ...
<path>/tmp/opencode</path> <type>directory</type> <entries> session-recovery-final-v16.patch session-recovery-final-v16/ session-recovery-final-v17.patch session-recovery-final-v17/ session-recovery-final-v18.patch session-recovery-final-v18/ session-recovery-v16-processes.txt session-recovery-v17-processes.txt session-recovery-v18-apply/ session-recovery-v18-processes.txt session-recovery-v18-smoke.mjs (11 entries) </entries>
node:internal/modules/esm/resolve:271
throw new ERR_MODULE_NOT_FOUND(
^
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/node_modules/@loreai/core/dist/node/index.js' imported from /home/byk/Code/opencode-lore-responses-projection-security/packages/gateway/src/turn-temporal.ts
at finalizeResolution (node:internal/modules/esm/resolve:271:11)
at moduleResolve (node:internal/modules/esm/resolve:865:10)
at defaultResolve (node:internal/modules/esm/resolve:992:11)
at #cachedDefaultResolve (node:internal/modules/esm/loader:691:20)
at #resolveAndMaybeBlockOnLoaderThread (node:internal/modules/esm/loader:708:38)
at nextStep (node:internal/modules/customization_hooks:189:26)
at resolveBaseSync (file:///home/byk/Code/opencode-lore-responses-projection-security/node_modules/.pnpm/tsx@4.22.4/node_modules/tsx/dist/register-CqMfTiWi.mjs:2:8745)
at resolveDirectorySync ...
The working copy has no changes. Working copy (@) : muqyuuym 60d399b5 (empty) (no description set) Parent commit (@-): kwmswwmt 6d9f8d6a fix/responses-hidden-output* | fix(responses): sanitize projected output 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. kwmswwmtzlnxuvpkqymrwrxttlwowsys 6d9f8d6a8a1953c655061bd8e37b33c91788d498 parents=f30236708bc928ee2e12739d1de7a7d21871c7d2 conflict=false description=fix(responses): sanitize projected output lnvrxqoqsqutpvpxvnppskkmmmsztwus f30236708bc928ee2e12739d1de7a7d21871c7d2 parents=a3fa555bdcabb376aa33278bdb76007269f1940a conflict=false description=fix(responses): complete hidden-output state pxrvwsvvkmpoxnsqmrkwrnlqvvkoltwz 2cbf40060c67df229731cf1b9e34d5bf22ec2145 parents=e977b4b1da8f8197c3238466d41de0bccd8eb054 conflict=false description=feat(cch): add seeds for Claude Code up to 2.1.272 ...
copyDefinedFields copies allowlisted keys without validating their values (packages/gateway/src/pipeline.ts:8085-8093). Several projectors then copy nested structures wholesale:
tool_search_output.results and additional_tools.tools: pipeline.ts:8388-8393pipeline.ts:8484-8514env: pipeline.ts:8198-8205obfuscation: pipeline.ts:8544-8554The lifecycle validator checks identity and status but does not validate these nested shapes (pipeline.ts:8988-9004).
Attack path: after receiving private recall results, a continuation emits a valid tool_search_output whose results contains private_extension, or an output-text event whose obfuscation is an object containing private data. Projection preserves it, queues it at pipeline.ts:11907-11925, and sends it at pipeline.ts:12259-12263.
The new tests cover unknown top-level fields and one nested web_search_call.action sibling (openai-responses-recall-aware-stream.test.ts:8297-8437), but not known-key type confusion or nested result/output/logprob/annotation fields.
Require strict, type-specific recursive projection or fail closed. Add principal and continuation tests across every nested output family.
onComplete and persistence still receive unprojected datafinish() sanitizes only rawOutputItems and spreads the rest of GatewayResponse unchanged (pipeline.ts:10216-10233).
Two private paths remain:
applyResponsesEvent stores raw message content (stream/openai-responses.ts:644-655). finalizeResponsesAcc places non-text parts into opaque blocks containing the raw item (stream/openai-responses.ts:825-843). Those blocks pass unchanged through visibleResp.content (pipeline.ts:12238-12252), then enter temporal storage (pipeline.ts:13903-13913; turn-temporal.ts:68-83; temporal-adapter.ts:199-209). ...Date: Sep 17, 2026 * 🔴 (00:56) User stated that Jujutsu (`jj`) operations never fail on conflict; conflicts are recorded in the resulting commit and must be detected with `jj st` and resolved manually rather than with interactive `jj resolve`. * 🔴 (00:56) User directed that repositories containing `.jj/` use `jj` rather than `git` for mutations; interactive flags are prohibited, `-m "msg"` is r…
Date: Sep 17, 2026 * 🟡 [requested-security-review] (00:56) User requested an independent immutable security/pentest review in `/home/byk/Code/opencode-lore-responses-projection-security`. * 🔴 (00:56) User identified candidate stable change `kwmswwmtzlnxuvpkqymrwrxttlwowsys`, exact head `6d9f8d6a8a1953c655061bd8e37b33c91788d498`, and base exact commit `2cbf40060c67df229731cf1b9e34d5bf22ec2145`. …