@@ -63,21 +63,44 @@ describe('agent-measure-absolutes', () => {
6363 it ( 'maps agent readings onto the catalog and falls back per-missing-reading' , ( ) => {
6464 const readings = [
6565 { measurementKind : 'function-count' , volume : 0.5 , magnitude : 20 } ,
66- { measurementKind : 'semantic-volume ' , volume : 0.66 } ,
67- // type-count, file-span, correctness-estimate omitted -> deterministic fallback
66+ { measurementKind : 'objectives-fidelity ' , volume : 0.66 } ,
67+ // other kinds omitted -> deterministic fallback
6868 ] ;
6969 const measurements = mapReadingsToAbsoluteMeasurements ( readings , PATCH ) ;
7070 expect ( measurements ) . toHaveLength ( ASSET_PACK_ABSOLUTES_CATALOG . length ) ;
7171 const fn = measurements . find ( ( m ) => m . measurementKind === 'function-count' ) ;
7272 expect ( fn ?. volume ) . toBe ( 0.5 ) ;
7373 expect ( fn ?. magnitude ) . toBe ( 20 ) ;
74- const sem = measurements . find ( ( m ) => m . measurementKind === 'semantic-volume ' ) ;
75- expect ( sem ?. volume ) . toBe ( 0.66 ) ;
74+ const objectives = measurements . find ( ( m ) => m . measurementKind === 'objectives-fidelity ' ) ;
75+ expect ( objectives ?. volume ) . toBe ( 0.66 ) ;
7676 // omitted file-span falls back to the deterministic exact count (2)
7777 const fileSpan = measurements . find ( ( m ) => m . measurementKind === 'file-span' ) ;
7878 expect ( fileSpan ?. magnitude ) . toBe ( 2 ) ;
7979 } ) ;
8080
81+ it ( 'catalog splits quantity vs quality material properties' , ( ) => {
82+ const quantity = ASSET_PACK_ABSOLUTES_CATALOG . filter ( ( s ) => s . propertyClass === 'quantity' ) ;
83+ const quality = ASSET_PACK_ABSOLUTES_CATALOG . filter ( ( s ) => s . propertyClass === 'quality' ) ;
84+ expect ( quantity . map ( ( s ) => s . measurementKind ) ) . toEqual (
85+ expect . arrayContaining ( [
86+ 'function-count' ,
87+ 'type-count' ,
88+ 'file-span' ,
89+ 'symbolic-richness' ,
90+ 'modularity' ,
91+ ] ) ,
92+ ) ;
93+ expect ( quality . map ( ( s ) => s . measurementKind ) ) . toEqual (
94+ expect . arrayContaining ( [
95+ 'correctness-estimate' ,
96+ 'objectives-fidelity' ,
97+ 'computational-usage' ,
98+ ] ) ,
99+ ) ;
100+ expect ( quantity . every ( ( s ) => s . hasMagnitude ) ) . toBe ( true ) ;
101+ expect ( quality . every ( ( s ) => ! s . hasMagnitude ) ) . toBe ( true ) ;
102+ } ) ;
103+
81104 it ( 'builds a lens-parameterized measurer agent' , ( ) => {
82105 const deposit = factoryAssetPackMeasureAbsolutesAgent ( 'deposit' ) ;
83106 const read = factoryAssetPackMeasureAbsolutesAgent ( 'read' ) ;
@@ -107,12 +130,12 @@ describe('validateDepositSynthesisOptions absolutes wiring', () => {
107130
108131 it ( 'prefers the formal absolutes over the placeholder catalog' , ( ) => {
109132 const absolutes = [
110- { measurementKind : 'function-count' , label : 'Functions' , weight : 0.18 , volume : 0.5 , category : 'absolute' , magnitude : 12 , unit : 'functions' } ,
111- { measurementKind : 'semantic-volume ' , label : 'Semantic volume ' , weight : 0.28 , volume : 0.66 , category : 'absolute' , unit : 'normalized ' } ,
133+ { measurementKind : 'function-count' , label : 'Functions' , weight : 0.12 , volume : 0.5 , category : 'absolute' , magnitude : 12 , unit : 'functions' } ,
134+ { measurementKind : 'correctness-estimate ' , label : 'Correctness ' , weight : 0.18 , volume : 0.66 , category : 'absolute' , unit : 'estimate ' } ,
112135 ] ;
113136 const out = validateDepositSynthesisOptions ( [ { ...baseOption , absolutes } ] , context ) ;
114137 const measurements = out . candidates [ 0 ] . measurements ;
115- expect ( measurements . map ( ( m ) => m . measurementKind ) ) . toEqual ( [ 'function-count' , 'semantic-volume ' ] ) ;
138+ expect ( measurements . map ( ( m ) => m . measurementKind ) ) . toEqual ( [ 'function-count' , 'correctness-estimate ' ] ) ;
116139 const fn = measurements . find ( ( m ) => m . measurementKind === 'function-count' ) ;
117140 expect ( fn ?. magnitude ) . toBe ( 12 ) ;
118141 expect ( fn ?. category ) . toBe ( 'absolute' ) ;
@@ -154,43 +177,60 @@ describe('tool-grounded absolutes (legitimate static-analysis sizes)', () => {
154177 title : 'x' , summary : 'y' , coveredSourcePaths : [ 'a.ts' , 'b.ts' ] , confidence : 0.6 ,
155178 } ;
156179 const measured = computeAbsolutesFromReport (
157- { measuredFromSamples : true , estimatedFunctionCount : 30 , estimatedTypeCount : 12 , targetFileCount : 2 ,
158- sampledFileCount : 2 , lineCount : 0 , tokenCount : 0 , functionCount : 30 , typeCount : 12 , symbolCount : 0 ,
159- configKeyCount : 0 , languageDensities : [ ] , targetLanguageBreakdown : { } , coverageRatio : 1 } as any ,
180+ {
181+ measuredFromSamples : true ,
182+ estimatedFunctionCount : 30 ,
183+ estimatedTypeCount : 12 ,
184+ estimatedSymbolCount : 100 ,
185+ moduleCount : 2 ,
186+ targetFileCount : 2 ,
187+ sampledFileCount : 2 ,
188+ lineCount : 0 ,
189+ tokenCount : 0 ,
190+ functionCount : 30 ,
191+ typeCount : 12 ,
192+ symbolCount : 100 ,
193+ configKeyCount : 0 ,
194+ languageDensities : [ ] ,
195+ targetLanguageBreakdown : { } ,
196+ coverageRatio : 1 ,
197+ } as any ,
160198 patch ,
161199 ) ;
162200 expect ( measured . find ( ( m ) => m . measurementKind === 'function-count' ) ?. magnitude ) . toBe ( 30 ) ;
201+ expect ( measured . find ( ( m ) => m . measurementKind === 'symbolic-richness' ) ?. magnitude ) . toBe ( 100 ) ;
202+ expect ( measured . find ( ( m ) => m . measurementKind === 'modularity' ) ?. magnitude ) . toBe ( 2 ) ;
163203 // no source -> heuristic from covered-path span (2 paths * 3 = 6)
164204 const heuristic = computeDeterministicAbsolutes ( patch ) ;
165205 expect ( heuristic . find ( ( m ) => m . measurementKind === 'function-count' ) ?. magnitude ) . toBe ( 6 ) ;
166206 } ) ;
167207
168- it ( 'mergeReportAndReadings clamps agent judgment readings into [0,1]' , ( ) => {
208+ it ( 'mergeReportAndReadings clamps agent quality readings into [0,1]' , ( ) => {
169209 const patch : MeasurableAssetPackPatch = {
170210 title : 'x' , summary : 'y' , coveredSourcePaths : [ 'a.ts' ] , fileChanges : [ { path : 'a.ts' , op : 'modify' } ] , confidence : 0.5 ,
171211 } ;
172212 const merged = mergeReportAndReadings ( computeDeterministicAbsolutes ( patch ) , [
173213 { measurementKind : 'correctness-estimate' , volume : 7 } , // clamped down
174- { measurementKind : 'semantic-volume ' , volume : - 3 } , // clamped up
214+ { measurementKind : 'objectives-fidelity ' , volume : - 3 } , // clamped up
175215 ] ) ;
176216 expect ( merged . find ( ( m ) => m . measurementKind === 'correctness-estimate' ) ?. volume ) . toBe ( 1 ) ;
177- expect ( merged . find ( ( m ) => m . measurementKind === 'semantic-volume ' ) ?. volume ) . toBe ( 0 ) ;
217+ expect ( merged . find ( ( m ) => m . measurementKind === 'objectives-fidelity ' ) ?. volume ) . toBe ( 0 ) ;
178218 } ) ;
179219
180- it ( 'mergeReportAndReadings keeps sizes authoritative, takes agent judgment ' , ( ) => {
220+ it ( 'mergeReportAndReadings keeps quantity tool- authoritative, takes agent quality ' , ( ) => {
181221 const patch : MeasurableAssetPackPatch = {
182222 title : 'x' , summary : 'y' , coveredSourcePaths : [ 'a.ts' ] , fileChanges : [ { path : 'a.ts' , op : 'modify' } ] , confidence : 0.5 ,
183223 } ;
184224 const base = computeDeterministicAbsolutes ( patch ) ;
185225 const baseFnVolume = base . find ( ( m ) => m . measurementKind === 'function-count' ) ! . volume ;
186226 const merged = mergeReportAndReadings ( base , [
187- { measurementKind : 'function-count' , volume : 0.99 } , // ignored — size is tool-authoritative
227+ { measurementKind : 'function-count' , volume : 0.99 } , // ignored — quantity is tool-authoritative
188228 { measurementKind : 'correctness-estimate' , volume : 0.91 } , // taken
189- { measurementKind : 'semantic-volume ' , volume : 0.4 } , // taken
229+ { measurementKind : 'computational-usage ' , volume : 0.4 } , // taken
190230 ] ) ;
191231 expect ( merged . find ( ( m ) => m . measurementKind === 'function-count' ) ?. volume ) . toBe ( baseFnVolume ) ;
192232 expect ( merged . find ( ( m ) => m . measurementKind === 'correctness-estimate' ) ?. volume ) . toBe ( 0.91 ) ;
193- expect ( merged . find ( ( m ) => m . measurementKind === 'semantic-volume ' ) ?. volume ) . toBe ( 0.4 ) ;
233+ expect ( merged . find ( ( m ) => m . measurementKind === 'computational-usage ' ) ?. volume ) . toBe ( 0.4 ) ;
194234 } ) ;
195235} ) ;
196236
@@ -219,15 +259,14 @@ describe('measureAssetPackAbsolutes real-inference path (boundary-mocked measure
219259 const executeSpy = jest . spyOn ( SourceStaticAnalysisTool . prototype , 'execute' ) ;
220260 setBoundaryLLMOutput ( {
221261 measurements : [
222- // Judgment readings — taken from the agent (pins the envelope unwrap: if the
223- // PTRR envelope were read directly these would be lost and correctness would
224- // fall back to the confidence-derived 0.7).
262+ // Quality readings — taken from the agent (pins the envelope unwrap).
225263 { measurementKind : 'correctness-estimate' , volume : 0.91 , rationale : 'Grounded in the measured counts.' } ,
226- { measurementKind : 'semantic-volume' , volume : 0.44 , rationale : 'Moderate legible knowledge volume.' } ,
227- // A size reading — MUST be ignored: sizes are static-analysis-authoritative.
264+ { measurementKind : 'objectives-fidelity' , volume : 0.44 , rationale : 'Aligned with deposit objectives.' } ,
265+ { measurementKind : 'computational-usage' , volume : 0.33 , rationale : 'Moderate complexity surface.' } ,
266+ // A quantity reading — MUST be ignored: quantities are tool-authoritative.
228267 { measurementKind : 'function-count' , volume : 0.99 , magnitude : 999 , rationale : 'Inflated size reading.' } ,
229268 ] ,
230- summary : 'Measured the absolutes of the patch descriptor .' ,
269+ summary : 'Measured the absolute material properties of the patch.' ,
231270 } ) ;
232271
233272 const absolutes = await measureAssetPackAbsolutes ( PATCH , {
@@ -237,13 +276,14 @@ describe('measureAssetPackAbsolutes real-inference path (boundary-mocked measure
237276 } ) ;
238277
239278 expect ( absolutes . map ( ( m ) => m . measurementKind ) . sort ( ) ) . toEqual ( [ ...ASSET_PACK_ABSOLUTE_KINDS ] . sort ( ) ) ;
240- // Sizes stay tool-grounded (2 functions in the provided source, not the agent's 999).
279+ // Quantity stays tool-grounded (2 functions in the provided source, not the agent's 999).
241280 const fn = absolutes . find ( ( m ) => m . measurementKind === 'function-count' ) ;
242281 expect ( fn ?. magnitude ) . toBe ( 2 ) ;
243282 expect ( fn ?. volume ) . toBe ( 0.05 ) ; // 2 / 40 normalizer
244- // Agent judgment readings are taken.
283+ // Agent quality readings are taken.
245284 expect ( absolutes . find ( ( m ) => m . measurementKind === 'correctness-estimate' ) ?. volume ) . toBe ( 0.91 ) ;
246- expect ( absolutes . find ( ( m ) => m . measurementKind === 'semantic-volume' ) ?. volume ) . toBe ( 0.44 ) ;
285+ expect ( absolutes . find ( ( m ) => m . measurementKind === 'objectives-fidelity' ) ?. volume ) . toBe ( 0.44 ) ;
286+ expect ( absolutes . find ( ( m ) => m . measurementKind === 'computational-usage' ) ?. volume ) . toBe ( 0.33 ) ;
247287 // Source-safety: only use() runs (in-memory samples); execute() would persist the
248288 // raw source args into a tool child execution and must never be called.
249289 expect ( executeSpy ) . not . toHaveBeenCalled ( ) ;
0 commit comments