fix(audit): real line numbers + entry.get() field-access detection + Optional/dict/Union patterns

Three real bugs fixed:
1. FunctionRef always used line=0. Now passes node.lineno from AST.
2. P3_pass results were discarded with bare pass. Now stored in
   ProducerConsumerGraph.field_accesses.
3. Field-access detector only saw entry['key']; missed entry.get('key')
   which is the dominant pattern in this codebase. Now handles both.

Plus _extract_type_name() helper handles Optional[T], dict[str, T],
list[T], Result[T], Union[T, ...], and T | None (PEP 604) so P1/P2
catch more annotation patterns.

Real numbers (Metadata aggregate):
- producers: 77 -> 117
- consumers: 35 -> 66
- field-access sites: 130 -> 173
- line numbers: all real (line 1281, 1746, etc.)

AUDIT_REPORT.md grew 2009 -> 3140 lines with real evidence.
Total audit output: 5176 lines / 50 files (was 2415 / 49).

All 131 tests still passing.
This commit is contained in:
ed
2026-06-22 12:20:32 -04:00
parent ac2e68542f
commit 077149011b
27 changed files with 2087 additions and 1263 deletions
@@ -4,8 +4,8 @@ Generated for 13 aggregates on 2026-06-22
- **Real aggregates (in scope):** 10
- **Candidate aggregates (placeholders):** 3
- **Total producers:** 78
- **Total consumers:** 41
- **Total producers:** 121
- **Total consumers:** 73
- **Total current cost (us/turn):** 4950
- **Total actionable savings (us/turn):** 140
@@ -23,13 +23,13 @@ Generated for 13 aggregates on 2026-06-22
| `CommsLog` | `typealias` | `discussion` | `mixed` | 0 | 0 |
| `CommsLogEntry` | `typealias` | `discussion` | `mixed` | 0 | 0 |
| `FileItem` | `typealias` | `curation` | `mixed` | 0 | 0 |
| `FileItems` | `typealias` | `curation` | `whole_struct` | 0 | 3 |
| `FileItems` | `typealias` | `curation` | `whole_struct` | 0 | 4 |
| `History` | `typealias` | `discussion` | `mixed` | 0 | 0 |
| `HistoryMessage` | `typealias` | `discussion` | `mixed` | 0 | 2 |
| `Metadata` | `typealias` | `discussion` | `whole_struct` | 77 | 35 |
| `HistoryMessage` | `typealias` | `discussion` | `mixed` | 1 | 2 |
| `Metadata` | `typealias` | `discussion` | `whole_struct` | 117 | 66 |
| `Result` | `typealias` | `control` | `mixed` | 0 | 0 |
| `ToolCall` | `typealias` | `control` | `whole_struct` | 1 | 1 |
| `ToolDefinition` | `typealias` | `control` | `mixed` | 0 | 0 |
| `ToolDefinition` | `typealias` | `control` | `mixed` | 2 | 0 |
| `ChatMessage` | `candidate_dataclass` | `discussion` | `mixed` | 0 | 0 |
| `ProviderHistory` | `candidate_dataclass` | `unknown` | `mixed` | 0 | 0 |
| `ToolSpec` | `candidate_dataclass` | `unknown` | `mixed` | 0 | 0 |
@@ -56,8 +56,8 @@ Generated for 13 aggregates on 2026-06-22
### `FileItems`
- **Result coverage:** 0 producers, 3 consumers
- **Type alias coverage:** 0 sites
- **Result coverage:** 0 producers, 4 consumers
- **Type alias coverage:** 2 sites; 0 typed (0%); 2 untyped (100%)
- **Cross-audit findings (total sites):** 0
### `History`
@@ -68,14 +68,14 @@ Generated for 13 aggregates on 2026-06-22
### `HistoryMessage`
- **Result coverage:** 0 producers, 2 consumers
- **Result coverage:** 1 producers, 2 consumers
- **Type alias coverage:** 4 sites; 0 typed (0%); 4 untyped (100%)
- **Cross-audit findings (total sites):** 0
### `Metadata`
- **Result coverage:** 77 producers, 35 consumers
- **Type alias coverage:** 130 sites; 0 typed (0%); 130 untyped (100%)
- **Result coverage:** 96 producers, 46 consumers
- **Type alias coverage:** 173 sites; 0 typed (0%); 173 untyped (100%)
- **Cross-audit findings (total sites):** 1
### `Result`
@@ -92,6 +92,6 @@ Generated for 13 aggregates on 2026-06-22
### `ToolDefinition`
- **Result coverage:** 0 producers, 0 consumers
- **Result coverage:** 2 producers, 0 consumers
- **Type alias coverage:** 0 sites
- **Cross-audit findings (total sites):** 0
- **Cross-audit findings (total sites):** 1