@@ -623,6 +623,28 @@ static char *delta_generated_props(const char *props, const char *generated) {
623623 return out ;
624624}
625625
626+ /* `props` (a JSON object) with the extractor's test verdict added as
627+ * `"is_test":true` (CBM_MEM_CLASS_OTHER; the caller frees), NULL on allocation
628+ * failure. The incremental registry seed reads the verdict back
629+ * (cbm_node_is_test) so a re-resolved caller ranks a test definition below
630+ * real code exactly as the full build does; an absent key reads as false. */
631+ static char * delta_test_props (const char * props ) {
632+ static const char member [] = "\"is_test\":true" ;
633+ size_t pl = props ? strlen (props ) : 0 ;
634+ bool has_members = pl > PAIR_LEN && props [0 ] == '{' && props [pl - SKIP_ONE ] == '}' ;
635+ size_t cap = pl + sizeof (member ) + CBM_SZ_4 ;
636+ char * out = (char * )cbm_alloc (CBM_MEM_CLASS_OTHER , cap );
637+ if (!out ) {
638+ return NULL ;
639+ }
640+ if (has_members ) {
641+ snprintf (out , cap , "%.*s,%s}" , (int )(pl - SKIP_ONE ), props , member );
642+ } else {
643+ snprintf (out , cap , "{%s}" , member );
644+ }
645+ return out ;
646+ }
647+
626648int64_t cbm_delta_preseed (cbm_store_t * store , const char * project , cbm_gbuf_t * gbuf ) {
627649 sqlite3 * db = cbm_store_get_db (store );
628650 if (!db ) {
@@ -673,7 +695,13 @@ int64_t cbm_delta_preseed(cbm_store_t *store, const char *project, cbm_gbuf_t *g
673695 * And a generated member's mark (a Java record's implicit accessor, a
674696 * Method node): the registry seed reads it to register the member by
675697 * qualified name only, as the full build does (cbm_node_props_generated);
676- * without it the proxy came back into the short-name index. */
698+ * without it the proxy came back into the short-name index.
699+ *
700+ * And the extractor's test verdict: the registry seed reads it back
701+ * (cbm_node_is_test) to rank a test definition below real code, as the
702+ * full build does with CBMDefinition.is_test; without it every proxy
703+ * scored as production and a re-resolved caller could bind a test helper
704+ * the full build ranks last. */
677705 sqlite3_stmt * stmt = NULL ;
678706 if (sqlite3_prepare_v2 (
679707 db ,
@@ -702,7 +730,8 @@ int64_t cbm_delta_preseed(cbm_store_t *store, const char *project, cbm_gbuf_t *g
702730 " THEN json_extract(properties, '$.parent_class') END,"
703731 " CASE WHEN label = 'Method'"
704732 " AND instr(properties, '\"" CBM_PROP_GENERATED "\"') > 0"
705- " THEN json_extract(properties, '$." CBM_PROP_GENERATED "') END"
733+ " THEN json_extract(properties, '$." CBM_PROP_GENERATED "') END,"
734+ " instr(properties, '\"is_test\":true') > 0"
706735 " FROM nodes"
707736 " WHERE project = ?1 AND label NOT IN"
708737 " ('Macro','Comment','Section','Branch','Commit','Tag')"
@@ -727,14 +756,27 @@ int64_t cbm_delta_preseed(cbm_store_t *store, const char *project, cbm_gbuf_t *g
727756 int end_line = sqlite3_column_int (stmt , 7 );
728757 const char * parent = (const char * )sqlite3_column_text (stmt , 8 );
729758 const char * generated = (const char * )sqlite3_column_text (stmt , 9 );
759+ bool is_test = sqlite3_column_int (stmt , 10 ) != 0 ;
730760 char * owner_props =
731761 parent ? delta_owner_props (project , name , qn , parent , client_props ) : NULL ;
732762 const char * props = owner_props ? owner_props : (client_props ? client_props : "{}" );
733763 char * generated_props = delta_generated_props (props , generated );
764+ const char * seed_props = generated_props ? generated_props : props ;
765+ char * test_props = is_test ? delta_test_props (seed_props ) : NULL ;
766+ if (is_test && !test_props ) {
767+ /* A proxy without its verdict would rank as production code;
768+ * the run cannot be trusted, as with an id mismatch below. */
769+ cbm_free (CBM_MEM_CLASS_OTHER , generated_props );
770+ cbm_free (CBM_MEM_CLASS_OTHER , owner_props );
771+ sqlite3_finalize (stmt );
772+ cbm_log_error ("delta.preseed_verdict_alloc_failed" , "qn" , qn ? qn : "" );
773+ return -1 ;
774+ }
734775 /* Pin the gbuf id to the database id: proxies ARE their rows. */
735776 cbm_gbuf_set_next_id (gbuf , id );
736777 int64_t got = cbm_gbuf_upsert_node (gbuf , label , name , qn , fp ? fp : "" , start_line ,
737- end_line , generated_props ? generated_props : props );
778+ end_line , test_props ? test_props : seed_props );
779+ cbm_free (CBM_MEM_CLASS_OTHER , test_props );
738780 cbm_free (CBM_MEM_CLASS_OTHER , generated_props );
739781 cbm_free (CBM_MEM_CLASS_OTHER , owner_props );
740782 if (got != id ) {
0 commit comments