Skip to content

Commit 0af667d

Browse files
V48 Gate 3 (implementation-only): Settled demand honesty and full-stack deposit stats
Ground earnings/neediness in settled Depository AssetPack search or show Unestimatable; re-ground option neediness after synthesis. Keep Positive ROI reviewable when demand is unestimatable (provisional ROI ranking; earnings display still unestimatable). Fix permanent Required denials=2 by treating sub-critical deposit authority as ready without depositApproved first.
1 parent eb83af0 commit 0af667d

16 files changed

Lines changed: 1522 additions & 149 deletions

packages/pipelines/asset-pack/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"./deposit-asset-pack-option-policy": "./src/deposit-asset-pack-option-policy.ts",
1818
"./deposit-asset-pack-option-admission": "./src/deposit-asset-pack-option-admission.ts",
1919
"./depositor-earning-supply-intelligence": "./src/depositor-earning-supply-intelligence.ts",
20+
"./depository-settled-demand-estimate": "./src/depository-settled-demand-estimate.ts",
2021
"./btd-btc-compensation-statements": "./src/btd-btc-compensation-statements.ts",
2122
"./asset-pack-commodity-state": "./src/asset-pack-commodity-state.ts",
2223
"./btd-scalar-volume-quote": "./src/btd-scalar-volume-quote.ts",

packages/pipelines/asset-pack/src/__tests__/depositor-earning-supply-intelligence.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,30 @@ describe('Depositor earning supply intelligence', () => {
106106
expect(assertDepositorEarningSupplyIntelligenceSourceSafe(intelligence).admitted).toBe(true);
107107
expect(JSON.stringify(intelligence)).not.toContain('PRIVATE_SOURCE_DO_NOT_SERIALIZE');
108108
});
109+
110+
it('marks likely demand and compensation unestimatable without inventing placeholders', () => {
111+
const intelligence = buildDepositorEarningSupplyIntelligence({
112+
policyReport: reviewablePolicyReport(),
113+
demandUnestimatable: true,
114+
demandUnestimatableRationale:
115+
'Unestimatable: the Depository has no settled AssetPacks to search for comparable demand.',
116+
unfitNeedOpportunitySignals: [
117+
{
118+
id: 'should-be-ignored',
119+
label: 'Must not surface when demand is unestimatable.',
120+
weight: 0.99,
121+
},
122+
],
123+
});
124+
125+
expect(intelligence.likelyDemand.state).toBe('unestimatable-demand');
126+
expect(intelligence.likelyDemand.averageConfidence).toBe(0);
127+
expect(intelligence.unfitNeedOpportunities.state).toBe('unestimatable-demand');
128+
expect(intelligence.unfitNeedOpportunities.opportunityCount).toBe(0);
129+
expect(
130+
intelligence.earningStatements.every((statement) => statement.state === 'unestimatable-demand'),
131+
).toBe(true);
132+
expect(intelligence.aggregate.totalExpectedCompensationSats).toBe(0);
133+
expect(intelligence.aggregate.eligibleEarningStatementCount).toBe(0);
134+
});
109135
});
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
import {
2+
estimateDepositorySettledDemand,
3+
groundOptionNeedinessFromSettledDepository,
4+
settledDemandEstimateToNeediness,
5+
settledDemandEstimateToSignals,
6+
type SettledDepositoryPackSummary,
7+
} from '../depository-settled-demand-estimate';
8+
9+
function pack(
10+
id: string,
11+
overrides: Partial<SettledDepositoryPackSummary> = {},
12+
): SettledDepositoryPackSummary {
13+
return {
14+
id,
15+
title: overrides.title ?? `Settled pack ${id}`,
16+
summary: overrides.summary ?? 'Source-safe settled AssetPack summary for demand search.',
17+
kind: overrides.kind ?? 'capability-slice',
18+
repositoryFullName: overrides.repositoryFullName ?? 'acme/widgets',
19+
lifecycleState: overrides.lifecycleState ?? 'settled',
20+
topics: overrides.topics ?? ['auth', 'routing'],
21+
};
22+
}
23+
24+
describe('depository settled demand estimate', () => {
25+
it('returns unestimatable when the settled corpus is empty', () => {
26+
const estimate = estimateDepositorySettledDemand({ settledPacks: [] });
27+
expect(estimate.estimatable).toBe(false);
28+
expect(estimate.state).toBe('unestimatable-demand');
29+
expect(estimate.demand).toBeNull();
30+
expect(estimate.needinessVolume).toBeNull();
31+
expect(estimate.rationale).toMatch(/^Unestimatable:/);
32+
expect(settledDemandEstimateToSignals(estimate).depositoryDemandSignals).toEqual([]);
33+
expect(settledDemandEstimateToNeediness(estimate).estimatable).toBe(false);
34+
});
35+
36+
it('returns unestimatable when below the settled floor', () => {
37+
const estimate = estimateDepositorySettledDemand({
38+
settledPacks: [pack('a'), pack('b')],
39+
minSettledPacks: 3,
40+
});
41+
expect(estimate.estimatable).toBe(false);
42+
expect(estimate.settledPackCount).toBe(2);
43+
expect(estimate.rationale).toMatch(/need at least 3/);
44+
});
45+
46+
it('estimates aggregate demand from a settled corpus without inventing strong placeholders', () => {
47+
const settledPacks = [
48+
pack('1', { title: 'Auth capability slice', summary: 'Reusable authentication capability' }),
49+
pack('2', { title: 'Routing pattern', summary: 'HTTP routing implementation pattern' }),
50+
pack('3', { title: 'Proof ops', summary: 'Operations proof for deposit route' }),
51+
pack('4', { title: 'Telemetry slice', summary: 'Telemetry collection capability' }),
52+
];
53+
const estimate = estimateDepositorySettledDemand({ settledPacks });
54+
expect(estimate.estimatable).toBe(true);
55+
expect(estimate.demand).not.toBeNull();
56+
expect(estimate.demand!).toBeGreaterThan(0);
57+
expect(estimate.demand!).toBeLessThanOrEqual(1);
58+
expect(estimate.saturation).not.toBeNull();
59+
expect(estimate.needinessVolume).not.toBeNull();
60+
expect(estimate.rationale).toMatch(/settled Depository AssetPack/i);
61+
const signals = settledDemandEstimateToSignals(estimate);
62+
expect(signals.depositoryDemandSignals[0]?.weight).toBe(estimate.demand);
63+
});
64+
65+
it('returns unestimatable for a focused topic with no matching settled packs', () => {
66+
const settledPacks = [
67+
pack('1', { title: 'Auth capability', summary: 'login session tokens' }),
68+
pack('2', { title: 'Auth middleware', summary: 'session cookies' }),
69+
pack('3', { title: 'Identity bridge', summary: 'oauth providers' }),
70+
];
71+
const estimate = estimateDepositorySettledDemand({
72+
settledPacks,
73+
focus: {
74+
title: 'Quantum ledger warp core',
75+
summary: 'Hyperdimensional quantum entanglement settlement primitives',
76+
kind: 'proof-operations-slice',
77+
repositoryFullName: 'other/org',
78+
},
79+
});
80+
expect(estimate.estimatable).toBe(false);
81+
expect(estimate.state).toBe('unestimatable-demand');
82+
expect(estimate.rationale).toMatch(/no settled Depository AssetPacks match/i);
83+
});
84+
85+
it('raises demand for topic-aligned settled packs with low corpus coverage', () => {
86+
const settledPacks = [
87+
pack('1', {
88+
title: 'Deposit route proof operations',
89+
summary: 'Source-safe deposit route proof and admission',
90+
kind: 'proof-operations-slice',
91+
repositoryFullName: 'engineeredsoftware/ENGI',
92+
topics: ['deposit', 'route', 'proof'],
93+
}),
94+
pack('2', {
95+
title: 'Deposit admission receipt',
96+
summary: 'Depository admission for deposit options',
97+
kind: 'proof-operations-slice',
98+
repositoryFullName: 'engineeredsoftware/ENGI',
99+
topics: ['deposit', 'admission'],
100+
}),
101+
pack('3', {
102+
title: 'Unrelated widget inventory',
103+
summary: 'Inventory of garden widgets and tools',
104+
kind: 'capability-slice',
105+
repositoryFullName: 'acme/widgets',
106+
topics: ['garden', 'widgets'],
107+
}),
108+
pack('4', {
109+
title: 'Widget shipping labels',
110+
summary: 'Shipping label generation for widgets',
111+
kind: 'implementation-pattern',
112+
repositoryFullName: 'acme/widgets',
113+
topics: ['shipping'],
114+
}),
115+
pack('5', {
116+
title: 'Widget color palette',
117+
summary: 'Color tokens for the widget catalog',
118+
kind: 'capability-slice',
119+
repositoryFullName: 'acme/widgets',
120+
topics: ['design'],
121+
}),
122+
];
123+
const estimate = estimateDepositorySettledDemand({
124+
settledPacks,
125+
focus: {
126+
title: 'Deposit route proof operations slice',
127+
summary: 'Source-safe deposit route proof and Depository admission evidence',
128+
kind: 'proof-operations-slice',
129+
repositoryFullName: 'engineeredsoftware/ENGI',
130+
coveredSourcePaths: ['uapi/app/deposits/DepositPageClient.tsx'],
131+
},
132+
});
133+
expect(estimate.estimatable).toBe(true);
134+
expect(estimate.matchedPackCount).toBeGreaterThan(0);
135+
expect(estimate.demand).toBeGreaterThan(0);
136+
expect(settledDemandEstimateToNeediness(estimate).estimatable).toBe(true);
137+
});
138+
139+
it('grounds option neediness from settled packs or marks Unestimatable', () => {
140+
const options = [
141+
{
142+
title: 'Auth capability slice',
143+
summary: 'Reusable authentication capability from the repository',
144+
kind: 'capability-slice',
145+
neediness: { volume: 0.86, demand: 0.9, saturation: 0.1, rationale: 'LLM invented' },
146+
contents: { provenantSourcePaths: ['src/auth.ts'] },
147+
sourceBinding: { repositoryFullName: 'acme/widgets' },
148+
},
149+
];
150+
151+
const thin = groundOptionNeedinessFromSettledDepository(options, []);
152+
expect(thin[0].neediness?.rationale).toMatch(/^Unestimatable:/);
153+
expect(thin[0].neediness?.demand).toBe(0);
154+
155+
const settledPacks = [
156+
pack('1', { title: 'Auth capability', summary: 'authentication sessions' }),
157+
pack('2', { title: 'Auth middleware', summary: 'login authentication middleware' }),
158+
pack('3', { title: 'Session store', summary: 'authentication session store pattern' }),
159+
];
160+
const grounded = groundOptionNeedinessFromSettledDepository(options, settledPacks);
161+
expect(grounded[0].neediness?.rationale).not.toBe('LLM invented');
162+
// Either estimatable from matches or honest Unestimatable — never silent invent.
163+
expect(
164+
grounded[0].neediness?.rationale?.includes('settled') ||
165+
grounded[0].neediness?.rationale?.startsWith('Unestimatable'),
166+
).toBe(true);
167+
});
168+
});

packages/pipelines/asset-pack/src/__tests__/organization-policy-wallet-authority.test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,39 @@ describe('OrganizationPolicyWalletAuthority', () => {
104104
expect(statement.disclosure.protectedSourceVisible).toBe(false);
105105
});
106106

107+
it('authorizes approve/submit when sub-critical without requiring depositApproved first (no permanent Required denials)', () => {
108+
const statement = buildOrganizationPolicyWalletAuthority({
109+
route: '/deposits',
110+
actorId: 'user-1',
111+
organizationId: 'org-1',
112+
organizationRole: 'admin',
113+
organizationPermissionGrants: [
114+
'deposit:synthesize_options',
115+
'deposit:approve_option',
116+
'deposit:submit',
117+
],
118+
walletId: 'wallet-depositor',
119+
walletAuthorityPresent: true,
120+
sourceCriticalityState: 'sub-critical',
121+
sourceCriticalityApproved: true,
122+
depositApproved: false,
123+
expectedSettlementSats: 5_200,
124+
depositLimitSats: 100_000,
125+
accountAdmitted: true,
126+
interfaceAdmitted: true,
127+
});
128+
129+
expect(statement.depositApproval.state).toBe('sub-critical-approved');
130+
expect(statement.aggregate.requiredDeniedActionCount).toBe(0);
131+
expect(statement.aggregate.state).toBe('allowed');
132+
expect(
133+
statement.actionStatements.find((entry) => entry.action === 'approve_deposit_option'),
134+
).toMatchObject({ allowed: true });
135+
expect(
136+
statement.actionStatements.find((entry) => entry.action === 'submit_deposit'),
137+
).toMatchObject({ allowed: true });
138+
});
139+
107140
it('blocks critical source deposit approval without exposing source-bearing payloads', () => {
108141
const statement = buildOrganizationPolicyWalletAuthority({
109142
route: '/deposits',

0 commit comments

Comments
 (0)