diff --git a/docs/reports/code_path_audit/2026-06-22/aggregates/ChatMessage.md b/docs/reports/code_path_audit/2026-06-22/aggregates/ChatMessage.md index 812bec38..7081d7f6 100644 --- a/docs/reports/code_path_audit/2026-06-22/aggregates/ChatMessage.md +++ b/docs/reports/code_path_audit/2026-06-22/aggregates/ChatMessage.md @@ -8,6 +8,24 @@ - Producers: 0 - Consumers: 0 +- Distinct producer fqnames: 0 +- Distinct consumer fqnames: 0 +- Access pattern (aggregate): mixed +- Frequency (aggregate): unknown +- Decomposition direction: insufficient_data +- Struct field count (estimated): 0 + +## Producers (0) + +_(none)_ + +## Consumers (0) + +_(none)_ + +## Field access matrix + +_(no field accesses detected)_ ## Access pattern @@ -23,27 +41,47 @@ **Summary:** +| metric | value | +|---|---| +| total producers | 0 | +| result producers | 0 | +| total consumers | 0 | +| result consumers | 0 | + ## Type alias coverage **Summary:** +| metric | value | +|---|---| +| total field-access sites | 0 | +| typed sites (canonical field) | 0 | +| untyped sites (wildcard) | 0 | + ## Cross-audit findings -| Audit script | Site count | Example | Note | -|---|---|---|---| +_(no cross-audit findings mapped to this aggregate)_ ## Decomposition cost -**Current cost estimate:** 0 us -**Componentize savings:** 0 us -**Unify savings:** 0 us +**Current cost estimate:** 0 us/turn +**Componentize savings:** 0 us/turn +**Unify savings:** 0 us/turn **Recommended direction:** insufficient_data **Rationale:** candidate aggregate; would be detected after any_type_componentization_20260621 merges +**Struct field count (estimated):** 0 +**Struct frozen:** False + +## Struct shape (inferred from producer returns) + +_(no producers; cannot infer shape)_ ## Optimization candidates -_(none)_ +_(no optimization candidates generated)_ ## Verdict -candidate aggregate; would be detected after any_type_componentization_20260621 merges \ No newline at end of file +candidate aggregate; would be detected after any_type_componentization_20260621 merges + +## Evidence appendix diff --git a/docs/reports/code_path_audit/2026-06-22/aggregates/CommsLog.md b/docs/reports/code_path_audit/2026-06-22/aggregates/CommsLog.md index 8217fd08..13d82ac4 100644 --- a/docs/reports/code_path_audit/2026-06-22/aggregates/CommsLog.md +++ b/docs/reports/code_path_audit/2026-06-22/aggregates/CommsLog.md @@ -8,6 +8,24 @@ - Producers: 0 - Consumers: 0 +- Distinct producer fqnames: 0 +- Distinct consumer fqnames: 0 +- Access pattern (aggregate): mixed +- Frequency (aggregate): per_turn +- Decomposition direction: insufficient_data +- Struct field count (estimated): 5 + +## Producers (0) + +_(none)_ + +## Consumers (0) + +_(none)_ + +## Field access matrix + +_(no field accesses detected)_ ## Access pattern @@ -23,27 +41,47 @@ **Summary:** 0 producers, 0 consumers +| metric | value | +|---|---| +| total producers | 0 | +| result producers | 0 | +| total consumers | 0 | +| result consumers | 0 | + ## Type alias coverage **Summary:** 0 sites +| metric | value | +|---|---| +| total field-access sites | 0 | +| typed sites (canonical field) | 0 | +| untyped sites (wildcard) | 0 | + ## Cross-audit findings -| Audit script | Site count | Example | Note | -|---|---|---|---| +_(no cross-audit findings mapped to this aggregate)_ ## Decomposition cost -**Current cost estimate:** 470 us -**Componentize savings:** 0 us -**Unify savings:** 0 us +**Current cost estimate:** 470 us/turn +**Componentize savings:** 0 us/turn +**Unify savings:** 0 us/turn **Recommended direction:** insufficient_data **Rationale:** CommsLog: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. +**Struct field count (estimated):** 5 +**Struct frozen:** True + +## Struct shape (inferred from producer returns) + +_(no producers; cannot infer shape)_ ## Optimization candidates -_(none)_ +_(no optimization candidates generated)_ ## Verdict -CommsLog: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. \ No newline at end of file +CommsLog: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. + +## Evidence appendix diff --git a/docs/reports/code_path_audit/2026-06-22/aggregates/CommsLogEntry.md b/docs/reports/code_path_audit/2026-06-22/aggregates/CommsLogEntry.md index e668d70a..6f15d926 100644 --- a/docs/reports/code_path_audit/2026-06-22/aggregates/CommsLogEntry.md +++ b/docs/reports/code_path_audit/2026-06-22/aggregates/CommsLogEntry.md @@ -8,6 +8,24 @@ - Producers: 0 - Consumers: 0 +- Distinct producer fqnames: 0 +- Distinct consumer fqnames: 0 +- Access pattern (aggregate): mixed +- Frequency (aggregate): per_turn +- Decomposition direction: insufficient_data +- Struct field count (estimated): 5 + +## Producers (0) + +_(none)_ + +## Consumers (0) + +_(none)_ + +## Field access matrix + +_(no field accesses detected)_ ## Access pattern @@ -23,27 +41,47 @@ **Summary:** 0 producers, 0 consumers +| metric | value | +|---|---| +| total producers | 0 | +| result producers | 0 | +| total consumers | 0 | +| result consumers | 0 | + ## Type alias coverage **Summary:** 0 sites +| metric | value | +|---|---| +| total field-access sites | 0 | +| typed sites (canonical field) | 0 | +| untyped sites (wildcard) | 0 | + ## Cross-audit findings -| Audit script | Site count | Example | Note | -|---|---|---|---| +_(no cross-audit findings mapped to this aggregate)_ ## Decomposition cost -**Current cost estimate:** 470 us -**Componentize savings:** 0 us -**Unify savings:** 0 us +**Current cost estimate:** 470 us/turn +**Componentize savings:** 0 us/turn +**Unify savings:** 0 us/turn **Recommended direction:** insufficient_data **Rationale:** CommsLogEntry: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. +**Struct field count (estimated):** 5 +**Struct frozen:** True + +## Struct shape (inferred from producer returns) + +_(no producers; cannot infer shape)_ ## Optimization candidates -_(none)_ +_(no optimization candidates generated)_ ## Verdict -CommsLogEntry: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. \ No newline at end of file +CommsLogEntry: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. + +## Evidence appendix diff --git a/docs/reports/code_path_audit/2026-06-22/aggregates/FileItem.md b/docs/reports/code_path_audit/2026-06-22/aggregates/FileItem.md index bb95f044..996dd669 100644 --- a/docs/reports/code_path_audit/2026-06-22/aggregates/FileItem.md +++ b/docs/reports/code_path_audit/2026-06-22/aggregates/FileItem.md @@ -8,6 +8,24 @@ - Producers: 0 - Consumers: 0 +- Distinct producer fqnames: 0 +- Distinct consumer fqnames: 0 +- Access pattern (aggregate): mixed +- Frequency (aggregate): per_turn +- Decomposition direction: insufficient_data +- Struct field count (estimated): 5 + +## Producers (0) + +_(none)_ + +## Consumers (0) + +_(none)_ + +## Field access matrix + +_(no field accesses detected)_ ## Access pattern @@ -23,27 +41,47 @@ **Summary:** 0 producers, 0 consumers +| metric | value | +|---|---| +| total producers | 0 | +| result producers | 0 | +| total consumers | 0 | +| result consumers | 0 | + ## Type alias coverage **Summary:** 0 sites +| metric | value | +|---|---| +| total field-access sites | 0 | +| typed sites (canonical field) | 0 | +| untyped sites (wildcard) | 0 | + ## Cross-audit findings -| Audit script | Site count | Example | Note | -|---|---|---|---| +_(no cross-audit findings mapped to this aggregate)_ ## Decomposition cost -**Current cost estimate:** 470 us -**Componentize savings:** 0 us -**Unify savings:** 0 us +**Current cost estimate:** 470 us/turn +**Componentize savings:** 0 us/turn +**Unify savings:** 0 us/turn **Recommended direction:** insufficient_data **Rationale:** FileItem: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. +**Struct field count (estimated):** 5 +**Struct frozen:** True + +## Struct shape (inferred from producer returns) + +_(no producers; cannot infer shape)_ ## Optimization candidates -_(none)_ +_(no optimization candidates generated)_ ## Verdict -FileItem: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. \ No newline at end of file +FileItem: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. + +## Evidence appendix diff --git a/docs/reports/code_path_audit/2026-06-22/aggregates/FileItems.dsl b/docs/reports/code_path_audit/2026-06-22/aggregates/FileItems.dsl index ce765c55..d4ff378d 100644 --- a/docs/reports/code_path_audit/2026-06-22/aggregates/FileItems.dsl +++ b/docs/reports/code_path_audit/2026-06-22/aggregates/FileItems.dsl @@ -10,17 +10,17 @@ \ === producers (0 items) === \ === consumers (3 items) === - "src.ai_client._build_file_context_text" "src\ai_client.py" 0 "consumer" fn-ref "src.ai_client._build_file_diff_text" "src\ai_client.py" 0 "consumer" fn-ref "src.ai_client._reread_file_items_result" "src\ai_client.py" 0 "consumer" fn-ref + "src.ai_client._build_file_context_text" "src\ai_client.py" 0 "consumer" fn-ref \ === access_pattern === "whole_struct" access-pattern \ === access_pattern_evidence (3 items) === - "src.ai_client._build_file_context_text" "whole_struct" 0 "low" ap-evidence "src.ai_client._build_file_diff_text" "whole_struct" 0 "low" ap-evidence "src.ai_client._reread_file_items_result" "whole_struct" 0 "low" ap-evidence + "src.ai_client._build_file_context_text" "whole_struct" 0 "low" ap-evidence \ === frequency === "per_turn" frequency diff --git a/docs/reports/code_path_audit/2026-06-22/aggregates/FileItems.md b/docs/reports/code_path_audit/2026-06-22/aggregates/FileItems.md index 4674273e..d67ca74e 100644 --- a/docs/reports/code_path_audit/2026-06-22/aggregates/FileItems.md +++ b/docs/reports/code_path_audit/2026-06-22/aggregates/FileItems.md @@ -8,12 +8,38 @@ - Producers: 0 - Consumers: 3 +- Distinct producer fqnames: 0 +- Distinct consumer fqnames: 3 +- Access pattern (aggregate): whole_struct +- Frequency (aggregate): per_turn +- Decomposition direction: hold +- Struct field count (estimated): 5 + +## Producers (0) + +_(none)_ + +## Consumers (3) + +### `src\ai_client.py` (3 consumers) + +- `src.ai_client._build_file_diff_text` (line 0) +- `src.ai_client._reread_file_items_result` (line 0) +- `src.ai_client._build_file_context_text` (line 0) + +## Field access matrix + +_(no field accesses detected)_ ## Access pattern **Dominant pattern:** whole_struct **Evidence count:** 3 +**Per-function pattern distribution:** + +- `whole_struct`: 3 functions (100%) + ## Frequency **Dominant frequency:** per_turn @@ -23,27 +49,55 @@ **Summary:** 0 producers, 3 consumers +| metric | value | +|---|---| +| total producers | 0 | +| result producers | 0 | +| total consumers | 3 | +| result consumers | 0 | + ## Type alias coverage **Summary:** 0 sites +| metric | value | +|---|---| +| total field-access sites | 0 | +| typed sites (canonical field) | 0 | +| untyped sites (wildcard) | 0 | + ## Cross-audit findings -| Audit script | Site count | Example | Note | -|---|---|---|---| +_(no cross-audit findings mapped to this aggregate)_ ## Decomposition cost -**Current cost estimate:** 470 us -**Componentize savings:** 0 us -**Unify savings:** 70 us +**Current cost estimate:** 470 us/turn +**Componentize savings:** 0 us/turn +**Unify savings:** 70 us/turn **Recommended direction:** hold **Rationale:** FileItems: access_pattern=whole_struct, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: hold because the current shape matches the access pattern. +**Struct field count (estimated):** 5 +**Struct frozen:** True + +## Struct shape (inferred from producer returns) + +_(no producers; cannot infer shape)_ ## Optimization candidates -_(none)_ +_(no optimization candidates generated)_ ## Verdict -FileItems: access_pattern=whole_struct, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: hold because the current shape matches the access pattern. \ No newline at end of file +FileItems: access_pattern=whole_struct, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: hold because the current shape matches the access pattern. + +## Evidence appendix + +### Access pattern evidence + +| function | pattern | field_accesses | confidence | +|---|---|---|---| +| `src.ai_client._build_file_diff_text` | `whole_struct` | | low | +| `src.ai_client._reread_file_items_result` | `whole_struct` | | low | +| `src.ai_client._build_file_context_text` | `whole_struct` | | low | diff --git a/docs/reports/code_path_audit/2026-06-22/aggregates/FileItems.tree b/docs/reports/code_path_audit/2026-06-22/aggregates/FileItems.tree index 9bd3710f..36a9ee45 100644 --- a/docs/reports/code_path_audit/2026-06-22/aggregates/FileItems.tree +++ b/docs/reports/code_path_audit/2026-06-22/aggregates/FileItems.tree @@ -3,9 +3,9 @@ Metadata: FileItems |- memory_dim: curation |- producers: [0] |- consumers: [3] -| |- src.ai_client._build_file_context_text (consumer) | |- src.ai_client._build_file_diff_text (consumer) | |- src.ai_client._reread_file_items_result (consumer) +| |- src.ai_client._build_file_context_text (consumer) |- access_pattern: whole_struct |- frequency: per_turn |- result_coverage: 0 producers, 3 consumers diff --git a/docs/reports/code_path_audit/2026-06-22/aggregates/History.md b/docs/reports/code_path_audit/2026-06-22/aggregates/History.md index 22e7d251..2fd6fc03 100644 --- a/docs/reports/code_path_audit/2026-06-22/aggregates/History.md +++ b/docs/reports/code_path_audit/2026-06-22/aggregates/History.md @@ -8,6 +8,24 @@ - Producers: 0 - Consumers: 0 +- Distinct producer fqnames: 0 +- Distinct consumer fqnames: 0 +- Access pattern (aggregate): mixed +- Frequency (aggregate): per_turn +- Decomposition direction: insufficient_data +- Struct field count (estimated): 5 + +## Producers (0) + +_(none)_ + +## Consumers (0) + +_(none)_ + +## Field access matrix + +_(no field accesses detected)_ ## Access pattern @@ -23,27 +41,47 @@ **Summary:** 0 producers, 0 consumers +| metric | value | +|---|---| +| total producers | 0 | +| result producers | 0 | +| total consumers | 0 | +| result consumers | 0 | + ## Type alias coverage **Summary:** 0 sites +| metric | value | +|---|---| +| total field-access sites | 0 | +| typed sites (canonical field) | 0 | +| untyped sites (wildcard) | 0 | + ## Cross-audit findings -| Audit script | Site count | Example | Note | -|---|---|---|---| +_(no cross-audit findings mapped to this aggregate)_ ## Decomposition cost -**Current cost estimate:** 470 us -**Componentize savings:** 0 us -**Unify savings:** 0 us +**Current cost estimate:** 470 us/turn +**Componentize savings:** 0 us/turn +**Unify savings:** 0 us/turn **Recommended direction:** insufficient_data **Rationale:** History: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. +**Struct field count (estimated):** 5 +**Struct frozen:** True + +## Struct shape (inferred from producer returns) + +_(no producers; cannot infer shape)_ ## Optimization candidates -_(none)_ +_(no optimization candidates generated)_ ## Verdict -History: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. \ No newline at end of file +History: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. + +## Evidence appendix diff --git a/docs/reports/code_path_audit/2026-06-22/aggregates/HistoryMessage.dsl b/docs/reports/code_path_audit/2026-06-22/aggregates/HistoryMessage.dsl index f46512e4..e089ec5b 100644 --- a/docs/reports/code_path_audit/2026-06-22/aggregates/HistoryMessage.dsl +++ b/docs/reports/code_path_audit/2026-06-22/aggregates/HistoryMessage.dsl @@ -10,15 +10,15 @@ \ === producers (0 items) === \ === consumers (2 items) === - "src.provider_state.append" "src\provider_state.py" 0 "consumer" fn-ref "src.provider_state.replace_all" "src\provider_state.py" 0 "consumer" fn-ref + "src.provider_state.append" "src\provider_state.py" 0 "consumer" fn-ref \ === access_pattern === "mixed" access-pattern \ === access_pattern_evidence (2 items) === - "src.provider_state.append" "mixed" 2 "high" ap-evidence "src.provider_state.replace_all" "mixed" 2 "high" ap-evidence + "src.provider_state.append" "mixed" 2 "high" ap-evidence \ === frequency === "per_turn" frequency diff --git a/docs/reports/code_path_audit/2026-06-22/aggregates/HistoryMessage.md b/docs/reports/code_path_audit/2026-06-22/aggregates/HistoryMessage.md index 5a0f532a..596ba0d4 100644 --- a/docs/reports/code_path_audit/2026-06-22/aggregates/HistoryMessage.md +++ b/docs/reports/code_path_audit/2026-06-22/aggregates/HistoryMessage.md @@ -8,12 +8,40 @@ - Producers: 0 - Consumers: 2 +- Distinct producer fqnames: 0 +- Distinct consumer fqnames: 2 +- Access pattern (aggregate): mixed +- Frequency (aggregate): per_turn +- Decomposition direction: insufficient_data +- Struct field count (estimated): 5 + +## Producers (0) + +_(none)_ + +## Consumers (2) + +### `src\provider_state.py` (2 consumers) + +- `src.provider_state.replace_all` (line 0) +- `src.provider_state.append` (line 0) + +## Field access matrix + +| consumer | lock | messages | +|---|---|---| +| `replace_all` | 1 | 1 | +| `append` | 1 | 1 | ## Access pattern **Dominant pattern:** mixed **Evidence count:** 2 +**Per-function pattern distribution:** + +- `mixed`: 2 functions (100%) + ## Frequency **Dominant frequency:** per_turn @@ -23,27 +51,54 @@ **Summary:** 0 producers, 2 consumers +| metric | value | +|---|---| +| total producers | 0 | +| result producers | 0 | +| total consumers | 2 | +| result consumers | 0 | + ## Type alias coverage **Summary:** 4 sites; 0 typed (0%); 4 untyped (100%) +| metric | value | +|---|---| +| total field-access sites | 4 | +| typed sites (canonical field) | 0 | +| untyped sites (wildcard) | 4 | + ## Cross-audit findings -| Audit script | Site count | Example | Note | -|---|---|---|---| +_(no cross-audit findings mapped to this aggregate)_ ## Decomposition cost -**Current cost estimate:** 470 us -**Componentize savings:** 0 us -**Unify savings:** 0 us +**Current cost estimate:** 470 us/turn +**Componentize savings:** 0 us/turn +**Unify savings:** 0 us/turn **Recommended direction:** insufficient_data **Rationale:** HistoryMessage: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. +**Struct field count (estimated):** 5 +**Struct frozen:** True + +## Struct shape (inferred from producer returns) + +_(no producers; cannot infer shape)_ ## Optimization candidates -_(none)_ +_(no optimization candidates generated)_ ## Verdict -HistoryMessage: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. \ No newline at end of file +HistoryMessage: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. + +## Evidence appendix + +### Access pattern evidence + +| function | pattern | field_accesses | confidence | +|---|---|---|---| +| `src.provider_state.replace_all` | `mixed` | `lock`=1, `messages`=1 | high | +| `src.provider_state.append` | `mixed` | `lock`=1, `messages`=1 | high | diff --git a/docs/reports/code_path_audit/2026-06-22/aggregates/HistoryMessage.tree b/docs/reports/code_path_audit/2026-06-22/aggregates/HistoryMessage.tree index 689ffadc..bde7cf4b 100644 --- a/docs/reports/code_path_audit/2026-06-22/aggregates/HistoryMessage.tree +++ b/docs/reports/code_path_audit/2026-06-22/aggregates/HistoryMessage.tree @@ -3,8 +3,8 @@ Metadata: HistoryMessage |- memory_dim: discussion |- producers: [0] |- consumers: [2] -| |- src.provider_state.append (consumer) | |- src.provider_state.replace_all (consumer) +| |- src.provider_state.append (consumer) |- access_pattern: mixed |- frequency: per_turn |- result_coverage: 0 producers, 2 consumers diff --git a/docs/reports/code_path_audit/2026-06-22/aggregates/Metadata.dsl b/docs/reports/code_path_audit/2026-06-22/aggregates/Metadata.dsl index 10e4dbaa..6d1868f3 100644 --- a/docs/reports/code_path_audit/2026-06-22/aggregates/Metadata.dsl +++ b/docs/reports/code_path_audit/2026-06-22/aggregates/Metadata.dsl @@ -8,170 +8,170 @@ "discussion" mem-dim \ === producers (77 items) === - "src.api_hook_client.wait_for_project_switch" "src\api_hook_client.py" 0 "producer" fn-ref - "src.ai_client._send_cli_round_result" "src\ai_client.py" 0 "producer" fn-ref - "src.app_controller.get_session_insights" "src\app_controller.py" 0 "producer" fn-ref - "src.app_controller._api_get_api_project" "src\app_controller.py" 0 "producer" fn-ref - "src.project_manager.load_project" "src\project_manager.py" 0 "producer" fn-ref - "src.app_controller.token_stats" "src\app_controller.py" 0 "producer" fn-ref - "src.api_hook_client.select_tab" "src\api_hook_client.py" 0 "producer" fn-ref - "src.app_controller._api_status" "src\app_controller.py" 0 "producer" fn-ref - "src.project_manager.migrate_from_legacy_config" "src\project_manager.py" 0 "producer" fn-ref - "src.api_hook_client.get_status" "src\api_hook_client.py" 0 "producer" fn-ref - "src.app_controller._api_get_performance" "src\app_controller.py" 0 "producer" fn-ref - "src.api_hook_client.set_value" "src\api_hook_client.py" 0 "producer" fn-ref - "src.app_controller._api_get_gui_state" "src\app_controller.py" 0 "producer" fn-ref + "src.api_hook_client.get_gui_diagnostics" "src\api_hook_client.py" 0 "producer" fn-ref "src.app_controller.get_gui_state" "src\app_controller.py" 0 "producer" fn-ref - "src.app_controller._api_token_stats" "src\app_controller.py" 0 "producer" fn-ref - "src.api_hook_client.get_warmup_status" "src\api_hook_client.py" 0 "producer" fn-ref - "src.api_hook_client.get_context_state" "src\api_hook_client.py" 0 "producer" fn-ref - "src.api_hook_client.get_gui_state" "src\api_hook_client.py" 0 "producer" fn-ref - "src.api_hook_client.select_list_item" "src\api_hook_client.py" 0 "producer" fn-ref - "src.app_controller.wait" "src\app_controller.py" 0 "producer" fn-ref - "src.app_controller.get_mma_status" "src\app_controller.py" 0 "producer" fn-ref - "src.models.to_dict" "src\models.py" 0 "producer" fn-ref - "src.api_hook_client.get_gui_health" "src\api_hook_client.py" 0 "producer" fn-ref - "src.api_hook_client.get_performance" "src\api_hook_client.py" 0 "producer" fn-ref - "src.app_controller._api_get_context" "src\app_controller.py" 0 "producer" fn-ref - "src.app_controller.get_context" "src\app_controller.py" 0 "producer" fn-ref - "src.app_controller.get_api_session" "src\app_controller.py" 0 "producer" fn-ref - "src.api_hook_client.post_session" "src\api_hook_client.py" 0 "producer" fn-ref + "src.app_controller._api_get_api_project" "src\app_controller.py" 0 "producer" fn-ref "src.api_hook_client.get_node_status" "src\api_hook_client.py" 0 "producer" fn-ref - "src.models._load_config_from_disk" "src\models.py" 0 "producer" fn-ref + "src.api_hook_client.post_session" "src\api_hook_client.py" 0 "producer" fn-ref + "src.api_hook_client.get_financial_metrics" "src\api_hook_client.py" 0 "producer" fn-ref + "src.api_hook_client.get_patch_status" "src\api_hook_client.py" 0 "producer" fn-ref + "src.app_controller._offload_entry_payload" "src\app_controller.py" 0 "producer" fn-ref + "src.ai_client._send_cli_round_result" "src\ai_client.py" 0 "producer" fn-ref + "src.api_hook_client.get_startup_timeline" "src\api_hook_client.py" 0 "producer" fn-ref + "src.api_hook_client.get_project" "src\api_hook_client.py" 0 "producer" fn-ref + "src.app_controller.get_session_insights" "src\app_controller.py" 0 "producer" fn-ref + "src.app_controller.generate" "src\app_controller.py" 0 "producer" fn-ref + "src.ai_client.get_token_stats" "src\ai_client.py" 0 "producer" fn-ref + "src.api_hook_client.drag" "src\api_hook_client.py" 0 "producer" fn-ref + "src.project_manager.flat_config" "src\project_manager.py" 0 "producer" fn-ref + "src.app_controller.get_api_session" "src\app_controller.py" 0 "producer" fn-ref + "src.app_controller.get_mma_status" "src\app_controller.py" 0 "producer" fn-ref + "src.project_manager.load_project" "src\project_manager.py" 0 "producer" fn-ref + "src.api_hook_client.apply_patch" "src\api_hook_client.py" 0 "producer" fn-ref + "src.api_hook_client.get_context_state" "src\api_hook_client.py" 0 "producer" fn-ref + "src.api_hook_client.get_status" "src\api_hook_client.py" 0 "producer" fn-ref + "src.project_manager.str_to_entry" "src\project_manager.py" 0 "producer" fn-ref + "src.project_manager.migrate_from_legacy_config" "src\project_manager.py" 0 "producer" fn-ref + "src.api_hook_client.post_project" "src\api_hook_client.py" 0 "producer" fn-ref + "src.app_controller._api_token_stats" "src\app_controller.py" 0 "producer" fn-ref + "src.app_controller.token_stats" "src\app_controller.py" 0 "producer" fn-ref + "src.app_controller.status" "src\app_controller.py" 0 "producer" fn-ref + "src.api_hook_client.get_system_telemetry" "src\api_hook_client.py" 0 "producer" fn-ref + "src.api_hook_client.push_event" "src\api_hook_client.py" 0 "producer" fn-ref + "src.api_hook_client.get_gui_state" "src\api_hook_client.py" 0 "producer" fn-ref + "src.app_controller._api_get_diagnostics" "src\app_controller.py" 0 "producer" fn-ref + "src.app_controller._api_get_api_session" "src\app_controller.py" 0 "producer" fn-ref + "src.api_hook_client.get_io_pool_status" "src\api_hook_client.py" 0 "producer" fn-ref + "src.app_controller.get_performance" "src\app_controller.py" 0 "producer" fn-ref + "src.api_hook_client.get_project_switch_status" "src\api_hook_client.py" 0 "producer" fn-ref + "src.models.to_dict" "src\models.py" 0 "producer" fn-ref + "src.app_controller.get_api_project" "src\app_controller.py" 0 "producer" fn-ref + "src.app_controller._api_get_session" "src\app_controller.py" 0 "producer" fn-ref + "src.app_controller.get_context" "src\app_controller.py" 0 "producer" fn-ref + "src.api_hook_client.click" "src\api_hook_client.py" 0 "producer" fn-ref + "src.api_hook_client.get_mma_workers" "src\api_hook_client.py" 0 "producer" fn-ref + "src.ai_client._load_credentials" "src\ai_client.py" 0 "producer" fn-ref + "src.api_hook_client.trigger_patch" "src\api_hook_client.py" 0 "producer" fn-ref + "src.api_hook_client.select_list_item" "src\api_hook_client.py" 0 "producer" fn-ref + "src.project_manager.load_history" "src\project_manager.py" 0 "producer" fn-ref + "src.api_hook_client.select_tab" "src\api_hook_client.py" 0 "producer" fn-ref "src.api_hook_client.reject_patch" "src\api_hook_client.py" 0 "producer" fn-ref "src.app_controller._api_generate" "src\app_controller.py" 0 "producer" fn-ref - "src.ai_client._dashscope_call" "src\ai_client.py" 0 "producer" fn-ref - "src.ai_client._add_bleed_derived" "src\ai_client.py" 0 "producer" fn-ref - "src.api_hook_client.get_startup_timeline" "src\api_hook_client.py" 0 "producer" fn-ref - "src.project_manager.default_discussion" "src\project_manager.py" 0 "producer" fn-ref - "src.api_hook_client.get_project_switch_status" "src\api_hook_client.py" 0 "producer" fn-ref - "src.api_hook_client.get_patch_status" "src\api_hook_client.py" 0 "producer" fn-ref - "src.api_hook_client.apply_patch" "src\api_hook_client.py" 0 "producer" fn-ref - "src.api_hook_client.get_project" "src\api_hook_client.py" 0 "producer" fn-ref - "src.api_hook_client.right_click" "src\api_hook_client.py" 0 "producer" fn-ref - "src.api_hook_client.push_event" "src\api_hook_client.py" 0 "producer" fn-ref - "src.api_hook_client.post_gui" "src\api_hook_client.py" 0 "producer" fn-ref - "src.api_hook_client.click" "src\api_hook_client.py" 0 "producer" fn-ref - "src.project_manager.flat_config" "src\project_manager.py" 0 "producer" fn-ref - "src.app_controller.get_api_project" "src\app_controller.py" 0 "producer" fn-ref - "src.app_controller.get_diagnostics" "src\app_controller.py" 0 "producer" fn-ref - "src.api_hook_client.get_financial_metrics" "src\api_hook_client.py" 0 "producer" fn-ref - "src.api_hook_client.get_io_pool_status" "src\api_hook_client.py" 0 "producer" fn-ref - "src.app_controller._api_get_api_session" "src\app_controller.py" 0 "producer" fn-ref - "src.api_hook_client.get_warmup_wait" "src\api_hook_client.py" 0 "producer" fn-ref - "src.ai_client._parse_tool_args_result" "src\ai_client.py" 0 "producer" fn-ref - "src.ai_client.get_gemini_cache_stats" "src\ai_client.py" 0 "producer" fn-ref - "src.app_controller.get_session" "src\app_controller.py" 0 "producer" fn-ref - "src.ai_client._content_block_to_dict" "src\ai_client.py" 0 "producer" fn-ref "src.app_controller.load_config" "src\app_controller.py" 0 "producer" fn-ref - "src.ai_client._load_credentials" "src\ai_client.py" 0 "producer" fn-ref - "src.api_hook_client.drag" "src\api_hook_client.py" 0 "producer" fn-ref - "src.api_hook_client.post_project" "src\api_hook_client.py" 0 "producer" fn-ref - "src.app_controller._api_get_diagnostics" "src\app_controller.py" 0 "producer" fn-ref - "src.ai_client.ollama_chat" "src\ai_client.py" 0 "producer" fn-ref - "src.api_hook_client.get_mma_status" "src\api_hook_client.py" 0 "producer" fn-ref - "src.api_hook_client.get_mma_workers" "src\api_hook_client.py" 0 "producer" fn-ref - "src.api_hook_client.get_system_telemetry" "src\api_hook_client.py" 0 "producer" fn-ref - "src.project_manager.load_history" "src\project_manager.py" 0 "producer" fn-ref - "src.api_hook_client.get_gui_diagnostics" "src\api_hook_client.py" 0 "producer" fn-ref - "src.api_hook_client.get_session" "src\api_hook_client.py" 0 "producer" fn-ref - "src.app_controller.get_performance" "src\app_controller.py" 0 "producer" fn-ref - "src.app_controller.status" "src\app_controller.py" 0 "producer" fn-ref - "src.app_controller._api_get_mma_status" "src\app_controller.py" 0 "producer" fn-ref - "src.ai_client.get_token_stats" "src\ai_client.py" 0 "producer" fn-ref - "src.app_controller.generate" "src\app_controller.py" 0 "producer" fn-ref + "src.ai_client.get_gemini_cache_stats" "src\ai_client.py" 0 "producer" fn-ref "src.project_manager.default_project" "src\project_manager.py" 0 "producer" fn-ref - "src.app_controller._api_get_session" "src\app_controller.py" 0 "producer" fn-ref - "src.app_controller._offload_entry_payload" "src\app_controller.py" 0 "producer" fn-ref - "src.api_hook_client.trigger_patch" "src\api_hook_client.py" 0 "producer" fn-ref - "src.project_manager.str_to_entry" "src\project_manager.py" 0 "producer" fn-ref + "src.app_controller.wait" "src\app_controller.py" 0 "producer" fn-ref + "src.app_controller._api_status" "src\app_controller.py" 0 "producer" fn-ref + "src.app_controller._api_get_mma_status" "src\app_controller.py" 0 "producer" fn-ref + "src.ai_client.ollama_chat" "src\ai_client.py" 0 "producer" fn-ref + "src.api_hook_client.wait_for_project_switch" "src\api_hook_client.py" 0 "producer" fn-ref + "src.ai_client._parse_tool_args_result" "src\ai_client.py" 0 "producer" fn-ref + "src.api_hook_client.get_mma_status" "src\api_hook_client.py" 0 "producer" fn-ref + "src.app_controller._api_get_context" "src\app_controller.py" 0 "producer" fn-ref + "src.api_hook_client.get_gui_health" "src\api_hook_client.py" 0 "producer" fn-ref + "src.models._load_config_from_disk" "src\models.py" 0 "producer" fn-ref + "src.api_hook_client.get_session" "src\api_hook_client.py" 0 "producer" fn-ref + "src.app_controller.get_session" "src\app_controller.py" 0 "producer" fn-ref + "src.app_controller._api_get_performance" "src\app_controller.py" 0 "producer" fn-ref + "src.api_hook_client.post_gui" "src\api_hook_client.py" 0 "producer" fn-ref + "src.ai_client._content_block_to_dict" "src\ai_client.py" 0 "producer" fn-ref + "src.api_hook_client.right_click" "src\api_hook_client.py" 0 "producer" fn-ref + "src.app_controller._api_get_gui_state" "src\app_controller.py" 0 "producer" fn-ref + "src.api_hook_client.get_performance" "src\api_hook_client.py" 0 "producer" fn-ref + "src.api_hook_client.get_warmup_wait" "src\api_hook_client.py" 0 "producer" fn-ref + "src.ai_client._add_bleed_derived" "src\ai_client.py" 0 "producer" fn-ref + "src.api_hook_client.set_value" "src\api_hook_client.py" 0 "producer" fn-ref + "src.app_controller.get_diagnostics" "src\app_controller.py" 0 "producer" fn-ref + "src.project_manager.default_discussion" "src\project_manager.py" 0 "producer" fn-ref + "src.ai_client._dashscope_call" "src\ai_client.py" 0 "producer" fn-ref + "src.api_hook_client.get_warmup_status" "src\api_hook_client.py" 0 "producer" fn-ref \ === consumers (35 items) === - "src.app_controller._offload_entry_payload" "src\app_controller.py" 0 "consumer" fn-ref - "src.aggregate.build_markdown_no_history" "src\aggregate.py" 0 "consumer" fn-ref - "src.app_controller._start_track_logic" "src\app_controller.py" 0 "consumer" fn-ref - "src.ai_client._strip_stale_file_refreshes" "src\ai_client.py" 0 "consumer" fn-ref - "src.project_manager.format_discussion" "src\project_manager.py" 0 "consumer" fn-ref - "src.ai_client._trim_anthropic_history" "src\ai_client.py" 0 "consumer" fn-ref - "src.project_manager.save_project" "src\project_manager.py" 0 "consumer" fn-ref - "src.ai_client._trim_minimax_history" "src\ai_client.py" 0 "consumer" fn-ref - "src.ai_client._estimate_prompt_tokens" "src\ai_client.py" 0 "consumer" fn-ref - "src.ai_client.ollama_chat" "src\ai_client.py" 0 "consumer" fn-ref - "src.project_manager.flat_config" "src\project_manager.py" 0 "consumer" fn-ref - "src.app_controller._on_comms_entry" "src\app_controller.py" 0 "consumer" fn-ref + "src.ai_client._add_history_cache_breakpoint" "src\ai_client.py" 0 "consumer" fn-ref "src.models.from_dict" "src\models.py" 0 "consumer" fn-ref "src.app_controller._start_track_logic_result" "src\app_controller.py" 0 "consumer" fn-ref + "src.project_manager.entry_to_str" "src\project_manager.py" 0 "consumer" fn-ref + "src.app_controller._on_comms_entry" "src\app_controller.py" 0 "consumer" fn-ref + "src.ai_client._trim_minimax_history" "src\ai_client.py" 0 "consumer" fn-ref + "src.aggregate.build_tier3_context" "src\aggregate.py" 0 "consumer" fn-ref + "src.ai_client.ollama_chat" "src\ai_client.py" 0 "consumer" fn-ref + "src.project_manager.flat_config" "src\project_manager.py" 0 "consumer" fn-ref + "src.ai_client._repair_minimax_history" "src\ai_client.py" 0 "consumer" fn-ref + "src.ai_client._estimate_message_tokens" "src\ai_client.py" 0 "consumer" fn-ref "src.ai_client._strip_private_keys" "src\ai_client.py" 0 "consumer" fn-ref "src.aggregate._build_files_section_from_items" "src\aggregate.py" 0 "consumer" fn-ref - "src.ai_client._dashscope_call" "src\ai_client.py" 0 "consumer" fn-ref - "src.ai_client._repair_deepseek_history" "src\ai_client.py" 0 "consumer" fn-ref - "src.ai_client._add_bleed_derived" "src\ai_client.py" 0 "consumer" fn-ref - "src.ai_client._add_history_cache_breakpoint" "src\ai_client.py" 0 "consumer" fn-ref - "src.project_manager.migrate_from_legacy_config" "src\project_manager.py" 0 "consumer" fn-ref - "src.ai_client._invalidate_token_estimate" "src\ai_client.py" 0 "consumer" fn-ref - "src.project_manager.entry_to_str" "src\project_manager.py" 0 "consumer" fn-ref - "src.ai_client._strip_cache_controls" "src\ai_client.py" 0 "consumer" fn-ref - "src.ai_client._repair_minimax_history" "src\ai_client.py" 0 "consumer" fn-ref - "src.ai_client._append_comms" "src\ai_client.py" 0 "consumer" fn-ref - "src.aggregate.build_tier3_context" "src\aggregate.py" 0 "consumer" fn-ref - "src.aggregate.build_markdown_from_items" "src\aggregate.py" 0 "consumer" fn-ref - "src.ai_client._pre_dispatch" "src\ai_client.py" 0 "consumer" fn-ref - "src.aggregate.run" "src\aggregate.py" 0 "consumer" fn-ref "src.models._save_config_to_disk" "src\models.py" 0 "consumer" fn-ref + "src.ai_client._repair_deepseek_history" "src\ai_client.py" 0 "consumer" fn-ref + "src.ai_client._pre_dispatch" "src\ai_client.py" 0 "consumer" fn-ref + "src.app_controller._start_track_logic" "src\app_controller.py" 0 "consumer" fn-ref + "src.ai_client._estimate_prompt_tokens" "src\ai_client.py" 0 "consumer" fn-ref + "src.project_manager.save_project" "src\project_manager.py" 0 "consumer" fn-ref "src.ai_client._repair_anthropic_history" "src\ai_client.py" 0 "consumer" fn-ref - "src.ai_client._estimate_message_tokens" "src\ai_client.py" 0 "consumer" fn-ref + "src.project_manager.migrate_from_legacy_config" "src\project_manager.py" 0 "consumer" fn-ref + "src.aggregate.run" "src\aggregate.py" 0 "consumer" fn-ref "src.app_controller._refresh_api_metrics" "src\app_controller.py" 0 "consumer" fn-ref + "src.project_manager.format_discussion" "src\project_manager.py" 0 "consumer" fn-ref + "src.aggregate.build_markdown_from_items" "src\aggregate.py" 0 "consumer" fn-ref + "src.aggregate.build_markdown_no_history" "src\aggregate.py" 0 "consumer" fn-ref + "src.app_controller._offload_entry_payload" "src\app_controller.py" 0 "consumer" fn-ref + "src.ai_client._add_bleed_derived" "src\ai_client.py" 0 "consumer" fn-ref + "src.ai_client._trim_anthropic_history" "src\ai_client.py" 0 "consumer" fn-ref "src.ai_client._execute_single_tool_call_async" "src\ai_client.py" 0 "consumer" fn-ref + "src.ai_client._dashscope_call" "src\ai_client.py" 0 "consumer" fn-ref + "src.ai_client._invalidate_token_estimate" "src\ai_client.py" 0 "consumer" fn-ref + "src.ai_client._strip_stale_file_refreshes" "src\ai_client.py" 0 "consumer" fn-ref + "src.ai_client._strip_cache_controls" "src\ai_client.py" 0 "consumer" fn-ref + "src.ai_client._append_comms" "src\ai_client.py" 0 "consumer" fn-ref \ === access_pattern === "whole_struct" access-pattern \ === access_pattern_evidence (35 items) === - "src.app_controller._offload_entry_payload" "whole_struct" 0 "low" ap-evidence - "src.aggregate.build_markdown_no_history" "whole_struct" 0 "low" ap-evidence - "src.app_controller._start_track_logic" "mixed" 2 "high" ap-evidence - "src.ai_client._strip_stale_file_refreshes" "whole_struct" 0 "low" ap-evidence - "src.project_manager.format_discussion" "whole_struct" 0 "low" ap-evidence - "src.ai_client._trim_anthropic_history" "whole_struct" 1 "high" ap-evidence - "src.project_manager.save_project" "mixed" 2 "high" ap-evidence - "src.ai_client._trim_minimax_history" "whole_struct" 1 "high" ap-evidence - "src.ai_client._estimate_prompt_tokens" "whole_struct" 0 "low" ap-evidence - "src.ai_client.ollama_chat" "whole_struct" 0 "low" ap-evidence - "src.project_manager.flat_config" "whole_struct" 1 "high" ap-evidence - "src.app_controller._on_comms_entry" "field_by_field" 10 "high" ap-evidence + "src.ai_client._add_history_cache_breakpoint" "whole_struct" 0 "low" ap-evidence "src.models.from_dict" "mixed" 2 "high" ap-evidence "src.app_controller._start_track_logic_result" "field_by_field" 17 "high" ap-evidence + "src.project_manager.entry_to_str" "whole_struct" 1 "high" ap-evidence + "src.app_controller._on_comms_entry" "field_by_field" 10 "high" ap-evidence + "src.ai_client._trim_minimax_history" "whole_struct" 1 "high" ap-evidence + "src.aggregate.build_tier3_context" "whole_struct" 0 "low" ap-evidence + "src.ai_client.ollama_chat" "whole_struct" 0 "low" ap-evidence + "src.project_manager.flat_config" "whole_struct" 1 "high" ap-evidence + "src.ai_client._repair_minimax_history" "whole_struct" 1 "high" ap-evidence + "src.ai_client._estimate_message_tokens" "mixed" 2 "high" ap-evidence "src.ai_client._strip_private_keys" "whole_struct" 0 "low" ap-evidence "src.aggregate._build_files_section_from_items" "whole_struct" 0 "low" ap-evidence - "src.ai_client._dashscope_call" "whole_struct" 0 "low" ap-evidence - "src.ai_client._repair_deepseek_history" "whole_struct" 1 "high" ap-evidence - "src.ai_client._add_bleed_derived" "field_by_field" 9 "high" ap-evidence - "src.ai_client._add_history_cache_breakpoint" "whole_struct" 0 "low" ap-evidence - "src.project_manager.migrate_from_legacy_config" "whole_struct" 1 "high" ap-evidence - "src.ai_client._invalidate_token_estimate" "whole_struct" 1 "high" ap-evidence - "src.project_manager.entry_to_str" "whole_struct" 1 "high" ap-evidence - "src.ai_client._strip_cache_controls" "whole_struct" 0 "low" ap-evidence - "src.ai_client._repair_minimax_history" "whole_struct" 1 "high" ap-evidence - "src.ai_client._append_comms" "whole_struct" 0 "low" ap-evidence - "src.aggregate.build_tier3_context" "whole_struct" 0 "low" ap-evidence - "src.aggregate.build_markdown_from_items" "whole_struct" 0 "low" ap-evidence - "src.ai_client._pre_dispatch" "whole_struct" 0 "low" ap-evidence - "src.aggregate.run" "field_by_field" 3 "high" ap-evidence "src.models._save_config_to_disk" "whole_struct" 0 "low" ap-evidence + "src.ai_client._repair_deepseek_history" "whole_struct" 1 "high" ap-evidence + "src.ai_client._pre_dispatch" "whole_struct" 0 "low" ap-evidence + "src.app_controller._start_track_logic" "mixed" 2 "high" ap-evidence + "src.ai_client._estimate_prompt_tokens" "whole_struct" 0 "low" ap-evidence + "src.project_manager.save_project" "mixed" 2 "high" ap-evidence "src.ai_client._repair_anthropic_history" "whole_struct" 1 "high" ap-evidence - "src.ai_client._estimate_message_tokens" "mixed" 2 "high" ap-evidence + "src.project_manager.migrate_from_legacy_config" "whole_struct" 1 "high" ap-evidence + "src.aggregate.run" "field_by_field" 3 "high" ap-evidence "src.app_controller._refresh_api_metrics" "field_by_field" 11 "high" ap-evidence + "src.project_manager.format_discussion" "whole_struct" 0 "low" ap-evidence + "src.aggregate.build_markdown_from_items" "whole_struct" 0 "low" ap-evidence + "src.aggregate.build_markdown_no_history" "whole_struct" 0 "low" ap-evidence + "src.app_controller._offload_entry_payload" "whole_struct" 0 "low" ap-evidence + "src.ai_client._add_bleed_derived" "field_by_field" 9 "high" ap-evidence + "src.ai_client._trim_anthropic_history" "whole_struct" 1 "high" ap-evidence "src.ai_client._execute_single_tool_call_async" "mixed" 2 "high" ap-evidence + "src.ai_client._dashscope_call" "whole_struct" 0 "low" ap-evidence + "src.ai_client._invalidate_token_estimate" "whole_struct" 1 "high" ap-evidence + "src.ai_client._strip_stale_file_refreshes" "whole_struct" 0 "low" ap-evidence + "src.ai_client._strip_cache_controls" "whole_struct" 0 "low" ap-evidence + "src.ai_client._append_comms" "whole_struct" 0 "low" ap-evidence \ === frequency === "per_turn" frequency \ === frequency_evidence (5 items) === - "src.api_hook_client.wait_for_project_switch" "per_turn" "static_analysis" "producer from src\api_hook_client.py" freq-evidence - "src.ai_client._send_cli_round_result" "per_turn" "static_analysis" "producer from src\ai_client.py" freq-evidence - "src.app_controller.get_session_insights" "per_turn" "static_analysis" "producer from src\app_controller.py" freq-evidence + "src.api_hook_client.get_gui_diagnostics" "per_turn" "static_analysis" "producer from src\api_hook_client.py" freq-evidence + "src.app_controller.get_gui_state" "per_turn" "static_analysis" "producer from src\app_controller.py" freq-evidence "src.app_controller._api_get_api_project" "per_turn" "static_analysis" "producer from src\app_controller.py" freq-evidence - "src.project_manager.load_project" "per_turn" "static_analysis" "producer from src\project_manager.py" freq-evidence + "src.api_hook_client.get_node_status" "per_turn" "static_analysis" "producer from src\api_hook_client.py" freq-evidence + "src.api_hook_client.post_session" "per_turn" "static_analysis" "producer from src\api_hook_client.py" freq-evidence \ === result_coverage === 77 77 35 0 result-coverage diff --git a/docs/reports/code_path_audit/2026-06-22/aggregates/Metadata.md b/docs/reports/code_path_audit/2026-06-22/aggregates/Metadata.md index 9037896b..cc461310 100644 --- a/docs/reports/code_path_audit/2026-06-22/aggregates/Metadata.md +++ b/docs/reports/code_path_audit/2026-06-22/aggregates/Metadata.md @@ -8,43 +8,372 @@ - Producers: 77 - Consumers: 35 +- Distinct producer fqnames: 77 +- Distinct consumer fqnames: 35 +- Access pattern (aggregate): whole_struct +- Frequency (aggregate): per_turn +- Decomposition direction: hold +- Struct field count (estimated): 10 + +## Producers (77) + +### `src\ai_client.py` (9 producers) + +- `src.ai_client._send_cli_round_result` (line 0) +- `src.ai_client.get_token_stats` (line 0) +- `src.ai_client._load_credentials` (line 0) +- `src.ai_client.get_gemini_cache_stats` (line 0) +- `src.ai_client.ollama_chat` (line 0) +- `src.ai_client._parse_tool_args_result` (line 0) +- `src.ai_client._content_block_to_dict` (line 0) +- `src.ai_client._add_bleed_derived` (line 0) +- `src.ai_client._dashscope_call` (line 0) + +### `src\api_hook_client.py` (33 producers) + +- `src.api_hook_client.get_gui_diagnostics` (line 0) +- `src.api_hook_client.get_node_status` (line 0) +- `src.api_hook_client.post_session` (line 0) +- `src.api_hook_client.get_financial_metrics` (line 0) +- `src.api_hook_client.get_patch_status` (line 0) +- `src.api_hook_client.get_startup_timeline` (line 0) +- `src.api_hook_client.get_project` (line 0) +- `src.api_hook_client.drag` (line 0) +- `src.api_hook_client.apply_patch` (line 0) +- `src.api_hook_client.get_context_state` (line 0) +- `src.api_hook_client.get_status` (line 0) +- `src.api_hook_client.post_project` (line 0) +- `src.api_hook_client.get_system_telemetry` (line 0) +- `src.api_hook_client.push_event` (line 0) +- `src.api_hook_client.get_gui_state` (line 0) +- `src.api_hook_client.get_io_pool_status` (line 0) +- `src.api_hook_client.get_project_switch_status` (line 0) +- `src.api_hook_client.click` (line 0) +- `src.api_hook_client.get_mma_workers` (line 0) +- `src.api_hook_client.trigger_patch` (line 0) +- `src.api_hook_client.select_list_item` (line 0) +- `src.api_hook_client.select_tab` (line 0) +- `src.api_hook_client.reject_patch` (line 0) +- `src.api_hook_client.wait_for_project_switch` (line 0) +- `src.api_hook_client.get_mma_status` (line 0) +- `src.api_hook_client.get_gui_health` (line 0) +- `src.api_hook_client.get_session` (line 0) +- `src.api_hook_client.post_gui` (line 0) +- `src.api_hook_client.right_click` (line 0) +- `src.api_hook_client.get_performance` (line 0) +- `src.api_hook_client.get_warmup_wait` (line 0) +- `src.api_hook_client.set_value` (line 0) +- `src.api_hook_client.get_warmup_status` (line 0) + +### `src\app_controller.py` (26 producers) + +- `src.app_controller.get_gui_state` (line 0) +- `src.app_controller._api_get_api_project` (line 0) +- `src.app_controller._offload_entry_payload` (line 0) +- `src.app_controller.get_session_insights` (line 0) +- `src.app_controller.generate` (line 0) +- `src.app_controller.get_api_session` (line 0) +- `src.app_controller.get_mma_status` (line 0) +- `src.app_controller._api_token_stats` (line 0) +- `src.app_controller.token_stats` (line 0) +- `src.app_controller.status` (line 0) +- `src.app_controller._api_get_diagnostics` (line 0) +- `src.app_controller._api_get_api_session` (line 0) +- `src.app_controller.get_performance` (line 0) +- `src.app_controller.get_api_project` (line 0) +- `src.app_controller._api_get_session` (line 0) +- `src.app_controller.get_context` (line 0) +- `src.app_controller._api_generate` (line 0) +- `src.app_controller.load_config` (line 0) +- `src.app_controller.wait` (line 0) +- `src.app_controller._api_status` (line 0) +- `src.app_controller._api_get_mma_status` (line 0) +- `src.app_controller._api_get_context` (line 0) +- `src.app_controller.get_session` (line 0) +- `src.app_controller._api_get_performance` (line 0) +- `src.app_controller._api_get_gui_state` (line 0) +- `src.app_controller.get_diagnostics` (line 0) + +### `src\models.py` (2 producers) + +- `src.models.to_dict` (line 0) +- `src.models._load_config_from_disk` (line 0) + +### `src\project_manager.py` (7 producers) + +- `src.project_manager.flat_config` (line 0) +- `src.project_manager.load_project` (line 0) +- `src.project_manager.str_to_entry` (line 0) +- `src.project_manager.migrate_from_legacy_config` (line 0) +- `src.project_manager.load_history` (line 0) +- `src.project_manager.default_project` (line 0) +- `src.project_manager.default_discussion` (line 0) + +## Consumers (35) + +### `src\aggregate.py` (5 consumers) + +- `src.aggregate.build_tier3_context` (line 0) +- `src.aggregate._build_files_section_from_items` (line 0) +- `src.aggregate.run` (line 0) +- `src.aggregate.build_markdown_from_items` (line 0) +- `src.aggregate.build_markdown_no_history` (line 0) + +### `src\ai_client.py` (18 consumers) + +- `src.ai_client._add_history_cache_breakpoint` (line 0) +- `src.ai_client._trim_minimax_history` (line 0) +- `src.ai_client.ollama_chat` (line 0) +- `src.ai_client._repair_minimax_history` (line 0) +- `src.ai_client._estimate_message_tokens` (line 0) +- `src.ai_client._strip_private_keys` (line 0) +- `src.ai_client._repair_deepseek_history` (line 0) +- `src.ai_client._pre_dispatch` (line 0) +- `src.ai_client._estimate_prompt_tokens` (line 0) +- `src.ai_client._repair_anthropic_history` (line 0) +- `src.ai_client._add_bleed_derived` (line 0) +- `src.ai_client._trim_anthropic_history` (line 0) +- `src.ai_client._execute_single_tool_call_async` (line 0) +- `src.ai_client._dashscope_call` (line 0) +- `src.ai_client._invalidate_token_estimate` (line 0) +- `src.ai_client._strip_stale_file_refreshes` (line 0) +- `src.ai_client._strip_cache_controls` (line 0) +- `src.ai_client._append_comms` (line 0) + +### `src\app_controller.py` (5 consumers) + +- `src.app_controller._start_track_logic_result` (line 0) +- `src.app_controller._on_comms_entry` (line 0) +- `src.app_controller._start_track_logic` (line 0) +- `src.app_controller._refresh_api_metrics` (line 0) +- `src.app_controller._offload_entry_payload` (line 0) + +### `src\models.py` (2 consumers) + +- `src.models.from_dict` (line 0) +- `src.models._save_config_to_disk` (line 0) + +### `src\project_manager.py` (5 consumers) + +- `src.project_manager.entry_to_str` (line 0) +- `src.project_manager.flat_config` (line 0) +- `src.project_manager.save_project` (line 0) +- `src.project_manager.migrate_from_legacy_config` (line 0) +- `src.project_manager.format_discussion` (line 0) + +## Field access matrix + +| consumer | _est_tokens | _gemini_cache_text | _offload_entry_payload | _pending_comms | _pending_comms_lock | _pending_gui_tasks | _pending_gui_tasks_lock | _pending_history_adds | _pending_history_adds_lock | _recalculate_session_usage | _start_track_logic_result | _token_history | _token_stats | _topological_sort_tickets_result | _update_cached_stats | active_discussion | active_project_path | active_project_root | ai_status | append | +|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---| +| `_add_history_cache_breakpoint` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `from_dict` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `_start_track_logic_result` | . | . | . | . | . | 2 | 2 | . | . | . | . | . | . | 1 | . | 1 | 1 | 1 | 4 | . | +| `entry_to_str` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `_on_comms_entry` | . | . | 1 | 1 | 1 | . | . | 4 | 4 | . | . | 1 | . | . | . | . | . | . | . | . | +| `_trim_minimax_history` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `build_tier3_context` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `ollama_chat` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `flat_config` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `_repair_minimax_history` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | 1 | +| `_estimate_message_tokens` | 1 | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `_strip_private_keys` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `_build_files_section_from_items` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `_save_config_to_disk` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `_repair_deepseek_history` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | 1 | +| `_pre_dispatch` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `_start_track_logic` | . | . | . | . | . | . | . | . | . | . | 1 | . | . | . | . | . | . | . | 1 | . | +| `_estimate_prompt_tokens` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `save_project` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `_repair_anthropic_history` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | 1 | +| `migrate_from_legacy_config` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `run` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `_refresh_api_metrics` | . | 1 | . | . | . | . | . | . | . | 1 | . | . | 1 | . | 1 | . | . | . | . | . | +| `format_discussion` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `build_markdown_from_items` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `build_markdown_no_history` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `_offload_entry_payload` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `_add_bleed_derived` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `_trim_anthropic_history` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `_execute_single_tool_call_async` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `_dashscope_call` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `_invalidate_token_estimate` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `_strip_stale_file_refreshes` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `_strip_cache_controls` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | +| `_append_comms` | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | . | + +_... 33 more fields_ ## Access pattern **Dominant pattern:** whole_struct **Evidence count:** 35 +**Per-function pattern distribution:** + +- `whole_struct`: 25 functions (71%) +- `mixed`: 5 functions (14%) +- `field_by_field`: 5 functions (14%) + ## Frequency **Dominant frequency:** per_turn **Evidence count:** 5 +**Per-function frequency distribution:** + +- `per_turn`: 5 functions + ## Result coverage **Summary:** 77 producers, 35 consumers +| metric | value | +|---|---| +| total producers | 77 | +| result producers | 77 | +| total consumers | 35 | +| result consumers | 0 | + ## Type alias coverage **Summary:** 130 sites; 0 typed (0%); 130 untyped (100%) +| metric | value | +|---|---| +| total field-access sites | 130 | +| typed sites (canonical field) | 0 | +| untyped sites (wildcard) | 130 | + ## Cross-audit findings -| Audit script | Site count | Example | Note | -|---|---|---|---| -| audit_optional_in_3_files | 76 | src\ai_client.py:159 | 76 sites | +| bucket | audit script | site count | example file | example line | note | +|---|---|---|---|---|---| +| optional_in_baseline | `audit_optional_in_3_files` | 76 | `src\ai_client.py` | 159 | 76 sites | ## Decomposition cost -**Current cost estimate:** 720 us -**Componentize savings:** 0 us -**Unify savings:** 0 us +**Current cost estimate:** 720 us/turn +**Componentize savings:** 0 us/turn +**Unify savings:** 0 us/turn **Recommended direction:** hold **Rationale:** Metadata: access_pattern=whole_struct, frequency=per_turn, struct_field_count=10, struct_frozen=True. Recommended: hold because the current shape matches the access pattern. +**Struct field count (estimated):** 10 +**Struct frozen:** True + +## Struct shape (inferred from producer returns) + +| field | access count | access pattern | +|---|---|---| +| `get` | 10 | hot | +| `pop` | 3 | hot | +| `append` | 3 | hot | +| `ai_status` | 2 | used | +| `session_usage` | 2 | used | +| `files` | 2 | used | +| `content` | 1 | used | +| `marker` | 1 | used | +| `context_files` | 1 | used | +| `_pending_gui_tasks_lock` | 1 | used | +| `_topological_sort_tickets_result` | 1 | used | +| `active_project_root` | 1 | used | +| `event_queue` | 1 | used | +| `engines` | 1 | used | +| `project` | 1 | used | +| `active_discussion` | 1 | used | +| `submit_io` | 1 | used | +| `tracks` | 1 | used | +| `config` | 1 | used | +| `mma_tier_usage` | 1 | used | +| `_pending_gui_tasks` | 1 | used | +| `mma_step_mode` | 1 | used | +| `active_project_path` | 1 | used | +| `local_ts` | 1 | used | +| `_offload_entry_payload` | 1 | used | +| `ui_auto_add_history` | 1 | used | +| `_pending_comms_lock` | 1 | used | +| `_pending_history_adds_lock` | 1 | used | +| `_token_history` | 1 | used | +| `_pending_comms` | 1 | used | +| `_pending_history_adds` | 1 | used | +| `_est_tokens` | 1 | used | +| `_start_track_logic_result` | 1 | used | +| `discussion` | 1 | used | +| `output` | 1 | used | +| `latency` | 1 | used | +| `_recalculate_session_usage` | 1 | used | +| `_token_stats` | 1 | used | +| `_gemini_cache_text` | 1 | used | +| `vendor_quota` | 1 | used | +| `last_error` | 1 | used | +| `error` | 1 | used | +| `_update_cached_stats` | 1 | used | +| `usage` | 1 | used | +| `estimated_prompt_tokens` | 1 | used | +| `max_prompt_tokens` | 1 | used | +| `utilization_pct` | 1 | used | +| `headroom` | 1 | used | +| `would_trim` | 1 | used | +| `sys_tokens` | 1 | used | +| `tool_tokens` | 1 | used | +| `history_tokens` | 1 | used | +| `items` | 1 | used | ## Optimization candidates -_(none)_ +_(no optimization candidates generated)_ ## Verdict -Metadata: access_pattern=whole_struct, frequency=per_turn, struct_field_count=10, struct_frozen=True. Recommended: hold because the current shape matches the access pattern. \ No newline at end of file +Metadata: access_pattern=whole_struct, frequency=per_turn, struct_field_count=10, struct_frozen=True. Recommended: hold because the current shape matches the access pattern. + +## Evidence appendix + +### Access pattern evidence + +| function | pattern | field_accesses | confidence | +|---|---|---|---| +| `src.ai_client._add_history_cache_breakpoint` | `whole_struct` | | low | +| `src.models.from_dict` | `mixed` | `content`=1, `marker`=1 | high | +| `src.app_controller._start_track_logic_result` | `field_by_field` | `ai_status`=4, `context_files`=1, `get`=3, `_pending_gui_tasks_lock`=2, `_topological_sort_tickets_result`=1, `active_project_root`=1, `event_queue`=1, `engines`=1, `project`=1, `active_discussion`=1 (+7 more) | high | +| `src.project_manager.entry_to_str` | `whole_struct` | `get`=4 | high | +| `src.app_controller._on_comms_entry` | `field_by_field` | `local_ts`=1, `_offload_entry_payload`=1, `get`=7, `ui_auto_add_history`=3, `_pending_comms_lock`=1, `session_usage`=5, `_pending_history_adds_lock`=4, `_token_history`=1, `_pending_comms`=1, `_pending_history_adds`=4 | high | +| `src.ai_client._trim_minimax_history` | `whole_struct` | `pop`=4 | high | +| `src.aggregate.build_tier3_context` | `whole_struct` | | low | +| `src.ai_client.ollama_chat` | `whole_struct` | | low | +| `src.project_manager.flat_config` | `whole_struct` | `get`=7 | high | +| `src.ai_client._repair_minimax_history` | `whole_struct` | `append`=1 | high | +| `src.ai_client._estimate_message_tokens` | `mixed` | `_est_tokens`=1, `get`=2 | high | +| `src.ai_client._strip_private_keys` | `whole_struct` | | low | +| `src.aggregate._build_files_section_from_items` | `whole_struct` | | low | +| `src.models._save_config_to_disk` | `whole_struct` | | low | +| `src.ai_client._repair_deepseek_history` | `whole_struct` | `append`=1 | high | +| `src.ai_client._pre_dispatch` | `whole_struct` | | low | +| `src.app_controller._start_track_logic` | `mixed` | `_start_track_logic_result`=1, `ai_status`=1 | high | +| `src.ai_client._estimate_prompt_tokens` | `whole_struct` | | low | +| `src.project_manager.save_project` | `mixed` | `discussion`=2, `files`=3 | high | +| `src.ai_client._repair_anthropic_history` | `whole_struct` | `append`=1 | high | +| `src.project_manager.migrate_from_legacy_config` | `whole_struct` | `get`=2 | high | +| `src.aggregate.run` | `field_by_field` | `output`=1, `files`=2, `get`=7 | high | +| `src.app_controller._refresh_api_metrics` | `field_by_field` | `latency`=1, `_recalculate_session_usage`=1, `_token_stats`=1, `get`=2, `_gemini_cache_text`=1, `vendor_quota`=1, `last_error`=1, `error`=2, `_update_cached_stats`=1, `session_usage`=2 (+1 more) | high | +| `src.project_manager.format_discussion` | `whole_struct` | | low | +| `src.aggregate.build_markdown_from_items` | `whole_struct` | | low | +| `src.aggregate.build_markdown_no_history` | `whole_struct` | | low | +| `src.app_controller._offload_entry_payload` | `whole_struct` | | low | +| `src.ai_client._add_bleed_derived` | `field_by_field` | `estimated_prompt_tokens`=1, `max_prompt_tokens`=1, `utilization_pct`=1, `headroom`=1, `would_trim`=1, `sys_tokens`=1, `tool_tokens`=1, `history_tokens`=1, `get`=3 | high | +| `src.ai_client._trim_anthropic_history` | `whole_struct` | `pop`=5 | high | +| `src.ai_client._execute_single_tool_call_async` | `mixed` | `get`=2, `items`=1 | high | +| `src.ai_client._dashscope_call` | `whole_struct` | | low | +| `src.ai_client._invalidate_token_estimate` | `whole_struct` | `pop`=1 | high | +| `src.ai_client._strip_stale_file_refreshes` | `whole_struct` | | low | +| `src.ai_client._strip_cache_controls` | `whole_struct` | | low | +| `src.ai_client._append_comms` | `whole_struct` | | low | + +### Frequency evidence + +| function | frequency | source | note | +|---|---|---|---| +| `src.api_hook_client.get_gui_diagnostics` | `per_turn` | `static_analysis` | producer from src\api_hook_client.py | +| `src.app_controller.get_gui_state` | `per_turn` | `static_analysis` | producer from src\app_controller.py | +| `src.app_controller._api_get_api_project` | `per_turn` | `static_analysis` | producer from src\app_controller.py | +| `src.api_hook_client.get_node_status` | `per_turn` | `static_analysis` | producer from src\api_hook_client.py | +| `src.api_hook_client.post_session` | `per_turn` | `static_analysis` | producer from src\api_hook_client.py | diff --git a/docs/reports/code_path_audit/2026-06-22/aggregates/Metadata.tree b/docs/reports/code_path_audit/2026-06-22/aggregates/Metadata.tree index 9477b7e9..76bf6404 100644 --- a/docs/reports/code_path_audit/2026-06-22/aggregates/Metadata.tree +++ b/docs/reports/code_path_audit/2026-06-22/aggregates/Metadata.tree @@ -2,119 +2,119 @@ Metadata: Metadata |- kind: typealias |- memory_dim: discussion |- producers: [77] -| |- src.api_hook_client.wait_for_project_switch (producer) -| |- src.ai_client._send_cli_round_result (producer) -| |- src.app_controller.get_session_insights (producer) -| |- src.app_controller._api_get_api_project (producer) -| |- src.project_manager.load_project (producer) -| |- src.app_controller.token_stats (producer) -| |- src.api_hook_client.select_tab (producer) -| |- src.app_controller._api_status (producer) -| |- src.project_manager.migrate_from_legacy_config (producer) -| |- src.api_hook_client.get_status (producer) -| |- src.app_controller._api_get_performance (producer) -| |- src.api_hook_client.set_value (producer) -| |- src.app_controller._api_get_gui_state (producer) +| |- src.api_hook_client.get_gui_diagnostics (producer) | |- src.app_controller.get_gui_state (producer) -| |- src.app_controller._api_token_stats (producer) -| |- src.api_hook_client.get_warmup_status (producer) -| |- src.api_hook_client.get_context_state (producer) -| |- src.api_hook_client.get_gui_state (producer) -| |- src.api_hook_client.select_list_item (producer) -| |- src.app_controller.wait (producer) -| |- src.app_controller.get_mma_status (producer) -| |- src.models.to_dict (producer) -| |- src.api_hook_client.get_gui_health (producer) -| |- src.api_hook_client.get_performance (producer) -| |- src.app_controller._api_get_context (producer) -| |- src.app_controller.get_context (producer) -| |- src.app_controller.get_api_session (producer) -| |- src.api_hook_client.post_session (producer) +| |- src.app_controller._api_get_api_project (producer) | |- src.api_hook_client.get_node_status (producer) -| |- src.models._load_config_from_disk (producer) +| |- src.api_hook_client.post_session (producer) +| |- src.api_hook_client.get_financial_metrics (producer) +| |- src.api_hook_client.get_patch_status (producer) +| |- src.app_controller._offload_entry_payload (producer) +| |- src.ai_client._send_cli_round_result (producer) +| |- src.api_hook_client.get_startup_timeline (producer) +| |- src.api_hook_client.get_project (producer) +| |- src.app_controller.get_session_insights (producer) +| |- src.app_controller.generate (producer) +| |- src.ai_client.get_token_stats (producer) +| |- src.api_hook_client.drag (producer) +| |- src.project_manager.flat_config (producer) +| |- src.app_controller.get_api_session (producer) +| |- src.app_controller.get_mma_status (producer) +| |- src.project_manager.load_project (producer) +| |- src.api_hook_client.apply_patch (producer) +| |- src.api_hook_client.get_context_state (producer) +| |- src.api_hook_client.get_status (producer) +| |- src.project_manager.str_to_entry (producer) +| |- src.project_manager.migrate_from_legacy_config (producer) +| |- src.api_hook_client.post_project (producer) +| |- src.app_controller._api_token_stats (producer) +| |- src.app_controller.token_stats (producer) +| |- src.app_controller.status (producer) +| |- src.api_hook_client.get_system_telemetry (producer) +| |- src.api_hook_client.push_event (producer) +| |- src.api_hook_client.get_gui_state (producer) +| |- src.app_controller._api_get_diagnostics (producer) +| |- src.app_controller._api_get_api_session (producer) +| |- src.api_hook_client.get_io_pool_status (producer) +| |- src.app_controller.get_performance (producer) +| |- src.api_hook_client.get_project_switch_status (producer) +| |- src.models.to_dict (producer) +| |- src.app_controller.get_api_project (producer) +| |- src.app_controller._api_get_session (producer) +| |- src.app_controller.get_context (producer) +| |- src.api_hook_client.click (producer) +| |- src.api_hook_client.get_mma_workers (producer) +| |- src.ai_client._load_credentials (producer) +| |- src.api_hook_client.trigger_patch (producer) +| |- src.api_hook_client.select_list_item (producer) +| |- src.project_manager.load_history (producer) +| |- src.api_hook_client.select_tab (producer) | |- src.api_hook_client.reject_patch (producer) | |- src.app_controller._api_generate (producer) -| |- src.ai_client._dashscope_call (producer) -| |- src.ai_client._add_bleed_derived (producer) -| |- src.api_hook_client.get_startup_timeline (producer) -| |- src.project_manager.default_discussion (producer) -| |- src.api_hook_client.get_project_switch_status (producer) -| |- src.api_hook_client.get_patch_status (producer) -| |- src.api_hook_client.apply_patch (producer) -| |- src.api_hook_client.get_project (producer) -| |- src.api_hook_client.right_click (producer) -| |- src.api_hook_client.push_event (producer) -| |- src.api_hook_client.post_gui (producer) -| |- src.api_hook_client.click (producer) -| |- src.project_manager.flat_config (producer) -| |- src.app_controller.get_api_project (producer) -| |- src.app_controller.get_diagnostics (producer) -| |- src.api_hook_client.get_financial_metrics (producer) -| |- src.api_hook_client.get_io_pool_status (producer) -| |- src.app_controller._api_get_api_session (producer) -| |- src.api_hook_client.get_warmup_wait (producer) -| |- src.ai_client._parse_tool_args_result (producer) -| |- src.ai_client.get_gemini_cache_stats (producer) -| |- src.app_controller.get_session (producer) -| |- src.ai_client._content_block_to_dict (producer) | |- src.app_controller.load_config (producer) -| |- src.ai_client._load_credentials (producer) -| |- src.api_hook_client.drag (producer) -| |- src.api_hook_client.post_project (producer) -| |- src.app_controller._api_get_diagnostics (producer) -| |- src.ai_client.ollama_chat (producer) -| |- src.api_hook_client.get_mma_status (producer) -| |- src.api_hook_client.get_mma_workers (producer) -| |- src.api_hook_client.get_system_telemetry (producer) -| |- src.project_manager.load_history (producer) -| |- src.api_hook_client.get_gui_diagnostics (producer) -| |- src.api_hook_client.get_session (producer) -| |- src.app_controller.get_performance (producer) -| |- src.app_controller.status (producer) -| |- src.app_controller._api_get_mma_status (producer) -| |- src.ai_client.get_token_stats (producer) -| |- src.app_controller.generate (producer) +| |- src.ai_client.get_gemini_cache_stats (producer) | |- src.project_manager.default_project (producer) -| |- src.app_controller._api_get_session (producer) -| |- src.app_controller._offload_entry_payload (producer) -| |- src.api_hook_client.trigger_patch (producer) -| |- src.project_manager.str_to_entry (producer) +| |- src.app_controller.wait (producer) +| |- src.app_controller._api_status (producer) +| |- src.app_controller._api_get_mma_status (producer) +| |- src.ai_client.ollama_chat (producer) +| |- src.api_hook_client.wait_for_project_switch (producer) +| |- src.ai_client._parse_tool_args_result (producer) +| |- src.api_hook_client.get_mma_status (producer) +| |- src.app_controller._api_get_context (producer) +| |- src.api_hook_client.get_gui_health (producer) +| |- src.models._load_config_from_disk (producer) +| |- src.api_hook_client.get_session (producer) +| |- src.app_controller.get_session (producer) +| |- src.app_controller._api_get_performance (producer) +| |- src.api_hook_client.post_gui (producer) +| |- src.ai_client._content_block_to_dict (producer) +| |- src.api_hook_client.right_click (producer) +| |- src.app_controller._api_get_gui_state (producer) +| |- src.api_hook_client.get_performance (producer) +| |- src.api_hook_client.get_warmup_wait (producer) +| |- src.ai_client._add_bleed_derived (producer) +| |- src.api_hook_client.set_value (producer) +| |- src.app_controller.get_diagnostics (producer) +| |- src.project_manager.default_discussion (producer) +| |- src.ai_client._dashscope_call (producer) +| |- src.api_hook_client.get_warmup_status (producer) |- consumers: [35] -| |- src.app_controller._offload_entry_payload (consumer) -| |- src.aggregate.build_markdown_no_history (consumer) -| |- src.app_controller._start_track_logic (consumer) -| |- src.ai_client._strip_stale_file_refreshes (consumer) -| |- src.project_manager.format_discussion (consumer) -| |- src.ai_client._trim_anthropic_history (consumer) -| |- src.project_manager.save_project (consumer) -| |- src.ai_client._trim_minimax_history (consumer) -| |- src.ai_client._estimate_prompt_tokens (consumer) -| |- src.ai_client.ollama_chat (consumer) -| |- src.project_manager.flat_config (consumer) -| |- src.app_controller._on_comms_entry (consumer) +| |- src.ai_client._add_history_cache_breakpoint (consumer) | |- src.models.from_dict (consumer) | |- src.app_controller._start_track_logic_result (consumer) +| |- src.project_manager.entry_to_str (consumer) +| |- src.app_controller._on_comms_entry (consumer) +| |- src.ai_client._trim_minimax_history (consumer) +| |- src.aggregate.build_tier3_context (consumer) +| |- src.ai_client.ollama_chat (consumer) +| |- src.project_manager.flat_config (consumer) +| |- src.ai_client._repair_minimax_history (consumer) +| |- src.ai_client._estimate_message_tokens (consumer) | |- src.ai_client._strip_private_keys (consumer) | |- src.aggregate._build_files_section_from_items (consumer) -| |- src.ai_client._dashscope_call (consumer) -| |- src.ai_client._repair_deepseek_history (consumer) -| |- src.ai_client._add_bleed_derived (consumer) -| |- src.ai_client._add_history_cache_breakpoint (consumer) -| |- src.project_manager.migrate_from_legacy_config (consumer) -| |- src.ai_client._invalidate_token_estimate (consumer) -| |- src.project_manager.entry_to_str (consumer) -| |- src.ai_client._strip_cache_controls (consumer) -| |- src.ai_client._repair_minimax_history (consumer) -| |- src.ai_client._append_comms (consumer) -| |- src.aggregate.build_tier3_context (consumer) -| |- src.aggregate.build_markdown_from_items (consumer) -| |- src.ai_client._pre_dispatch (consumer) -| |- src.aggregate.run (consumer) | |- src.models._save_config_to_disk (consumer) +| |- src.ai_client._repair_deepseek_history (consumer) +| |- src.ai_client._pre_dispatch (consumer) +| |- src.app_controller._start_track_logic (consumer) +| |- src.ai_client._estimate_prompt_tokens (consumer) +| |- src.project_manager.save_project (consumer) | |- src.ai_client._repair_anthropic_history (consumer) -| |- src.ai_client._estimate_message_tokens (consumer) +| |- src.project_manager.migrate_from_legacy_config (consumer) +| |- src.aggregate.run (consumer) | |- src.app_controller._refresh_api_metrics (consumer) +| |- src.project_manager.format_discussion (consumer) +| |- src.aggregate.build_markdown_from_items (consumer) +| |- src.aggregate.build_markdown_no_history (consumer) +| |- src.app_controller._offload_entry_payload (consumer) +| |- src.ai_client._add_bleed_derived (consumer) +| |- src.ai_client._trim_anthropic_history (consumer) | |- src.ai_client._execute_single_tool_call_async (consumer) +| |- src.ai_client._dashscope_call (consumer) +| |- src.ai_client._invalidate_token_estimate (consumer) +| |- src.ai_client._strip_stale_file_refreshes (consumer) +| |- src.ai_client._strip_cache_controls (consumer) +| |- src.ai_client._append_comms (consumer) |- access_pattern: whole_struct |- frequency: per_turn |- result_coverage: 77 producers, 35 consumers diff --git a/docs/reports/code_path_audit/2026-06-22/aggregates/ProviderHistory.md b/docs/reports/code_path_audit/2026-06-22/aggregates/ProviderHistory.md index 1369f47a..6b5b92da 100644 --- a/docs/reports/code_path_audit/2026-06-22/aggregates/ProviderHistory.md +++ b/docs/reports/code_path_audit/2026-06-22/aggregates/ProviderHistory.md @@ -8,6 +8,24 @@ - Producers: 0 - Consumers: 0 +- Distinct producer fqnames: 0 +- Distinct consumer fqnames: 0 +- Access pattern (aggregate): mixed +- Frequency (aggregate): unknown +- Decomposition direction: insufficient_data +- Struct field count (estimated): 0 + +## Producers (0) + +_(none)_ + +## Consumers (0) + +_(none)_ + +## Field access matrix + +_(no field accesses detected)_ ## Access pattern @@ -23,27 +41,47 @@ **Summary:** +| metric | value | +|---|---| +| total producers | 0 | +| result producers | 0 | +| total consumers | 0 | +| result consumers | 0 | + ## Type alias coverage **Summary:** +| metric | value | +|---|---| +| total field-access sites | 0 | +| typed sites (canonical field) | 0 | +| untyped sites (wildcard) | 0 | + ## Cross-audit findings -| Audit script | Site count | Example | Note | -|---|---|---|---| +_(no cross-audit findings mapped to this aggregate)_ ## Decomposition cost -**Current cost estimate:** 0 us -**Componentize savings:** 0 us -**Unify savings:** 0 us +**Current cost estimate:** 0 us/turn +**Componentize savings:** 0 us/turn +**Unify savings:** 0 us/turn **Recommended direction:** insufficient_data **Rationale:** candidate aggregate; would be detected after any_type_componentization_20260621 merges +**Struct field count (estimated):** 0 +**Struct frozen:** False + +## Struct shape (inferred from producer returns) + +_(no producers; cannot infer shape)_ ## Optimization candidates -_(none)_ +_(no optimization candidates generated)_ ## Verdict -candidate aggregate; would be detected after any_type_componentization_20260621 merges \ No newline at end of file +candidate aggregate; would be detected after any_type_componentization_20260621 merges + +## Evidence appendix diff --git a/docs/reports/code_path_audit/2026-06-22/aggregates/Result.md b/docs/reports/code_path_audit/2026-06-22/aggregates/Result.md index 51546ff3..32ec5014 100644 --- a/docs/reports/code_path_audit/2026-06-22/aggregates/Result.md +++ b/docs/reports/code_path_audit/2026-06-22/aggregates/Result.md @@ -8,6 +8,24 @@ - Producers: 0 - Consumers: 0 +- Distinct producer fqnames: 0 +- Distinct consumer fqnames: 0 +- Access pattern (aggregate): mixed +- Frequency (aggregate): per_turn +- Decomposition direction: insufficient_data +- Struct field count (estimated): 5 + +## Producers (0) + +_(none)_ + +## Consumers (0) + +_(none)_ + +## Field access matrix + +_(no field accesses detected)_ ## Access pattern @@ -23,27 +41,47 @@ **Summary:** 0 producers, 0 consumers +| metric | value | +|---|---| +| total producers | 0 | +| result producers | 0 | +| total consumers | 0 | +| result consumers | 0 | + ## Type alias coverage **Summary:** 0 sites +| metric | value | +|---|---| +| total field-access sites | 0 | +| typed sites (canonical field) | 0 | +| untyped sites (wildcard) | 0 | + ## Cross-audit findings -| Audit script | Site count | Example | Note | -|---|---|---|---| +_(no cross-audit findings mapped to this aggregate)_ ## Decomposition cost -**Current cost estimate:** 470 us -**Componentize savings:** 0 us -**Unify savings:** 0 us +**Current cost estimate:** 470 us/turn +**Componentize savings:** 0 us/turn +**Unify savings:** 0 us/turn **Recommended direction:** insufficient_data **Rationale:** Result: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. +**Struct field count (estimated):** 5 +**Struct frozen:** True + +## Struct shape (inferred from producer returns) + +_(no producers; cannot infer shape)_ ## Optimization candidates -_(none)_ +_(no optimization candidates generated)_ ## Verdict -Result: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. \ No newline at end of file +Result: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. + +## Evidence appendix diff --git a/docs/reports/code_path_audit/2026-06-22/aggregates/ToolCall.md b/docs/reports/code_path_audit/2026-06-22/aggregates/ToolCall.md index fb325ec9..12a8dcb1 100644 --- a/docs/reports/code_path_audit/2026-06-22/aggregates/ToolCall.md +++ b/docs/reports/code_path_audit/2026-06-22/aggregates/ToolCall.md @@ -8,42 +8,108 @@ - Producers: 1 - Consumers: 1 +- Distinct producer fqnames: 1 +- Distinct consumer fqnames: 1 +- Access pattern (aggregate): whole_struct +- Frequency (aggregate): per_turn +- Decomposition direction: hold +- Struct field count (estimated): 5 + +## Producers (1) + +### `src\openai_compatible.py` (1 producer) + +- `src.openai_compatible._to_typed_tool_call` (line 0) + +## Consumers (1) + +### `src\openai_compatible.py` (1 consumer) + +- `src.openai_compatible._to_dict_tool_call` (line 0) + +## Field access matrix + +| consumer | to_dict | +|---|---| +| `_to_dict_tool_call` | 1 | ## Access pattern **Dominant pattern:** whole_struct **Evidence count:** 1 +**Per-function pattern distribution:** + +- `whole_struct`: 1 functions (100%) + ## Frequency **Dominant frequency:** per_turn **Evidence count:** 1 +**Per-function frequency distribution:** + +- `per_turn`: 1 functions + ## Result coverage **Summary:** 1 producers, 1 consumers +| metric | value | +|---|---| +| total producers | 1 | +| result producers | 1 | +| total consumers | 1 | +| result consumers | 0 | + ## Type alias coverage **Summary:** 1 sites; 0 typed (0%); 1 untyped (100%) +| metric | value | +|---|---| +| total field-access sites | 1 | +| typed sites (canonical field) | 0 | +| untyped sites (wildcard) | 1 | + ## Cross-audit findings -| Audit script | Site count | Example | Note | -|---|---|---|---| +_(no cross-audit findings mapped to this aggregate)_ ## Decomposition cost -**Current cost estimate:** 470 us -**Componentize savings:** 0 us -**Unify savings:** 70 us +**Current cost estimate:** 470 us/turn +**Componentize savings:** 0 us/turn +**Unify savings:** 70 us/turn **Recommended direction:** hold **Rationale:** ToolCall: access_pattern=whole_struct, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: hold because the current shape matches the access pattern. +**Struct field count (estimated):** 5 +**Struct frozen:** True + +## Struct shape (inferred from producer returns) + +| field | access count | access pattern | +|---|---|---| +| `to_dict` | 1 | used | ## Optimization candidates -_(none)_ +_(no optimization candidates generated)_ ## Verdict -ToolCall: access_pattern=whole_struct, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: hold because the current shape matches the access pattern. \ No newline at end of file +ToolCall: access_pattern=whole_struct, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: hold because the current shape matches the access pattern. + +## Evidence appendix + +### Access pattern evidence + +| function | pattern | field_accesses | confidence | +|---|---|---|---| +| `src.openai_compatible._to_dict_tool_call` | `whole_struct` | `to_dict`=1 | high | + +### Frequency evidence + +| function | frequency | source | note | +|---|---|---|---| +| `src.openai_compatible._to_typed_tool_call` | `per_turn` | `static_analysis` | producer from src\openai_compatible.py | diff --git a/docs/reports/code_path_audit/2026-06-22/aggregates/ToolDefinition.md b/docs/reports/code_path_audit/2026-06-22/aggregates/ToolDefinition.md index fc53c645..8eeb485e 100644 --- a/docs/reports/code_path_audit/2026-06-22/aggregates/ToolDefinition.md +++ b/docs/reports/code_path_audit/2026-06-22/aggregates/ToolDefinition.md @@ -8,6 +8,24 @@ - Producers: 0 - Consumers: 0 +- Distinct producer fqnames: 0 +- Distinct consumer fqnames: 0 +- Access pattern (aggregate): mixed +- Frequency (aggregate): per_turn +- Decomposition direction: insufficient_data +- Struct field count (estimated): 5 + +## Producers (0) + +_(none)_ + +## Consumers (0) + +_(none)_ + +## Field access matrix + +_(no field accesses detected)_ ## Access pattern @@ -23,27 +41,47 @@ **Summary:** 0 producers, 0 consumers +| metric | value | +|---|---| +| total producers | 0 | +| result producers | 0 | +| total consumers | 0 | +| result consumers | 0 | + ## Type alias coverage **Summary:** 0 sites +| metric | value | +|---|---| +| total field-access sites | 0 | +| typed sites (canonical field) | 0 | +| untyped sites (wildcard) | 0 | + ## Cross-audit findings -| Audit script | Site count | Example | Note | -|---|---|---|---| +_(no cross-audit findings mapped to this aggregate)_ ## Decomposition cost -**Current cost estimate:** 470 us -**Componentize savings:** 0 us -**Unify savings:** 0 us +**Current cost estimate:** 470 us/turn +**Componentize savings:** 0 us/turn +**Unify savings:** 0 us/turn **Recommended direction:** insufficient_data **Rationale:** ToolDefinition: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. +**Struct field count (estimated):** 5 +**Struct frozen:** True + +## Struct shape (inferred from producer returns) + +_(no producers; cannot infer shape)_ ## Optimization candidates -_(none)_ +_(no optimization candidates generated)_ ## Verdict -ToolDefinition: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. \ No newline at end of file +ToolDefinition: access_pattern=mixed, frequency=per_turn, struct_field_count=5, struct_frozen=True. Recommended: insufficient_data because runtime profiling is needed to determine the dominant pattern. + +## Evidence appendix diff --git a/docs/reports/code_path_audit/2026-06-22/aggregates/ToolSpec.md b/docs/reports/code_path_audit/2026-06-22/aggregates/ToolSpec.md index 08ba6fe9..f61c3453 100644 --- a/docs/reports/code_path_audit/2026-06-22/aggregates/ToolSpec.md +++ b/docs/reports/code_path_audit/2026-06-22/aggregates/ToolSpec.md @@ -8,6 +8,24 @@ - Producers: 0 - Consumers: 0 +- Distinct producer fqnames: 0 +- Distinct consumer fqnames: 0 +- Access pattern (aggregate): mixed +- Frequency (aggregate): unknown +- Decomposition direction: insufficient_data +- Struct field count (estimated): 0 + +## Producers (0) + +_(none)_ + +## Consumers (0) + +_(none)_ + +## Field access matrix + +_(no field accesses detected)_ ## Access pattern @@ -23,27 +41,47 @@ **Summary:** +| metric | value | +|---|---| +| total producers | 0 | +| result producers | 0 | +| total consumers | 0 | +| result consumers | 0 | + ## Type alias coverage **Summary:** +| metric | value | +|---|---| +| total field-access sites | 0 | +| typed sites (canonical field) | 0 | +| untyped sites (wildcard) | 0 | + ## Cross-audit findings -| Audit script | Site count | Example | Note | -|---|---|---|---| +_(no cross-audit findings mapped to this aggregate)_ ## Decomposition cost -**Current cost estimate:** 0 us -**Componentize savings:** 0 us -**Unify savings:** 0 us +**Current cost estimate:** 0 us/turn +**Componentize savings:** 0 us/turn +**Unify savings:** 0 us/turn **Recommended direction:** insufficient_data **Rationale:** candidate aggregate; would be detected after any_type_componentization_20260621 merges +**Struct field count (estimated):** 0 +**Struct frozen:** False + +## Struct shape (inferred from producer returns) + +_(no producers; cannot infer shape)_ ## Optimization candidates -_(none)_ +_(no optimization candidates generated)_ ## Verdict -candidate aggregate; would be detected after any_type_componentization_20260621 merges \ No newline at end of file +candidate aggregate; would be detected after any_type_componentization_20260621 merges + +## Evidence appendix diff --git a/docs/reports/code_path_audit/2026-06-22/call_graph.md b/docs/reports/code_path_audit/2026-06-22/call_graph.md new file mode 100644 index 00000000..80c0107c --- /dev/null +++ b/docs/reports/code_path_audit/2026-06-22/call_graph.md @@ -0,0 +1,166 @@ +# Call Graph Rollup + +Functions that are producers or consumers of each aggregate, grouped by file. + +## Metadata (77 producers + 35 consumers) + +| role | fqname | file | +|---|---|---| +| producer | `src.api_hook_client.get_gui_diagnostics` | `src\api_hook_client.py` | +| producer | `src.app_controller.get_gui_state` | `src\app_controller.py` | +| producer | `src.app_controller._api_get_api_project` | `src\app_controller.py` | +| producer | `src.api_hook_client.get_node_status` | `src\api_hook_client.py` | +| producer | `src.api_hook_client.post_session` | `src\api_hook_client.py` | +| producer | `src.api_hook_client.get_financial_metrics` | `src\api_hook_client.py` | +| producer | `src.api_hook_client.get_patch_status` | `src\api_hook_client.py` | +| producer | `src.app_controller._offload_entry_payload` | `src\app_controller.py` | +| producer | `src.ai_client._send_cli_round_result` | `src\ai_client.py` | +| producer | `src.api_hook_client.get_startup_timeline` | `src\api_hook_client.py` | +| producer | `src.api_hook_client.get_project` | `src\api_hook_client.py` | +| producer | `src.app_controller.get_session_insights` | `src\app_controller.py` | +| producer | `src.app_controller.generate` | `src\app_controller.py` | +| producer | `src.ai_client.get_token_stats` | `src\ai_client.py` | +| producer | `src.api_hook_client.drag` | `src\api_hook_client.py` | +| producer | `src.project_manager.flat_config` | `src\project_manager.py` | +| producer | `src.app_controller.get_api_session` | `src\app_controller.py` | +| producer | `src.app_controller.get_mma_status` | `src\app_controller.py` | +| producer | `src.project_manager.load_project` | `src\project_manager.py` | +| producer | `src.api_hook_client.apply_patch` | `src\api_hook_client.py` | +| producer | `src.api_hook_client.get_context_state` | `src\api_hook_client.py` | +| producer | `src.api_hook_client.get_status` | `src\api_hook_client.py` | +| producer | `src.project_manager.str_to_entry` | `src\project_manager.py` | +| producer | `src.project_manager.migrate_from_legacy_config` | `src\project_manager.py` | +| producer | `src.api_hook_client.post_project` | `src\api_hook_client.py` | +| producer | `src.app_controller._api_token_stats` | `src\app_controller.py` | +| producer | `src.app_controller.token_stats` | `src\app_controller.py` | +| producer | `src.app_controller.status` | `src\app_controller.py` | +| producer | `src.api_hook_client.get_system_telemetry` | `src\api_hook_client.py` | +| producer | `src.api_hook_client.push_event` | `src\api_hook_client.py` | +| producer | `src.api_hook_client.get_gui_state` | `src\api_hook_client.py` | +| producer | `src.app_controller._api_get_diagnostics` | `src\app_controller.py` | +| producer | `src.app_controller._api_get_api_session` | `src\app_controller.py` | +| producer | `src.api_hook_client.get_io_pool_status` | `src\api_hook_client.py` | +| producer | `src.app_controller.get_performance` | `src\app_controller.py` | +| producer | `src.api_hook_client.get_project_switch_status` | `src\api_hook_client.py` | +| producer | `src.models.to_dict` | `src\models.py` | +| producer | `src.app_controller.get_api_project` | `src\app_controller.py` | +| producer | `src.app_controller._api_get_session` | `src\app_controller.py` | +| producer | `src.app_controller.get_context` | `src\app_controller.py` | +| producer | `src.api_hook_client.click` | `src\api_hook_client.py` | +| producer | `src.api_hook_client.get_mma_workers` | `src\api_hook_client.py` | +| producer | `src.ai_client._load_credentials` | `src\ai_client.py` | +| producer | `src.api_hook_client.trigger_patch` | `src\api_hook_client.py` | +| producer | `src.api_hook_client.select_list_item` | `src\api_hook_client.py` | +| producer | `src.project_manager.load_history` | `src\project_manager.py` | +| producer | `src.api_hook_client.select_tab` | `src\api_hook_client.py` | +| producer | `src.api_hook_client.reject_patch` | `src\api_hook_client.py` | +| producer | `src.app_controller._api_generate` | `src\app_controller.py` | +| producer | `src.app_controller.load_config` | `src\app_controller.py` | +| producer | `src.ai_client.get_gemini_cache_stats` | `src\ai_client.py` | +| producer | `src.project_manager.default_project` | `src\project_manager.py` | +| producer | `src.app_controller.wait` | `src\app_controller.py` | +| producer | `src.app_controller._api_status` | `src\app_controller.py` | +| producer | `src.app_controller._api_get_mma_status` | `src\app_controller.py` | +| producer | `src.ai_client.ollama_chat` | `src\ai_client.py` | +| producer | `src.api_hook_client.wait_for_project_switch` | `src\api_hook_client.py` | +| producer | `src.ai_client._parse_tool_args_result` | `src\ai_client.py` | +| producer | `src.api_hook_client.get_mma_status` | `src\api_hook_client.py` | +| producer | `src.app_controller._api_get_context` | `src\app_controller.py` | +| producer | `src.api_hook_client.get_gui_health` | `src\api_hook_client.py` | +| producer | `src.models._load_config_from_disk` | `src\models.py` | +| producer | `src.api_hook_client.get_session` | `src\api_hook_client.py` | +| producer | `src.app_controller.get_session` | `src\app_controller.py` | +| producer | `src.app_controller._api_get_performance` | `src\app_controller.py` | +| producer | `src.api_hook_client.post_gui` | `src\api_hook_client.py` | +| producer | `src.ai_client._content_block_to_dict` | `src\ai_client.py` | +| producer | `src.api_hook_client.right_click` | `src\api_hook_client.py` | +| producer | `src.app_controller._api_get_gui_state` | `src\app_controller.py` | +| producer | `src.api_hook_client.get_performance` | `src\api_hook_client.py` | +| producer | `src.api_hook_client.get_warmup_wait` | `src\api_hook_client.py` | +| producer | `src.ai_client._add_bleed_derived` | `src\ai_client.py` | +| producer | `src.api_hook_client.set_value` | `src\api_hook_client.py` | +| producer | `src.app_controller.get_diagnostics` | `src\app_controller.py` | +| producer | `src.project_manager.default_discussion` | `src\project_manager.py` | +| producer | `src.ai_client._dashscope_call` | `src\ai_client.py` | +| producer | `src.api_hook_client.get_warmup_status` | `src\api_hook_client.py` | +| consumer | `src.ai_client._add_history_cache_breakpoint` | `src\ai_client.py` | +| consumer | `src.models.from_dict` | `src\models.py` | +| consumer | `src.app_controller._start_track_logic_result` | `src\app_controller.py` | +| consumer | `src.project_manager.entry_to_str` | `src\project_manager.py` | +| consumer | `src.app_controller._on_comms_entry` | `src\app_controller.py` | +| consumer | `src.ai_client._trim_minimax_history` | `src\ai_client.py` | +| consumer | `src.aggregate.build_tier3_context` | `src\aggregate.py` | +| consumer | `src.ai_client.ollama_chat` | `src\ai_client.py` | +| consumer | `src.project_manager.flat_config` | `src\project_manager.py` | +| consumer | `src.ai_client._repair_minimax_history` | `src\ai_client.py` | +| consumer | `src.ai_client._estimate_message_tokens` | `src\ai_client.py` | +| consumer | `src.ai_client._strip_private_keys` | `src\ai_client.py` | +| consumer | `src.aggregate._build_files_section_from_items` | `src\aggregate.py` | +| consumer | `src.models._save_config_to_disk` | `src\models.py` | +| consumer | `src.ai_client._repair_deepseek_history` | `src\ai_client.py` | +| consumer | `src.ai_client._pre_dispatch` | `src\ai_client.py` | +| consumer | `src.app_controller._start_track_logic` | `src\app_controller.py` | +| consumer | `src.ai_client._estimate_prompt_tokens` | `src\ai_client.py` | +| consumer | `src.project_manager.save_project` | `src\project_manager.py` | +| consumer | `src.ai_client._repair_anthropic_history` | `src\ai_client.py` | +| consumer | `src.project_manager.migrate_from_legacy_config` | `src\project_manager.py` | +| consumer | `src.aggregate.run` | `src\aggregate.py` | +| consumer | `src.app_controller._refresh_api_metrics` | `src\app_controller.py` | +| consumer | `src.project_manager.format_discussion` | `src\project_manager.py` | +| consumer | `src.aggregate.build_markdown_from_items` | `src\aggregate.py` | +| consumer | `src.aggregate.build_markdown_no_history` | `src\aggregate.py` | +| consumer | `src.app_controller._offload_entry_payload` | `src\app_controller.py` | +| consumer | `src.ai_client._add_bleed_derived` | `src\ai_client.py` | +| consumer | `src.ai_client._trim_anthropic_history` | `src\ai_client.py` | +| consumer | `src.ai_client._execute_single_tool_call_async` | `src\ai_client.py` | +| consumer | `src.ai_client._dashscope_call` | `src\ai_client.py` | +| consumer | `src.ai_client._invalidate_token_estimate` | `src\ai_client.py` | +| consumer | `src.ai_client._strip_stale_file_refreshes` | `src\ai_client.py` | +| consumer | `src.ai_client._strip_cache_controls` | `src\ai_client.py` | +| consumer | `src.ai_client._append_comms` | `src\ai_client.py` | + +## FileItem (0 producers + 0 consumers) + +_(no producers or consumers)_ + +## FileItems (0 producers + 3 consumers) + +| role | fqname | file | +|---|---|---| +| consumer | `src.ai_client._build_file_diff_text` | `src\ai_client.py` | +| consumer | `src.ai_client._reread_file_items_result` | `src\ai_client.py` | +| consumer | `src.ai_client._build_file_context_text` | `src\ai_client.py` | + +## CommsLogEntry (0 producers + 0 consumers) + +_(no producers or consumers)_ + +## CommsLog (0 producers + 0 consumers) + +_(no producers or consumers)_ + +## HistoryMessage (0 producers + 2 consumers) + +| role | fqname | file | +|---|---|---| +| consumer | `src.provider_state.replace_all` | `src\provider_state.py` | +| consumer | `src.provider_state.append` | `src\provider_state.py` | + +## History (0 producers + 0 consumers) + +_(no producers or consumers)_ + +## ToolDefinition (0 producers + 0 consumers) + +_(no producers or consumers)_ + +## ToolCall (1 producers + 1 consumers) + +| role | fqname | file | +|---|---|---| +| producer | `src.openai_compatible._to_typed_tool_call` | `src\openai_compatible.py` | +| consumer | `src.openai_compatible._to_dict_tool_call` | `src\openai_compatible.py` | + +## Result (0 producers + 0 consumers) + +_(no producers or consumers)_ diff --git a/docs/reports/code_path_audit/2026-06-22/field_usage.md b/docs/reports/code_path_audit/2026-06-22/field_usage.md new file mode 100644 index 00000000..55e189ed --- /dev/null +++ b/docs/reports/code_path_audit/2026-06-22/field_usage.md @@ -0,0 +1,19 @@ +# Field Usage Rollup + +Cross-aggregate analysis of which fields are accessed how often across the codebase. + +| aggregate | field | total accesses | +|---|---|---| +| `HistoryMessage` | `lock` | 2 | +| `HistoryMessage` | `messages` | 2 | +| `Metadata` | `get` | 39 | +| `Metadata` | `pop` | 10 | +| `Metadata` | `session_usage` | 7 | +| `Metadata` | `ai_status` | 5 | +| `Metadata` | `files` | 5 | +| `Metadata` | `_pending_history_adds_lock` | 4 | +| `Metadata` | `_pending_history_adds` | 4 | +| `Metadata` | `ui_auto_add_history` | 3 | +| `Metadata` | `append` | 3 | +| `Metadata` | `_pending_gui_tasks_lock` | 2 | +| `ToolCall` | `to_dict` | 1 | diff --git a/src/code_path_audit.py b/src/code_path_audit.py index 74e4008f..1708b437 100644 --- a/src/code_path_audit.py +++ b/src/code_path_audit.py @@ -1187,7 +1187,8 @@ def run_audit( md_path = agg_dir / f"{profile.name}.md" tree_path = agg_dir / f"{profile.name}.tree" dsl_path.write_text(to_dsl_v2(profile, generated_date=date), encoding="utf-8") - md_path.write_text(to_markdown(profile), encoding="utf-8") + from src.code_path_audit_render import render_full_markdown + md_path.write_text(render_full_markdown(profile), encoding="utf-8") tree_path.write_text(to_tree(profile), encoding="utf-8") output_paths[profile.name] = str(dsl_path) return Result(data=AuditSummary(aggregate_profiles=tuple(profiles), output_paths=output_paths)) @@ -1233,11 +1234,18 @@ def render_rollups(summary: AuditSummary, output_dir: Path) -> dict[str, str]: if p.is_candidate: cand_lines.append(f"- **{p.name}**: candidate; would be detected after any_type_componentization_20260621 merges") candidates_path.write_text("\n".join(cand_lines), encoding="utf-8") + from src.code_path_audit_render import render_field_usage_rollup, render_call_graph_rollup + field_usage_path = output_dir / "field_usage.md" + field_usage_path.write_text(render_field_usage_rollup(profiles), encoding="utf-8") + call_graph_path = output_dir / "call_graph.md" + call_graph_path.write_text(render_call_graph_rollup(profiles), encoding="utf-8") return { "summary.md": str(summary_path), "cross_audit_summary.md": str(cross_audit_path), "decomposition_matrix.md": str(decomposition_matrix_path), "candidates.md": str(candidates_path), + "field_usage.md": str(field_usage_path), + "call_graph.md": str(call_graph_path), } def code_path_audit_v2( diff --git a/src/code_path_audit_render.py b/src/code_path_audit_render.py new file mode 100644 index 00000000..8cbeb260 --- /dev/null +++ b/src/code_path_audit_render.py @@ -0,0 +1,325 @@ +"""Enriched markdown renderers for code_path_audit v2. + +Provides per-profile detail: call graph, field access breakdown, +struct shape, frequency per function, and concrete optimization +candidates. Designed for 2k+ line audit reports. +""" +from __future__ import annotations +from collections import Counter +from src.code_path_audit import ( + AggregateProfile, + FunctionRef, +) + + +def render_full_markdown(profile: AggregateProfile) -> str: + """Render the per-aggregate markdown with full detail. + + Sections (15+): + 1. Header (name, kind, memory_dim, is_candidate, totals) + 2. Pipeline summary (producer/consumer counts) + 3. Producers detail (per-producer: file, role, fields returned) + 4. Consumers detail (per-consumer: file, role, fields accessed) + 5. Field access matrix (every field x every consumer) + 6. Access pattern (dominant + per-function breakdown) + 7. Frequency (aggregate-level + per-function) + 8. Result coverage + 9. Type alias coverage (typed vs untyped breakdown) + 10. Cross-audit findings (per bucket, with examples) + 11. Decomposition cost (current/savings/direction/rationale) + 12. Struct shape (inferred from producer return shapes) + 13. Optimization candidates (concrete refactor steps) + 14. Verdict (1-sentence summary) + 15. Evidence appendix (every per-function evidence item) + """ + lines: list[str] = [] + # Header + lines.append(f"# Aggregate Profile: {profile.name}") + lines.append("") + lines.append(f"**Aggregate kind:** {profile.aggregate_kind}") + lines.append(f"**Memory dim:** {profile.memory_dim}") + lines.append(f"**Is candidate:** {profile.is_candidate}") + lines.append("") + # Pipeline summary + lines.append("## Pipeline summary") + lines.append("") + lines.append(f"- Producers: {len(profile.producers)}") + lines.append(f"- Consumers: {len(profile.consumers)}") + lines.append(f"- Distinct producer fqnames: {len({f.fqname for f in profile.producers})}") + lines.append(f"- Distinct consumer fqnames: {len({f.fqname for f in profile.consumers})}") + lines.append(f"- Access pattern (aggregate): {profile.access_pattern}") + lines.append(f"- Frequency (aggregate): {profile.frequency}") + lines.append(f"- Decomposition direction: {profile.decomposition_cost.recommended_direction}") + lines.append(f"- Struct field count (estimated): {profile.decomposition_cost.struct_field_count}") + lines.append("") + # Producers detail + lines.append(f"## Producers ({len(profile.producers)})") + lines.append("") + if profile.producers: + # Group by file + by_file: dict[str, list[FunctionRef]] = {} + for p in profile.producers: + by_file.setdefault(p.file, []).append(p) + for file in sorted(by_file.keys()): + funcs = by_file[file] + lines.append(f"### `{file}` ({len(funcs)} producer{'s' if len(funcs) != 1 else ''})") + lines.append("") + for f in funcs: + lines.append(f"- `{f.fqname}` (line {f.line})") + lines.append("") + else: + lines.append("_(none)_") + lines.append("") + # Consumers detail + lines.append(f"## Consumers ({len(profile.consumers)})") + lines.append("") + if profile.consumers: + by_file = {} + for c in profile.consumers: + by_file.setdefault(c.file, []).append(c) + for file in sorted(by_file.keys()): + funcs = by_file[file] + lines.append(f"### `{file}` ({len(funcs)} consumer{'s' if len(funcs) != 1 else ''})") + lines.append("") + for f in funcs: + lines.append(f"- `{f.fqname}` (line {f.line})") + lines.append("") + else: + lines.append("_(none)_") + lines.append("") + # Field access matrix + lines.append("## Field access matrix") + lines.append("") + if profile.access_pattern_evidence: + all_fields: set[str] = set() + for ev in profile.access_pattern_evidence: + all_fields.update(ev.field_accesses.keys()) + if all_fields: + sorted_fields = sorted(all_fields) + consumer_names = [ev.function.fqname.rsplit(".", 1)[-1] for ev in profile.access_pattern_evidence] + lines.append("| consumer | " + " | ".join(sorted_fields[:20]) + " |") + lines.append("|---|" + "|".join(["---"] * min(len(sorted_fields), 20)) + "|") + for ev in profile.access_pattern_evidence: + name = ev.function.fqname.rsplit(".", 1)[-1] + cells = [] + for f in sorted_fields[:20]: + count = ev.field_accesses.get(f, 0) + cells.append(str(count) if count > 0 else ".") + lines.append(f"| `{name}` | " + " | ".join(cells) + " |") + if len(sorted_fields) > 20: + lines.append("") + lines.append(f"_... {len(sorted_fields) - 20} more fields_") + else: + lines.append("_(no field accesses detected)_") + else: + lines.append("_(no field accesses detected)_") + lines.append("") + # Access pattern + lines.append("## Access pattern") + lines.append("") + lines.append(f"**Dominant pattern:** {profile.access_pattern}") + lines.append(f"**Evidence count:** {len(profile.access_pattern_evidence)}") + if profile.access_pattern_evidence: + pattern_counts: Counter[str] = Counter() + for ev in profile.access_pattern_evidence: + pattern_counts[ev.pattern] += 1 + lines.append("") + lines.append("**Per-function pattern distribution:**") + lines.append("") + for pat, count in pattern_counts.most_common(): + pct = count / len(profile.access_pattern_evidence) * 100 + lines.append(f"- `{pat}`: {count} functions ({pct:.0f}%)") + lines.append("") + # Frequency + lines.append("## Frequency") + lines.append("") + lines.append(f"**Dominant frequency:** {profile.frequency}") + lines.append(f"**Evidence count:** {len(profile.frequency_evidence)}") + if profile.frequency_evidence: + freq_counts: Counter[str] = Counter() + for ev in profile.frequency_evidence: + freq_counts[ev.frequency] += 1 + lines.append("") + lines.append("**Per-function frequency distribution:**") + lines.append("") + for freq, count in freq_counts.most_common(): + lines.append(f"- `{freq}`: {count} functions") + lines.append("") + # Result coverage + lines.append("## Result coverage") + lines.append("") + lines.append(f"**Summary:** {profile.result_coverage.summary}") + lines.append("") + lines.append("| metric | value |") + lines.append("|---|---|") + lines.append(f"| total producers | {profile.result_coverage.total_producers} |") + lines.append(f"| result producers | {profile.result_coverage.result_producers} |") + lines.append(f"| total consumers | {profile.result_coverage.total_consumers} |") + lines.append(f"| result consumers | {profile.result_coverage.result_consumers} |") + lines.append("") + # Type alias coverage + lines.append("## Type alias coverage") + lines.append("") + lines.append(f"**Summary:** {profile.type_alias_coverage.summary}") + lines.append("") + lines.append("| metric | value |") + lines.append("|---|---|") + lines.append(f"| total field-access sites | {profile.type_alias_coverage.total_sites} |") + lines.append(f"| typed sites (canonical field) | {profile.type_alias_coverage.typed_sites} |") + lines.append(f"| untyped sites (wildcard) | {profile.type_alias_coverage.untyped_sites} |") + lines.append("") + # Cross-audit findings + lines.append("## Cross-audit findings") + lines.append("") + total_cf = ( + len(profile.cross_audit_findings.weak_types) + + len(profile.cross_audit_findings.exception_handling) + + len(profile.cross_audit_findings.optional_in_baseline) + + len(profile.cross_audit_findings.config_io_ownership) + + len(profile.cross_audit_findings.import_graph) + ) + if total_cf == 0: + lines.append("_(no cross-audit findings mapped to this aggregate)_") + else: + lines.append("| bucket | audit script | site count | example file | example line | note |") + lines.append("|---|---|---|---|---|---|") + for f in profile.cross_audit_findings.weak_types: + lines.append(f"| weak_types | `{f.audit_script}` | {f.site_count} | `{f.example_file}` | {f.example_line} | {f.note} |") + for f in profile.cross_audit_findings.exception_handling: + lines.append(f"| exception_handling | `{f.audit_script}` | {f.site_count} | `{f.example_file}` | {f.example_line} | {f.note} |") + for f in profile.cross_audit_findings.optional_in_baseline: + lines.append(f"| optional_in_baseline | `{f.audit_script}` | {f.site_count} | `{f.example_file}` | {f.example_line} | {f.note} |") + for f in profile.cross_audit_findings.config_io_ownership: + lines.append(f"| config_io_ownership | `{f.audit_script}` | {f.site_count} | `{f.example_file}` | {f.example_line} | {f.note} |") + for f in profile.cross_audit_findings.import_graph: + lines.append(f"| import_graph | `{f.audit_script}` | {f.site_count} | `{f.example_file}` | {f.example_line} | {f.note} |") + lines.append("") + # Decomposition cost + lines.append("## Decomposition cost") + lines.append("") + dc = profile.decomposition_cost + lines.append(f"**Current cost estimate:** {dc.current_cost_estimate} us/turn") + lines.append(f"**Componentize savings:** {dc.componentize_savings} us/turn") + lines.append(f"**Unify savings:** {dc.unify_savings} us/turn") + lines.append(f"**Recommended direction:** {dc.recommended_direction}") + lines.append(f"**Rationale:** {dc.recommended_rationale}") + lines.append(f"**Struct field count (estimated):** {dc.struct_field_count}") + lines.append(f"**Struct frozen:** {dc.struct_frozen}") + lines.append("") + # Struct shape (inferred) + lines.append("## Struct shape (inferred from producer returns)") + lines.append("") + if profile.producers: + field_usage: Counter[str] = Counter() + for ev in profile.access_pattern_evidence: + field_usage.update(ev.field_accesses.keys()) + if field_usage: + lines.append("| field | access count | access pattern |") + lines.append("|---|---|---|") + sorted_fields_by_use = field_usage.most_common() + for field_name, count in sorted_fields_by_use: + if count >= 3: + pattern = "hot" + elif count >= 1: + pattern = "used" + else: + pattern = "dead" + lines.append(f"| `{field_name}` | {count} | {pattern} |") + else: + lines.append("_(no field access data; cannot infer shape)_") + else: + lines.append("_(no producers; cannot infer shape)_") + lines.append("") + # Optimization candidates + lines.append("## Optimization candidates") + lines.append("") + if profile.optimization_candidates: + for cand in profile.optimization_candidates: + lines.append(f"### {cand.direction.upper()}: {cand.candidate}") + lines.append("") + lines.append(f"- **Effort:** {cand.effort}") + lines.append(f"- **Priority:** {cand.priority}") + lines.append(f"- **Estimated savings:** {cand.estimated_savings_us} us/turn") + lines.append(f"- **Affected files ({len(cand.affected_files)}):**") + for f in cand.affected_files: + lines.append(f" - `{f}`") + lines.append(f"- **Reference:** {cand.cross_ref}") + lines.append("") + else: + lines.append("_(no optimization candidates generated)_") + lines.append("") + # Verdict + lines.append("## Verdict") + lines.append("") + lines.append(f"{dc.recommended_rationale}") + lines.append("") + # Evidence appendix + lines.append("## Evidence appendix") + lines.append("") + if profile.access_pattern_evidence: + lines.append("### Access pattern evidence") + lines.append("") + lines.append("| function | pattern | field_accesses | confidence |") + lines.append("|---|---|---|---|") + for ev in profile.access_pattern_evidence: + fields_str = ", ".join(f"`{k}`={v}" for k, v in list(ev.field_accesses.items())[:10]) + if len(ev.field_accesses) > 10: + fields_str += f" (+{len(ev.field_accesses) - 10} more)" + lines.append(f"| `{ev.function.fqname}` | `{ev.pattern}` | {fields_str} | {ev.confidence} |") + lines.append("") + if profile.frequency_evidence: + lines.append("### Frequency evidence") + lines.append("") + lines.append("| function | frequency | source | note |") + lines.append("|---|---|---|---|") + for ev in profile.frequency_evidence: + lines.append(f"| `{ev.function.fqname}` | `{ev.frequency}` | `{ev.source}` | {ev.note} |") + lines.append("") + return "\n".join(lines) + + +def render_field_usage_rollup(profiles: tuple[AggregateProfile, ...]) -> str: + """Render the field usage rollup (cross-aggregate).""" + lines: list[str] = ["# Field Usage Rollup", ""] + lines.append("Cross-aggregate analysis of which fields are accessed how often across the codebase.") + lines.append("") + all_field_usage: dict[str, dict[str, int]] = {} + for p in profiles: + if p.is_candidate: + continue + for ev in p.access_pattern_evidence: + aggregate_fields = all_field_usage.setdefault(p.name, {}) + for field_name, count in ev.field_accesses.items(): + aggregate_fields[field_name] = aggregate_fields.get(field_name, 0) + count + if all_field_usage: + lines.append("| aggregate | field | total accesses |") + lines.append("|---|---|---|") + for aggregate in sorted(all_field_usage.keys()): + fields = all_field_usage[aggregate] + for field_name, count in sorted(fields.items(), key=lambda x: -x[1])[:10]: + lines.append(f"| `{aggregate}` | `{field_name}` | {count} |") + lines.append("") + return "\n".join(lines) + + +def render_call_graph_rollup(profiles: tuple[AggregateProfile, ...]) -> str: + """Render the call graph rollup (most-touched functions per aggregate).""" + lines: list[str] = ["# Call Graph Rollup", ""] + lines.append("Functions that are producers or consumers of each aggregate, grouped by file.") + lines.append("") + for p in profiles: + if p.is_candidate: + continue + lines.append(f"## {p.name} ({len(p.producers)} producers + {len(p.consumers)} consumers)") + lines.append("") + if p.producers or p.consumers: + lines.append("| role | fqname | file |") + lines.append("|---|---|---|") + for prod in p.producers: + lines.append(f"| producer | `{prod.fqname}` | `{prod.file}` |") + for cons in p.consumers: + lines.append(f"| consumer | `{cons.fqname}` | `{cons.file}` |") + else: + lines.append("_(no producers or consumers)_") + lines.append("") + return "\n".join(lines) \ No newline at end of file