Skip to content

Commit 6ea0619

Browse files
Merge pull request #216 from engineeredsoftware/v45/gate-13-btd-scalar-volume-quote-conservation
V45 Gate 13: Deterministic BTD Quote Conservation
2 parents 2d738e3 + 6443630 commit 6ea0619

7 files changed

Lines changed: 1279 additions & 0 deletions

File tree

BITCODE_SPEC_V45_PARITY_MATRIX.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,13 @@ Acceptance:
144144
- Source-to-shares conservation remains exact for one and many selected Fits.
145145
- `check:v45-gate13` passes locally and in gate-quality CI.
146146

147+
Gate 13 implementation readback:
148+
149+
- Deterministic BTD scalar-volume and quote conservation bridge: `packages/pipelines/asset-pack/src/btd-scalar-volume-quote.ts`.
150+
- Final-BTD blocker coverage and one/many Fit source-to-shares conservation coverage: `packages/pipelines/asset-pack/src/__tests__/btd-scalar-volume-quote.test.ts`.
151+
- Package export binding: `packages/pipelines/asset-pack/package.json` and `packages/pipelines/asset-pack/src/index.ts`.
152+
- Closure checker: `check:v45-gate13`.
153+
147154
### Gate 14: BTC Settlement Rights Delivery And Compensation Readback
148155

149156
Gate class: `implementation`.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@
398398
"check:v45-gate10": "node scripts/check-v45-gate10-formal-spec-consolidation.mjs",
399399
"check:v45-gate11": "node scripts/check-v45-gate11-implementation-parity-audit.mjs",
400400
"check:v45-gate12": "node scripts/check-v45-gate12-state-vocabulary-commodity-model.mjs",
401+
"check:v45-gate13": "node scripts/check-v45-gate13-btd-scalar-volume-quote-conservation.mjs",
401402
"generate:v38-inference-surface-inventory": "node scripts/generate-v38-inference-surface-inventory.mjs",
402403
"check:v38-inference-surface-inventory": "node scripts/generate-v38-inference-surface-inventory.mjs --check",
403404
"check:v38-gate2": "node scripts/check-v38-gate2-inference-surface-inventory.mjs",

packages/pipelines/asset-pack/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"./depositor-earning-supply-intelligence": "./src/depositor-earning-supply-intelligence.ts",
1919
"./btd-btc-compensation-statements": "./src/btd-btc-compensation-statements.ts",
2020
"./asset-pack-commodity-state": "./src/asset-pack-commodity-state.ts",
21+
"./btd-scalar-volume-quote": "./src/btd-scalar-volume-quote.ts",
2122
"./organization-policy-wallet-authority": "./src/organization-policy-wallet-authority.ts",
2223
"./read-need": "./src/read-need.ts",
2324
"./read-need-review-resynthesis": "./src/read-need-review-resynthesis.ts",
Lines changed: 367 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,367 @@
1+
import {
2+
assertFinalBtdScalarVolumeAdmissible,
3+
buildBtdScalarVolumeQuoteConservation,
4+
type BtdScalarVolumeSelectedFitInput,
5+
} from '../btd-scalar-volume-quote';
6+
import {
7+
acceptReadNeed,
8+
buildAssetPackSourceSafePreview,
9+
buildShareToFeePreview,
10+
synthesizeReadNeedForPipelineInput,
11+
type AssetPackSourceSafePreview,
12+
type ReadNeed,
13+
type ReadNeedMeasurementDimension,
14+
} from '../read-need';
15+
import type { DepositoryFitResultEvidence } from '../depository-search';
16+
17+
const input = {
18+
read: {
19+
id: 'read-btd-scalar-volume-1',
20+
prompt:
21+
'Find source-bound implementation knowledge that can improve the repository Reading path, proof readback, BTC settlement, and AssetPack delivery.',
22+
},
23+
sourceRevision: {
24+
repositoryFullName: 'engineeredsoftware/ENGI',
25+
branch: 'main',
26+
commit: '31bbc0c5227b6b3aed5d107fd8507d35ec22970a',
27+
},
28+
};
29+
30+
function acceptedNeed(): ReadNeed {
31+
return acceptReadNeed(
32+
synthesizeReadNeedForPipelineInput(input),
33+
'2026-05-31T00:00:00.000Z',
34+
);
35+
}
36+
37+
function fitResult(
38+
fits: Array<{ assetId: string; finalScore: number; semanticScore?: number }>,
39+
): DepositoryFitResultEvidence {
40+
const selectedCandidates = fits.map((fit, index) => ({
41+
assetId: fit.assetId,
42+
title: `Depository AssetPack ${fit.assetId}`,
43+
artifactKind: 'asset-pack',
44+
useTier: 'settlement-eligible' as const,
45+
sourceBinding: {
46+
repositoryFullName: 'engineeredsoftware/ENGI',
47+
sourceBranch: 'main',
48+
sourceCommit: '31bbc0c5227b6b3aed5d107fd8507d35ec22970a',
49+
contentRoot: `sha256:content-${fit.assetId}`,
50+
},
51+
selectedUnits: [],
52+
scores: {
53+
finalScore: fit.finalScore,
54+
semanticScore: fit.semanticScore ?? fit.finalScore,
55+
textScore: 0.8,
56+
unitScore: 0.8,
57+
repositoryScore: 1,
58+
revisionScore: 1,
59+
artifactKindScore: 1,
60+
proofScore: 1,
61+
measurementScore: 1,
62+
providerScore: 0,
63+
penaltyMass: 0,
64+
},
65+
verification: {
66+
repositoryBound: true,
67+
sourceRevisionBound: true,
68+
hasWalletOrAttestationProof: true,
69+
hasAssetMeasurementEvidence: true,
70+
proofRootRequired: true,
71+
proofRootPresent: true,
72+
reconciliationReadbackRequired: true,
73+
reconciliationReadbackPresent: true,
74+
blockers: [],
75+
warnings: [],
76+
},
77+
recall: {
78+
matchedTerms: ['assetpack', 'proof', 'settlement'],
79+
matchedTargetKinds: ['asset-pack'],
80+
matchedUnitIds: [`unit-${index + 1}`],
81+
providerMatchCount: 1,
82+
providerIds: ['test-provider'],
83+
},
84+
proofEvidence: {
85+
hasWalletOrAttestationProof: true,
86+
attestationCount: 1,
87+
signingSurfacePresent: true,
88+
identitySurfacePresent: true,
89+
githubBoundaryPresent: true,
90+
githubAppAuthSurfacePresent: true,
91+
proofRoot: `sha256:proof-${fit.assetId}`,
92+
},
93+
measurementEvidence: {
94+
hasAssetMeasurementEvidence: true,
95+
assetMeasurementPresent: true,
96+
measurementProvenanceCount: 1,
97+
measurementRoot: `sha256:measurement-${fit.assetId}`,
98+
},
99+
readbackEvidence: {
100+
proofRootRequired: true,
101+
proofRootPresent: true,
102+
reconciliationReadbackRequired: true,
103+
reconciliationReadbackPresent: true,
104+
reconciliationReadbackRoot: `sha256:readback-${fit.assetId}`,
105+
},
106+
rejectionReasons: [],
107+
}));
108+
109+
return {
110+
schema: 'bitcode.asset-pack.fit-result',
111+
resultState: 'worthy_fit',
112+
resultReasons: ['Selected source-safe Depository AssetPacks exceed the worthy-fit threshold.'],
113+
fitDepositAssetIds: fits.map((fit) => fit.assetId),
114+
selectedCandidateAssetIds: fits.map((fit) => fit.assetId),
115+
queryRoot: 'sha256:query-root',
116+
rankingRoot: `sha256:ranking-${fits.map((fit) => fit.assetId).join('-')}`,
117+
searchedAssetCount: fits.length,
118+
embeddingPolicy: { provider: 'test' },
119+
selectionTrace: {
120+
selectedCandidates,
121+
fitDeposits: selectedCandidates,
122+
blockedCandidates: [],
123+
candidateRanking: selectedCandidates,
124+
rejectedCandidateCount: 0,
125+
},
126+
} as unknown as DepositoryFitResultEvidence;
127+
}
128+
129+
function previewFor(
130+
need: ReadNeed,
131+
fits: Array<{ assetId: string; finalScore: number }>,
132+
): AssetPackSourceSafePreview {
133+
return buildAssetPackSourceSafePreview({
134+
need,
135+
fitResult: fitResult(fits),
136+
rangeStart: 50_000,
137+
pullRequestTarget: 'https://github.com/engineeredsoftware/ENGI/pull/4500',
138+
createdAt: '2026-05-31T00:00:00.000Z',
139+
});
140+
}
141+
142+
function selectedFit(
143+
assetId: string,
144+
units: number,
145+
fitQualityBps: number,
146+
): BtdScalarVolumeSelectedFitInput {
147+
return {
148+
depositId: assetId,
149+
assetId,
150+
assetPackId: `depository-${assetId}`,
151+
depositorWalletId: `depositor-wallet-${assetId}`,
152+
sourceManifestRoot: `sha256:source-${assetId}`,
153+
measurementRoot: `sha256:measurement-${assetId}`,
154+
normalizedMeasurementUnits: units,
155+
fitQualityBps,
156+
provenanceBps: 10_000,
157+
accepted: true,
158+
};
159+
}
160+
161+
describe('BTD scalar volume and deterministic quote conservation', () => {
162+
it('computes final Need-relative BTD scalar volume with conserved quote and one selected Fit', () => {
163+
const need = acceptedNeed();
164+
const preview = previewFor(need, [{ assetId: 'fit-a', finalScore: 0.82 }]);
165+
const projection = buildBtdScalarVolumeQuoteConservation({
166+
acceptedNeed: need,
167+
sourceSafePreview: preview,
168+
selectedFits: [selectedFit('fit-a', 820, 8200)],
169+
issuedAt: '2026-05-31T00:00:00.000Z',
170+
});
171+
172+
expect(projection.schema).toBe('bitcode.btd.scalar-volume.quote-conservation');
173+
expect(projection.state).toBe('final_btd_scalar_volume_admissible');
174+
expect(projection.blockers).toEqual([]);
175+
expect(projection.depositPotential).toMatchObject({
176+
state: 'estimate_only_before_need_fit',
177+
measurementRoot: need.measurementRoot,
178+
});
179+
expect(projection.measurementWeightPolicy).toMatchObject({
180+
policyId: 'need-relative-fixed-point-weighted-volume',
181+
arithmetic: 'fixed-point-integer',
182+
rounding: 'floor-row-remainder-rooted',
183+
requiredWeightBpsTotal: 10_000,
184+
});
185+
expect(projection.measurementRows).toHaveLength(
186+
need.pricingMeasurementInputs.measurementVector.length,
187+
);
188+
expect(projection.quote).toMatchObject({
189+
quoteRoot: preview.feeQuote.quoteRoot,
190+
quoteSats: preview.feeQuote.sats,
191+
expectedSats: preview.feeQuote.sats,
192+
quoteConserved: true,
193+
});
194+
expect(projection.rangeProjection).toMatchObject({
195+
tokenCount: preview.rangeProjection.tokenCount,
196+
conservedWithScalarVolume: true,
197+
});
198+
expect(projection.sourceToShares?.proof.fitDeposits).toHaveLength(1);
199+
expect(projection.sourceToShares).toMatchObject({
200+
sourceToSharesConserved: true,
201+
grossSats: String(preview.feeQuote.sats),
202+
allocatedSats: String(preview.feeQuote.sats),
203+
});
204+
expect(assertFinalBtdScalarVolumeAdmissible(projection)).toBe(projection);
205+
});
206+
207+
it('conserves source-to-shares settlement sats and BTD range slices across many selected Fits', () => {
208+
const need = acceptedNeed();
209+
const preview = previewFor(need, [
210+
{ assetId: 'fit-a', finalScore: 0.82 },
211+
{ assetId: 'fit-b', finalScore: 0.74 },
212+
]);
213+
const projection = buildBtdScalarVolumeQuoteConservation({
214+
acceptedNeed: need,
215+
sourceSafePreview: preview,
216+
selectedFits: [
217+
selectedFit('fit-a', 820, 8200),
218+
selectedFit('fit-b', 740, 7400),
219+
],
220+
issuedAt: '2026-05-31T00:00:00.000Z',
221+
});
222+
223+
assertFinalBtdScalarVolumeAdmissible(projection);
224+
const proof = projection.sourceToShares!.proof;
225+
const shareTotal = proof.contributionWeights.reduce((sum, weight) => sum + weight.shareBps, 0);
226+
const allocatedSats = proof.settlementAllocations.reduce(
227+
(sum, allocation) => sum + allocation.allocatedSats,
228+
0n,
229+
);
230+
const allocatedTokenCount = proof.rangeSlices.reduce((sum, slice) => sum + slice.tokenCount, 0);
231+
232+
expect(proof.fitDeposits).toHaveLength(2);
233+
expect(shareTotal).toBe(10_000);
234+
expect(allocatedSats).toBe(proof.feeQuote.grossSats);
235+
expect(allocatedTokenCount).toBe(proof.zeroCellRefitTail.rangeTokenCount);
236+
expect(proof.settlementConservation.state).toBe('balanced');
237+
expect(proof.settlementAllocations.map((allocation) => allocation.depositId)).toEqual([
238+
'fit-a',
239+
'fit-b',
240+
]);
241+
});
242+
243+
it('blocks final BTD when reviewed Need, selected Fit set, synthesized AssetPack, proof roots, deterministic weights, range, or quote are missing', () => {
244+
const need = acceptedNeed();
245+
const preview = previewFor(need, [{ assetId: 'fit-a', finalScore: 0.82 }]);
246+
const unreviewedNeed = synthesizeReadNeedForPipelineInput(input);
247+
const malformedWeightsNeed = {
248+
...need,
249+
pricingMeasurementInputs: {
250+
...need.pricingMeasurementInputs,
251+
measurementVector: [
252+
{ dimension: 'semantic_relevance', weight: 0.5, volume: 1 },
253+
{ dimension: 'source_binding', weight: 0.4, volume: 1 },
254+
] as ReadNeedMeasurementDimension[],
255+
},
256+
};
257+
const malformedProofPreview = {
258+
...preview,
259+
roots: {
260+
...preview.roots,
261+
proofRoot: '',
262+
sourceManifestRoot: '',
263+
},
264+
};
265+
const malformedQuotePreview = {
266+
...preview,
267+
feeQuote: {
268+
...preview.feeQuote,
269+
sats: preview.feeQuote.sats + 1,
270+
},
271+
};
272+
const unassignedRangePreview = {
273+
...preview,
274+
rangeProjection: {
275+
...preview.rangeProjection,
276+
rangeStart: null,
277+
rangeEndExclusive: null,
278+
},
279+
};
280+
281+
const cases = [
282+
{
283+
name: 'reviewed Need',
284+
projection: buildBtdScalarVolumeQuoteConservation({
285+
acceptedNeed: unreviewedNeed,
286+
sourceSafePreview: preview,
287+
selectedFits: [selectedFit('fit-a', 820, 8200)],
288+
}),
289+
blocker: 'reviewed_need_required',
290+
},
291+
{
292+
name: 'selected Fit set',
293+
projection: buildBtdScalarVolumeQuoteConservation({
294+
acceptedNeed: need,
295+
sourceSafePreview: preview,
296+
selectedFits: [],
297+
}),
298+
blocker: 'selected_fit_set_required',
299+
},
300+
{
301+
name: 'synthesized Need-Fit AssetPack',
302+
projection: buildBtdScalarVolumeQuoteConservation({
303+
acceptedNeed: need,
304+
quote: buildShareToFeePreview({ need, admittedFitQuality: 0.82 }),
305+
selectedFits: [selectedFit('fit-a', 820, 8200)],
306+
}),
307+
blocker: 'need_fit_assetpack_required',
308+
},
309+
{
310+
name: 'deterministic measurement weights',
311+
projection: buildBtdScalarVolumeQuoteConservation({
312+
acceptedNeed: malformedWeightsNeed,
313+
sourceSafePreview: preview,
314+
selectedFits: [selectedFit('fit-a', 820, 8200)],
315+
}),
316+
blocker: 'measurement_weight_policy_required',
317+
},
318+
{
319+
name: 'source-safe proof roots',
320+
projection: buildBtdScalarVolumeQuoteConservation({
321+
acceptedNeed: need,
322+
sourceSafePreview: malformedProofPreview,
323+
selectedFits: [selectedFit('fit-a', 820, 8200)],
324+
}),
325+
blocker: 'source_safe_proof_root_required',
326+
},
327+
{
328+
name: 'settlement-bound quote',
329+
projection: buildBtdScalarVolumeQuoteConservation({
330+
acceptedNeed: need,
331+
sourceSafePreview: {
332+
...preview,
333+
feeQuote: null as unknown as AssetPackSourceSafePreview['feeQuote'],
334+
},
335+
selectedFits: [selectedFit('fit-a', 820, 8200)],
336+
}),
337+
blocker: 'settlement_bound_quote_required',
338+
},
339+
{
340+
name: 'conserved quote',
341+
projection: buildBtdScalarVolumeQuoteConservation({
342+
acceptedNeed: need,
343+
sourceSafePreview: malformedQuotePreview,
344+
selectedFits: [selectedFit('fit-a', 820, 8200)],
345+
}),
346+
blocker: 'quote_conservation_failed',
347+
},
348+
{
349+
name: 'assigned BTD range',
350+
projection: buildBtdScalarVolumeQuoteConservation({
351+
acceptedNeed: need,
352+
sourceSafePreview: unassignedRangePreview,
353+
selectedFits: [selectedFit('fit-a', 820, 8200)],
354+
}),
355+
blocker: 'btd_range_conservation_failed',
356+
},
357+
];
358+
359+
for (const entry of cases) {
360+
expect(entry.projection.state).toBe('final_btd_scalar_volume_blocked');
361+
expect(entry.projection.blockers).toContain(entry.blocker);
362+
expect(() => assertFinalBtdScalarVolumeAdmissible(entry.projection)).toThrow(
363+
/Final BTD scalar volume is not admissible/,
364+
);
365+
}
366+
});
367+
});

0 commit comments

Comments
 (0)