Skip to content

Commit 6190a83

Browse files
V48 (implementation-only): Make typecheck, lint, build, and package tests green
Fix CI failures from logs_79306565646 / logs_79306565630: - btd: extractNeedinesses fail-closed without readonly-array never exhaustiveness - domain: export depositNeedinessSignalSchema; required magnitude/unit; needinesses dep - settle: accept Execution store surface; widen SettleExecutionStore get - generic-asset-packs: Omit base schema literal so product schemas do not collapse to never - uapi: supabaseAdmin is a client (not factory); workspacePath; stream config; dispose holder - domain tests: nested measurements, current agent keys, runtime test bypass at call time - jest: map @bitcode/vcs-generics to packages/vcs-generics Verified: uapi tsc/lint/build; btd + domain + settle + product pack tests.
1 parent 23542c0 commit 6190a83

21 files changed

Lines changed: 943 additions & 559 deletions

File tree

packages/asset-packs-pipelines/domain/jest.config.cjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ module.exports = {
5656
'^@bitcode/logger/(.*)$': '<rootDir>/../../logger/src/$1',
5757
'^@bitcode/tools-generics$': '<rootDir>/../../tools-generics/src/index.ts',
5858
'^@bitcode/tools-generics/(.*)$': '<rootDir>/../../tools-generics/src/$1',
59-
'^@bitcode/vcs-generics$': '<rootDir>/../../vcs/src/index.ts',
60-
'^@bitcode/vcs-generics/(.*)$': '<rootDir>/../../vcs/src/$1',
59+
'^@bitcode/vcs-generics$': '<rootDir>/../../vcs-generics/src/index.ts',
60+
'^@bitcode/vcs-generics/(.*)$': '<rootDir>/../../vcs-generics/src/$1',
6161
'^@bitcode/orm$': '<rootDir>/../../orm/src/index.ts',
6262
'^@bitcode/orm/(.*)$': '<rootDir>/../../orm/src/$1',
6363
'^@bitcode/prompts$': '<rootDir>/../../prompts/src/index.ts',

packages/asset-packs-pipelines/domain/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
"@bitcode/measurement-generics": "workspace:*",
6868
"@bitcode/generic-measurements-measure-agent": "workspace:*",
6969
"@bitcode/generic-measurements-absolutes": "workspace:*",
70+
"@bitcode/generic-measurements-needinesses": "workspace:*",
7071
"@bitcode/asset-packs-generics": "workspace:*",
7172
"@bitcode/generic-asset-packs-synthesis": "workspace:*"
7273
},

packages/asset-packs-pipelines/domain/src/__tests__/deposit-agent-store-contract.test.ts

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,39 @@ function depositSynthesisOption(overrides: Record<string, unknown> = {}) {
6868
summary:
6969
'A bounded, source-safe capability slice covering session authentication and token refresh flows.',
7070
coveredSourcePaths: ['src/auth/session.ts', 'src/auth/token.ts'],
71-
measurements: { 'source-coverage': 0.7, 'demand-alignment': 0.6, 'reuse-likelihood': 0.5 },
71+
// Nested kinds only (deposit: needinesses always empty; host fills absolutes).
72+
measurements: {
73+
absolutes: [
74+
{
75+
measurementKind: 'source-coverage',
76+
label: 'Source coverage',
77+
weight: 0.7,
78+
volume: 0.7,
79+
magnitude: 0.7,
80+
unit: 'normalized',
81+
category: 'absolute' as const,
82+
},
83+
{
84+
measurementKind: 'demand-alignment',
85+
label: 'Demand alignment',
86+
weight: 0.6,
87+
volume: 0.6,
88+
magnitude: 0.6,
89+
unit: 'normalized',
90+
category: 'absolute' as const,
91+
},
92+
{
93+
measurementKind: 'reuse-likelihood',
94+
label: 'Reuse likelihood',
95+
weight: 0.5,
96+
volume: 0.5,
97+
magnitude: 0.5,
98+
unit: 'normalized',
99+
category: 'absolute' as const,
100+
},
101+
],
102+
needinesses: [],
103+
},
72104
measurementRationale: 'Covers both auth modules with moderate demand alignment.',
73105
confidence: 0.8,
74106
patch: {
@@ -78,7 +110,6 @@ function depositSynthesisOption(overrides: Record<string, unknown> = {}) {
78110
],
79111
patchSummary: 'Adds a reusable session/token authentication capability.',
80112
},
81-
needinessSignal: { demand: 0.7, saturation: 0.3, rationale: 'Auth knowledge is frequently read.' },
82113
...overrides,
83114
};
84115
}

packages/asset-packs-pipelines/domain/src/__tests__/deposit-finish-agents.test.ts

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,21 @@ describe('deposit finish agents (store → ledgerize → finish)', () => {
3232
fileChanges: [{ path: 'src/bill.ts', op: 'modify' }],
3333
patchSummary: 'Encodes billing capability.',
3434
},
35-
absolutes: [
36-
{
37-
measurementKind: 'function-count',
38-
label: 'Functions',
39-
weight: 0.12,
40-
volume: 0.5,
41-
category: 'absolute',
42-
},
43-
],
35+
// Nested kinds only — AssetPack = patch + measurements + metadata.
36+
measurements: {
37+
absolutes: [
38+
{
39+
measurementKind: 'function-count',
40+
label: 'Functions',
41+
weight: 0.12,
42+
volume: 0.5,
43+
magnitude: 0.5,
44+
unit: 'normalized',
45+
category: 'absolute' as const,
46+
},
47+
],
48+
needinesses: [],
49+
},
4450
},
4551
];
4652

@@ -99,7 +105,8 @@ describe('deposit finish agents (store → ledgerize → finish)', () => {
99105
const envelope = exec.get('finish', 'selectionEnvelope');
100106
expect(envelope.options).toHaveLength(1);
101107
expect(envelope.options[0].patch).toBeTruthy();
102-
expect(envelope.options[0].measurements).toHaveLength(1);
108+
expect(envelope.options[0].measurements?.absolutes).toHaveLength(1);
109+
expect(envelope.options[0].measurements?.needinesses).toEqual([]);
103110
expect(exec.get('finish', 'completion')?.cleanup?.disposeRecommended).toBeDefined();
104111
});
105112
});

packages/asset-packs-pipelines/domain/src/__tests__/deposit-sdivf-pipeline-integration.test.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -202,11 +202,13 @@ describe('deposit SDIVF pipeline integration (boundary-mocked LLMs)', () => {
202202
expect(options[0].title).toMatch(/auth/i);
203203
expect(options[0].patch?.fileChanges?.length).toBeGreaterThan(0);
204204

205-
// Validation measure-agent attaches formal absolutes in place.
206-
expect(Array.isArray(options[0].absolutes)).toBe(true);
207-
expect(options[0].absolutes.length).toBeGreaterThan(0);
205+
// Validation measure-agent attaches formal absolutes in place (nested kinds).
206+
const absolutes =
207+
options[0].measurements?.absolutes ?? options[0].absolutes ?? [];
208+
expect(Array.isArray(absolutes)).toBe(true);
209+
expect(absolutes.length).toBeGreaterThan(0);
208210
expect(
209-
options[0].absolutes.some((m) => m.measurementKind === 'function-count'),
211+
absolutes.some((m) => m.measurementKind === 'function-count'),
210212
).toBe(true);
211213

212214
// Product projection must accept formal absolutes (no placeholder fallback).
Lines changed: 156 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,44 @@
11
// @ts-nocheck
2+
/**
3+
* Bring-up: setup phase streaming + structured DB inserts (phase/agent rows).
4+
* Opt-in setup runtime under NODE_ENV=test; boundary agents mocked offline.
5+
*/
26
import assetPack from '../index';
37
import { Execution } from '@bitcode/execution-generics';
48
import { enablePipelineStreaming } from '@bitcode/pipelines-generics';
59

6-
// Mock setup agents to ensure deterministic, fast dry-run
7-
jest.mock('../agents/setup/asset-pack-clone-vcs-repository-agent', () => ({ __esModule: true, default: jest.fn().mockResolvedValue({ success: true, repository: { owner: 'acme', name: 'repo', ref: 'main' } }) }));
8-
jest.mock('../agents/setup/read-fits-finding-synthesis-read-comprehension-agent', () => ({ __esModule: true, default: jest.fn().mockResolvedValue({ success: true }) }));
9-
jest.mock('../agents/setup/asset-pack-danger-wall-agent', () => ({
10+
// Mock setup agents to ensure deterministic, fast dry-run (read Setup roster).
11+
jest.mock('../agents/setup/asset-pack-clone-vcs-repository-agent', () => ({
12+
__esModule: true,
13+
default: jest.fn().mockResolvedValue({
14+
success: true,
15+
repository: { owner: 'acme', name: 'repo', ref: 'main' },
16+
}),
17+
}));
18+
jest.mock('../agents/setup/asset-pack-initialize-lsp-agent', () => ({
19+
__esModule: true,
20+
default: jest.fn().mockResolvedValue({ success: true, lsp: { available: false } }),
21+
}));
22+
jest.mock('../agents/setup/asset-pack-initialize-mcps-tools-agent', () => ({
23+
__esModule: true,
24+
default: jest.fn().mockResolvedValue({ success: true, active: {}, initialized: [] }),
25+
}));
26+
jest.mock('../agents/setup/read-need-comprehension-agent', () => ({
27+
__esModule: true,
28+
default: jest.fn().mockResolvedValue({ success: true, summary: 'test need' }),
29+
}));
30+
jest.mock('../agents/setup/read-danger-wall-agent', () => ({
31+
__esModule: true,
32+
default: jest.fn().mockResolvedValue({
33+
finalAssessment: {
34+
safe: true,
35+
maxSeverity: 'low',
36+
confidence: 1,
37+
verdict: { reason: 'test-safe', flags: [] },
38+
},
39+
}),
40+
}));
41+
jest.mock('../agents/setup/deposit-danger-wall-agent', () => ({
1042
__esModule: true,
1143
default: jest.fn().mockResolvedValue({
1244
finalAssessment: {
@@ -17,97 +49,134 @@ jest.mock('../agents/setup/asset-pack-danger-wall-agent', () => ({
1749
},
1850
}),
1951
}));
52+
jest.mock('../agents/setup/read-fits-finding-synthesis-read-comprehension-agent', () => ({
53+
__esModule: true,
54+
default: jest.fn().mockResolvedValue({ success: true }),
55+
}));
2056

2157
describe('AssetPack pipeline bring-up (setup + PTRR plan: prepare→reason)', () => {
22-
it('streams phase/agent events and persists structured rows', async () => {
23-
process.env.BITCODE_DEBUG_ONLY_FAILSAFES = 'prepare';
24-
process.env.BITCODE_DEBUG_ONLY_GENERATIONS = 'reason';
25-
process.env.BITCODE_ENABLE_ASSET_PACK_SETUP_PHASE_RUNTIME_IN_TEST = '1';
58+
it(
59+
'streams phase/agent events and persists structured rows',
60+
async () => {
61+
process.env.BITCODE_DEBUG_ONLY_FAILSAFES = 'prepare';
62+
process.env.BITCODE_DEBUG_ONLY_GENERATIONS = 'reason';
63+
process.env.BITCODE_ENABLE_ASSET_PACK_SETUP_PHASE_RUNTIME_IN_TEST = '1';
2664

27-
try {
28-
const exec = new Execution('asset-pack:test');
29-
const inserts: any[] = [];
30-
const selectedRows = (table: string, filters: Array<[string, any]>) => {
31-
return inserts
32-
.filter((insert) => insert.table === table)
33-
.map((insert) => insert.row)
34-
.filter((row) => filters.every(([column, value]) => row?.[column] === value));
35-
};
36-
const selectBuilder = (table: string) => {
37-
const filters: Array<[string, any]> = [];
38-
const builder: any = {
39-
eq: (column: string, value: any) => {
40-
filters.push([column, value]);
41-
return builder;
42-
},
43-
order: () => builder,
44-
limit: () => builder,
45-
maybeSingle: async () => ({ data: selectedRows(table, filters).at(-1) || null }),
46-
then: (resolve: any) => Promise.resolve({ data: selectedRows(table, filters), error: null }).then(resolve),
65+
try {
66+
const exec = new Execution('asset-pack:test');
67+
const inserts: any[] = [];
68+
const selectedRows = (table: string, filters: Array<[string, any]>) => {
69+
return inserts
70+
.filter((insert) => insert.table === table)
71+
.map((insert) => insert.row)
72+
.filter((row) => filters.every(([column, value]) => row?.[column] === value));
73+
};
74+
const selectBuilder = (table: string) => {
75+
const filters: Array<[string, any]> = [];
76+
const builder: any = {
77+
eq: (column: string, value: any) => {
78+
filters.push([column, value]);
79+
return builder;
80+
},
81+
order: () => builder,
82+
limit: () => builder,
83+
maybeSingle: async () => ({ data: selectedRows(table, filters).at(-1) || null }),
84+
then: (resolve: any) =>
85+
Promise.resolve({ data: selectedRows(table, filters), error: null }).then(resolve),
86+
};
87+
return builder;
4788
};
48-
return builder;
49-
};
50-
const updateBuilder = (table: string, patch: any) => {
51-
const filters: Array<(row: any) => boolean> = [];
52-
const apply = async () => {
53-
const rows = inserts.filter((insert) => insert.table === table).map((insert) => insert.row);
54-
for (const row of rows) {
55-
if (filters.every((filter) => filter(row))) Object.assign(row, patch);
56-
}
57-
return { data: rows.filter((row) => filters.every((filter) => filter(row))), error: null };
89+
const updateBuilder = (table: string, patch: any) => {
90+
const filters: Array<(row: any) => boolean> = [];
91+
const apply = async () => {
92+
const rows = inserts
93+
.filter((insert) => insert.table === table)
94+
.map((insert) => insert.row);
95+
for (const row of rows) {
96+
if (filters.every((filter) => filter(row))) Object.assign(row, patch);
97+
}
98+
return {
99+
data: rows.filter((row) => filters.every((filter) => filter(row))),
100+
error: null,
101+
};
102+
};
103+
const builder: any = {
104+
eq: (column: string, value: any) => {
105+
filters.push((row) => row?.[column] === value);
106+
return builder;
107+
},
108+
in: (column: string, values: any[]) => {
109+
filters.push((row) => values.includes(row?.[column]));
110+
return builder;
111+
},
112+
then: (resolve: any) => apply().then(resolve),
113+
};
114+
return builder;
58115
};
59-
const builder: any = {
60-
eq: (column: string, value: any) => {
61-
filters.push((row) => row?.[column] === value);
62-
return builder;
63-
},
64-
in: (column: string, values: any[]) => {
65-
filters.push((row) => values.includes(row?.[column]));
66-
return builder;
116+
const supabaseStub: any = {
117+
from(table: string) {
118+
return {
119+
insert: (row: any) => {
120+
inserts.push({ table, row });
121+
return {
122+
select: (_?: any) => ({
123+
single: () =>
124+
Promise.resolve({ data: { id: 'id-' + inserts.length } }),
125+
}),
126+
} as any;
127+
},
128+
update: (patch: any) => updateBuilder(table, patch),
129+
select: () => selectBuilder(table),
130+
} as any;
67131
},
68-
then: (resolve: any) => apply().then(resolve),
69132
};
70-
return builder;
71-
};
72-
const supabaseStub: any = {
73-
from(table: string) {
74-
return {
75-
insert: (row: any) => {
76-
inserts.push({ table, row });
77-
return { select: (_?: any) => ({ single: () => Promise.resolve({ data: { id: 'id-' + inserts.length } }) }) } as any;
78-
},
79-
update: (patch: any) => updateBuilder(table, patch),
80-
select: () => selectBuilder(table),
81-
} as any;
82-
}
83-
};
84-
enablePipelineStreaming(exec as any, {
85-
runId: '33333333-3333-4333-8333-333333333333',
86-
userId: '44444444-4444-4444-8444-444444444444',
87-
supabase: supabaseStub,
88-
streamToDatabase: true,
89-
structuredToDatabase: true,
90-
});
133+
const streamer = enablePipelineStreaming(exec as any, {
134+
runId: '33333333-3333-4333-8333-333333333333',
135+
userId: '44444444-4444-4444-8444-444444444444',
136+
supabase: supabaseStub,
137+
streamToDatabase: true,
138+
structuredToDatabase: true,
139+
});
140+
141+
const res = await assetPack(
142+
{
143+
definitionOfRead: 'Test',
144+
repository: { url: 'x' },
145+
deliveryTarget: 'pr' as const,
146+
},
147+
exec,
148+
);
91149

92-
const res = await assetPack({
93-
definitionOfRead: 'Test',
94-
repository: { url: 'x' },
95-
deliveryTarget: 'pr' as const,
96-
}, exec);
150+
// Drain async structured write queue before asserting inserts.
151+
await (streamer as any).flushStructuredWrites?.();
152+
await new Promise((r) => setImmediate(r));
97153

98-
expect(res).toBeDefined();
154+
expect(res).toBeDefined();
99155

100-
// Structured inserts occurred
101-
const phaseRows = inserts.filter(i => i.table === 'deliverable_pipeline_phase_delegations');
102-
expect(phaseRows.length).toBeGreaterThanOrEqual(1);
103-
expect(
104-
phaseRows.some((row) => row.row.phase_name === 'setup' || row.row.phase === 'setup')
105-
).toBe(true);
106-
const agentRows = inserts.filter(i => i.table === 'deliverable_pipeline_agent_steps');
107-
expect(agentRows.length).toBeGreaterThanOrEqual(1);
108-
expect(agentRows.some(r => String(r.row.agent_name || '').startsWith('setup:'))).toBe(true);
109-
} finally {
110-
delete process.env.BITCODE_ENABLE_ASSET_PACK_SETUP_PHASE_RUNTIME_IN_TEST;
111-
}
112-
});
156+
// Structured inserts occurred (runs + phases + agents).
157+
expect(
158+
inserts.some((i) => i.table === 'deliverable_pipeline_runs'),
159+
).toBe(true);
160+
const phaseRows = inserts.filter(
161+
(i) => i.table === 'deliverable_pipeline_phase_delegations',
162+
);
163+
expect(phaseRows.length).toBeGreaterThanOrEqual(1);
164+
expect(
165+
phaseRows.some(
166+
(row) => row.row.phase_name === 'setup' || row.row.phase === 'setup',
167+
),
168+
).toBe(true);
169+
const agentRows = inserts.filter(
170+
(i) => i.table === 'deliverable_pipeline_agent_steps',
171+
);
172+
expect(agentRows.length).toBeGreaterThanOrEqual(1);
173+
expect(
174+
agentRows.some((r) => String(r.row.agent_name || '').startsWith('setup:')),
175+
).toBe(true);
176+
} finally {
177+
delete process.env.BITCODE_ENABLE_ASSET_PACK_SETUP_PHASE_RUNTIME_IN_TEST;
178+
}
179+
},
180+
30000,
181+
);
113182
});

0 commit comments

Comments
 (0)