Skip to content

Commit 1e2f89e

Browse files
V48 Gate 3 (implementation-only): withhold PCC's selectedContext read-in — it re-carries verbatim inventory source
Found live on run 59504a3e (the first run with working key selection): the context:selectedContext store re-carries the resolved VALUES of the selected keys, and when the selection includes deposit#inventory that is the verbatim source inventory — streamed unwithheld into execution_events while deposit:inventory itself was withheld. The context namespace's value-bearing keys (selectedContext, legacy full) join the withholding allowlist; the key-NAME stores (keys/selectedKeys/missingKeys) stay visible. Regression-pinned with the exact live leak shape. Streaming suite 40 green; tsc clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 37ef59f commit 1e2f89e

2 files changed

Lines changed: 31 additions & 0 deletions

File tree

packages/pipelines-generics/src/streaming/__tests__/pipeline-stream-integration.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,32 @@ describe('sourceSafeStreamEvent — non-llm content-bearing stores (deposit inve
286286
expect(JSON.stringify(safe)).not.toContain('INVENTORY-SOURCE-MARKER');
287287
});
288288

289+
it('withholds context:selectedContext (PCC read-in re-carries resolved values incl. the inventory — live leak, run 59504a3e)', () => {
290+
const safe = sourceSafeStreamEvent({
291+
type: 'status',
292+
namespace: 'context',
293+
key: 'selectedContext',
294+
data: {
295+
'deposit#inventory': {
296+
sources: [{ path: 'src/secret.ts', content: SOURCE_LINE }],
297+
},
298+
'deposit#obfuscations': 'guidance text',
299+
},
300+
});
301+
expect(safe.data.contentWithheld).toBe(true);
302+
expect(JSON.stringify(safe)).not.toContain('INVENTORY-SOURCE-MARKER');
303+
});
304+
305+
it('passes through the key-NAME context stores (keys/selectedKeys/missingKeys are source-safe)', () => {
306+
const selectedKeys = {
307+
type: 'status',
308+
namespace: 'context',
309+
key: 'selectedKeys',
310+
data: ['deposit#obfuscations', 'deposit#inventory'],
311+
};
312+
expect(sourceSafeStreamEvent(selectedKeys)).toBe(selectedKeys);
313+
});
314+
289315
it('passes through OTHER pipeline/deposit metadata keys unchanged (allowlist is key-scoped)', () => {
290316
const pattern = { type: 'status', namespace: 'pipeline', key: 'pattern', data: 'SDIVF' };
291317
expect(sourceSafeStreamEvent(pattern)).toBe(pattern);

packages/pipelines-generics/src/streaming/pipeline-stream-integration.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ const SOURCE_CONTENT_BEARING_KEYS_BY_NAMESPACE: Record<string, Set<string>> = {
7070
deposit: new Set(['inventory']),
7171
tool: new Set(['input', 'result']),
7272
tools: new Set(['invocation', 'result']),
73+
// PCC's read-in re-carries the resolved VALUES of the selected keys — when
74+
// the selection includes the inventory, selectedContext holds verbatim
75+
// source (observed live, run 59504a3e). context:keys/selectedKeys/
76+
// missingKeys stay visible: key NAMES are source-safe.
77+
context: new Set(['selectedContext', 'full']),
7378
};
7479

7580
export function sourceSafeStreamEvent(event: any): any {

0 commit comments

Comments
 (0)