Skip to content

Commit 38690c9

Browse files
V48 Gate 3: Run AssetPacksSynthesis through the formal pipeline (retire the hand-rolled inference)
synthesizeAssetPackCandidates now delegates inference to synthesizeAssetPackCandidatesFormal (the real PipelineExecution -> factoryAgent -> Failsafe of Thricified spine) instead of runBoundedStructuredInference. This module keeps what it owns: the deposit/read lens contract, the candidate schema, fail-closed exclusion/path validation, measurement-catalog mapping, and inference accounting. - request.execution is now a real execution-generics Execution (the deposit route's streaming Execution); a detached root Execution is created when absent. SourceSafeStreamTarget and the in-module usage-recorder / source-safe-summary bridge are retired — telemetry source-safety is now the universal streaming filter (chunk A). - Added assertSourceSafeCandidates: defense-in-depth local source-safety assertion (Garrett's 'keep local assert') that fails closed if any candidate's prose carries a verbatim source line (>= 40 chars) from the excerpts. - deposit-option-real-synthesis adapter + route status wording updated; synthesis test repoints its mock from bounded-structured-inference to asset-packs-synthesis-pipeline (5/5 green). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 008180a commit 38690c9

4 files changed

Lines changed: 108 additions & 190 deletions

File tree

packages/pipelines/asset-pack/src/__tests__/asset-packs-synthesis.test.ts

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
jest.mock('../bounded-structured-inference', () => ({
2-
runBoundedStructuredInference: jest.fn(),
1+
jest.mock('../asset-packs-synthesis-pipeline', () => ({
2+
synthesizeAssetPackCandidatesFormal: jest.fn(),
33
}));
44
jest.mock('../runtime-inference-policy', () => ({
55
isAssetPackRealInferenceEnabled: jest.fn(() => true),
66
}));
77

8-
import { runBoundedStructuredInference } from '../bounded-structured-inference';
8+
import { synthesizeAssetPackCandidatesFormal } from '../asset-packs-synthesis-pipeline';
99
import {
1010
applyExclusionsToInventory,
1111
isPathExcluded,
@@ -16,7 +16,16 @@ import {
1616
import { buildRealDepositAssetPackOptionSynthesis } from '../deposit-option-real-synthesis';
1717
import { assertDepositAssetPackOptionSynthesisSourceSafe } from '../deposit-asset-pack-options';
1818

19-
const mockInference = runBoundedStructuredInference as jest.Mock;
19+
// The formal pipeline (PipelineExecution → factoryAgent → Failsafe ∘ Thricified)
20+
// is mocked here; its own correctness is covered by the agent-generics suites.
21+
// These tests cover the lens contract + fail-closed validation this module owns.
22+
const mockInference = synthesizeAssetPackCandidatesFormal as jest.Mock;
23+
const inferenceOutcome = (options: unknown[]) => ({
24+
options,
25+
provider: 'anthropic',
26+
model: 'claude-sonnet-4-6',
27+
totalTokens: 1234,
28+
});
2029

2130
const INVENTORY = {
2231
paths: ['README.md', 'src/app.py', 'src/utils.py', 'secret/keys.py'],
@@ -63,7 +72,7 @@ describe('AssetPacksSynthesis core', () => {
6372
});
6473

6574
it('maps inference candidates through the lens measurement catalog', async () => {
66-
mockInference.mockResolvedValue({ options: [inferenceCandidate()] });
75+
mockInference.mockResolvedValue(inferenceOutcome([inferenceCandidate()]));
6776

6877
const result = await synthesizeAssetPackCandidates({
6978
lens: 'deposit',
@@ -86,13 +95,13 @@ describe('AssetPacksSynthesis core', () => {
8695
});
8796

8897
it('drops candidates that violate exclusions or reference unknown paths, fail-closed', async () => {
89-
mockInference.mockResolvedValue({
90-
options: [
98+
mockInference.mockResolvedValue(
99+
inferenceOutcome([
91100
inferenceCandidate(),
92101
inferenceCandidate({ title: 'Violates exclusion boundary now', coveredSourcePaths: ['secret/keys.py'] }),
93102
inferenceCandidate({ title: 'References unknown paths now', coveredSourcePaths: ['made/up.py'] }),
94-
],
95-
});
103+
]),
104+
);
96105

97106
const result = await synthesizeAssetPackCandidates({
98107
lens: 'deposit',
@@ -110,9 +119,9 @@ describe('AssetPacksSynthesis core', () => {
110119
});
111120

112121
it('throws when no admissible candidates survive', async () => {
113-
mockInference.mockResolvedValue({
114-
options: [inferenceCandidate({ coveredSourcePaths: ['secret/keys.py'] })],
115-
});
122+
mockInference.mockResolvedValue(
123+
inferenceOutcome([inferenceCandidate({ coveredSourcePaths: ['secret/keys.py'] })]),
124+
);
116125

117126
await expect(
118127
synthesizeAssetPackCandidates({
@@ -134,7 +143,7 @@ describe('deposit lens adapter', () => {
134143
});
135144

136145
it('builds a law-compatible synthesis with real measurements and exclusion posture', async () => {
137-
mockInference.mockResolvedValue({ options: [inferenceCandidate()] });
146+
mockInference.mockResolvedValue(inferenceOutcome([inferenceCandidate()]));
138147
const inventory = { ...INVENTORY, totalPathCount: 4, excludedPathCount: 1 };
139148
const result = await synthesizeAssetPackCandidates({
140149
lens: 'deposit',

0 commit comments

Comments
 (0)