Private
Public Access
conductor(campaign): metadata_ssdl_defusing_20260624 - 3-child SSDL defusing campaign
Campaign: address the parent code_path_audit_20260607 Finding 1 (CRITICAL)
Metadata 4.01e22 effective codepaths via 3 SSDL techniques.
3 children, sequential, with budget gates:
1. metadata_nil_sentinel_20260624 (>= 10% drop): introduce
NIL_METADATA sentinel + migrate 6 nil-check functions.
2. metadata_generational_handle_20260624 (>= 20% drop,
BLOCKED_BY 1): wrap Metadata in (index, generation) handle;
collapse lifetime branches to 1 lookup + 1 cmp.
3. metadata_field_cache_20260624 (>= 30% drop, BLOCKED_BY 2):
MetadataFieldCache keyed by (handle.index, field_name);
123 string-keyed entry.get('key', default) sites become
cache lookups.
Each child has its own spec/plan/metadata/state. Budget gate
after each child: re-measure effective codepaths; if drop < threshold,
PAUSE the campaign and report to user.
End-of-campaign TRACK_COMPLETION captures the cumulative reduction
vs the 4.01e22 baseline. Deferred follow-up: apply the same
3 SSDL primitives to the 4 other dict[str, Any] aliases
(FileItem, CommsLogEntry, HistoryMessage, ToolDefinition, ToolCall).
16 files committed: 4 directories x 4 files each (spec, plan,
metadata, state).
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
# Track Specification: metadata_field_cache_20260624
|
||||
|
||||
## Overview
|
||||
|
||||
Child 3 of the `metadata_ssdl_defusing_20260624` campaign. Introduces `MetadataFieldCache` keyed by `(handle.index, field_name)`. The 123 string-keyed `entry.get('key', default)` field-access sites become 123 cache lookups. **BLOCKED_BY child 2** (the handle provides the stable cache key).
|
||||
|
||||
## Current State Audit (master @ child-2-SHIPPED, after metadata_generational_handle_20260624)
|
||||
|
||||
- `NIL_METADATA` sentinel exists (from child 1)
|
||||
- `MetadataHandle` + `MetadataHandleRegistry` exist (from child 2)
|
||||
- The 123 field-access sites in `src/aggregate.py`, `src/ai_client.py`, and other production files use `entry.get('key', default)` or `entry['key']` patterns
|
||||
|
||||
## Goals
|
||||
|
||||
| ID | Goal | Acceptance |
|
||||
|---|---|---|
|
||||
| G1 | `MetadataFieldCache` introduced: keyed by `(handle.index, field_name)` | The cache type is exported; can be created, queried, and invalidated |
|
||||
| G2 | The 123 field-access sites use the cache | `grep -rn "MetadataFieldCache\|field_cache.get\|field_cache.set" src/` returns ≥ 1 hit per site |
|
||||
| G3 | 1 behavioral test for the cache | `tests/test_metadata_field_cache.py` exists; asserts hit, miss, invalidation via generation bump |
|
||||
| G4 | Budget gate met: effective-codepaths drop ≥ 30% vs post-child-2 measurement | Re-measurement shows the drop |
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- Touching the 4 other `dict[str, Any]` aliases — out of scope
|
||||
- Touching the list-typed aggregates — out of scope
|
||||
- Replacing the 3 candidate placeholders — blocked on `any_type_componentization_20260621`
|
||||
- Cache for the inner Metadata values within nested structures (the campaign handles the top-level Metadata)
|
||||
- Eviction policy (LRU, etc.) — the cache is small (123 entries) and keyed by handle; no eviction needed
|
||||
|
||||
## Functional Requirements
|
||||
|
||||
### FR1: Cache type
|
||||
|
||||
In a sensible location (likely `src/aggregate.py`):
|
||||
|
||||
```python
|
||||
class MetadataFieldCache:
|
||||
def __init__(self) -> None:
|
||||
self._cache: dict[tuple[int, str], Any] = {}
|
||||
self._generations: dict[int, int] = {} # mirrors the registry
|
||||
|
||||
def get(self, handle: MetadataHandle, field_name: str) -> Any:
|
||||
# if handle.generation != self._generations[handle.index], return None (sentinel equivalent)
|
||||
# otherwise return self._cache.get((handle.index, field_name), NIL)
|
||||
|
||||
def set(self, handle: MetadataHandle, field_name: str, value: Any) -> None:
|
||||
# if handle.generation != self._generations[handle.index], ignore (stale write)
|
||||
# otherwise self._cache[(handle.index, field_name)] = value
|
||||
|
||||
def invalidate(self, index: int) -> None:
|
||||
# clear all entries for this index; bump generation
|
||||
```
|
||||
|
||||
(Exact API up to Tier 2; the contract is: cache keyed by `(index, field_name)`, generation-aware invalidation.)
|
||||
|
||||
### FR2: Migrate the 123 field-access sites
|
||||
|
||||
For each `entry.get('key', default)` or `entry['key']` site in the production code:
|
||||
- Replace with `cache.get(handle, 'key') or NIL_METADATA.get('key', default)` (or similar; the exact pattern depends on whether the cache returns the raw value or the cached Metadata)
|
||||
- Alternative: the cache stores the entire Metadata (or per-field values), and consumers request `(handle, 'field_name')`
|
||||
|
||||
The exact migration pattern is up to Tier 2. The acceptance criterion is that the 123 sites are migrated.
|
||||
|
||||
### FR3: Behavioral test
|
||||
|
||||
`tests/test_metadata_field_cache.py` with at least 4 tests:
|
||||
- `test_cache_hit`: `cache.get(handle, 'key')` after `cache.set(handle, 'key', value)` returns value
|
||||
- `test_cache_miss`: `cache.get(handle, 'key')` without prior set returns NIL (or None)
|
||||
- `test_cache_invalidation_on_bump`: after `cache.invalidate(handle.index)`, `cache.get(handle, 'key')` returns NIL
|
||||
- `test_cache_stale_write_ignored`: `cache.set(stale_handle, 'key', value)` does not write
|
||||
|
||||
## Non-Functional Requirements
|
||||
|
||||
- NFR1: 1-space indentation
|
||||
- NFR2: CRLF line endings on Windows
|
||||
- NFR3: No comments in source code
|
||||
- NFR4: Per-task atomic commits with git notes
|
||||
- NFR5: No new pip dependencies
|
||||
- NFR6: `Result[T]` returns for fallible cache methods
|
||||
- NFR7: No new `src/<thing>.py` files
|
||||
|
||||
## Architecture Reference
|
||||
|
||||
- `NIL_METADATA` (child 1) — the sentinel returned by `cache.get` on miss or stale write
|
||||
- `MetadataHandle` + `MetadataHandleRegistry` (child 2) — the handle provides the cache key
|
||||
- `docs/reports/code_path_audit/2026-06-22/AUDIT_REPORT.md` Finding 1 Fix 2 — the Immediate-Mode Cache proposal
|
||||
- `src/code_path_audit_ssdl.py` — the SSDL infrastructure used to measure progress
|
||||
- `conductor/code_styleguides/data_oriented_design.md` — canonical DOD reference
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- The 4 other `dict[str, Any]` aliases (deferred)
|
||||
- The 3 candidate placeholders (blocked)
|
||||
- Runtime profiling (Track F)
|
||||
- Eviction policy (the cache is small)
|
||||
|
||||
## Verification Criteria (Definition of Done)
|
||||
|
||||
| # | Criterion | Verification command |
|
||||
|---|---|---|
|
||||
| VC1 | `MetadataFieldCache` exists | `grep -rn "class MetadataFieldCache" src/` |
|
||||
| VC2 | Production code uses the cache at field-access sites | `grep -rn "field_cache.get\|field_cache.set" src/` returns ≥ 1 hit |
|
||||
| VC3 | Behavioral test exists and passes | `uv run pytest tests/test_metadata_field_cache.py -v` |
|
||||
| VC4 | Budget gate met | `compute_effective_codepaths(Metadata_profile)` returns number ≥ 30% smaller than post-child-2 measurement |
|
||||
| VC5 | Full test suite remains green | `uv run python scripts/run_tests_batched.py` → 11/11 tiers PASS |
|
||||
| VC6 | 4 audit gates remain clean | weak_types ≤ 112, type_registry in sync, main_thread_imports clean, no_models_config_io clean |
|
||||
|
||||
## Risks
|
||||
|
||||
| # | Risk | Likelihood | Mitigation |
|
||||
|---|---|---|---|
|
||||
| R1 | Cache invalidation is wrong (stale values returned) | medium | Cache is keyed by handle; when the underlying value changes, the handle's generation bumps (via the registry), invalidating cache entries. Behavioral test verifies the invalidation path. |
|
||||
| R2 | The 123 field-access sites are not actually 123 (audit was wrong) | low | Re-run `src.code_path_audit.detect_access_pattern_evidence` after migration to count the actual sites |
|
||||
| R3 | Budget gate fails (drop < 30%) | low | The cache collapses 123 lookups to 1 lookup each; expected to be a large drop. If not, investigate. |
|
||||
Reference in New Issue
Block a user