conductor(metadata): correct metadata_promotion_20260624 metadata.json for per-aggregate design
This commit is contained in:
@@ -1,68 +1,126 @@
|
||||
{
|
||||
"track_id": "metadata_promotion_20260624",
|
||||
"name": "Metadata Promotion: dict[str, Any] -> @dataclass(frozen=True, slots=True)",
|
||||
"name": "Metadata Promotion: per-aggregate dataclasses + direct field access (NOT a shared mega-dataclass)",
|
||||
"status": "active",
|
||||
"type": "fix",
|
||||
"parent": "any_type_componentization_20260621",
|
||||
"grandparent": "code_path_audit_20260607",
|
||||
"date_created": "2026-06-25",
|
||||
"created_by": "tier1-orchestrator",
|
||||
"corrected": "2026-06-25",
|
||||
"correction_note": "Original spec (commit e50bebdd) proposed a single shared @dataclass(frozen=True, slots=True) Metadata with ~200 fields for all 5 sub-aggregates. Rejected 2026-06-25 on user direction: each sub-aggregate is its own dataclass with its own fields; Metadata: TypeAlias = dict[str, Any] is preserved as the catch-all for collapsed codepaths only. See docs/reports/PLANNING_CORRECTION_metadata_promotion_20260625.md for the full rationale.",
|
||||
"blocks": [],
|
||||
"blocked_by": {
|
||||
"code_path_audit_phase_3_provider_state_20260624": "pending (not started yet; recommended prerequisite to run in parallel)"
|
||||
"code_path_audit_phase_3_provider_state_20260624": "shipped (the per-vendor _X_history aliases were removed; ChatMessage and ToolCall from openai_schemas.py are now wireable into the send paths)"
|
||||
},
|
||||
"scope": {
|
||||
"new_files": [
|
||||
"tests/test_metadata_dataclass.py",
|
||||
"docs/reports/metadata_promotion_progress.md"
|
||||
"tests/test_comms_log_entry.py",
|
||||
"tests/test_history_message.py",
|
||||
"tests/test_tool_definition.py",
|
||||
"tests/test_rag_chunk.py",
|
||||
"tests/test_session_insights.py",
|
||||
"tests/test_discussion_settings.py",
|
||||
"tests/test_custom_slice.py",
|
||||
"tests/test_mma_usage_stats.py",
|
||||
"tests/test_provider_payload.py",
|
||||
"tests/test_ui_panel_config.py",
|
||||
"tests/test_path_info.py",
|
||||
"tests/test_context_preset_schema.py",
|
||||
"docs/reports/PLANNING_CORRECTION_metadata_promotion_20260625.md",
|
||||
"docs/reports/TRACK_COMPLETION_metadata_promotion_20260624.md"
|
||||
],
|
||||
"modified_files": [
|
||||
"src/type_aliases.py"
|
||||
],
|
||||
"consumer_files": [
|
||||
"src/session_logger.py",
|
||||
"src/multi_agent_conductor.py",
|
||||
"src/type_aliases.py",
|
||||
"src/rag_engine.py",
|
||||
"src/models.py",
|
||||
"src/gui_2.py",
|
||||
"src/app_controller.py",
|
||||
"src/ai_client.py",
|
||||
"src/aggregate.py",
|
||||
"src/gui_2.py",
|
||||
"src/mcp_client.py",
|
||||
"src/models.py",
|
||||
"src/paths.py",
|
||||
"src/synthesis_formatter.py"
|
||||
"src/aggregate.py",
|
||||
"src/session_logger.py",
|
||||
"src/multi_agent_conductor.py",
|
||||
"src/conductor_tech_lead.py",
|
||||
"conductor/code_styleguides/type_aliases.md"
|
||||
],
|
||||
"new_dataclasses": [
|
||||
{"name": "CommsLogEntry", "module": "src/type_aliases.py", "fields": 8},
|
||||
{"name": "HistoryMessage", "module": "src/type_aliases.py", "fields": 6},
|
||||
{"name": "ToolDefinition", "module": "src/type_aliases.py", "fields": 4},
|
||||
{"name": "SessionInsights", "module": "src/type_aliases.py", "fields": 6},
|
||||
{"name": "DiscussionSettings", "module": "src/type_aliases.py", "fields": 3},
|
||||
{"name": "CustomSlice", "module": "src/type_aliases.py", "fields": 4},
|
||||
{"name": "MMAUsageStats", "module": "src/type_aliases.py", "fields": 3},
|
||||
{"name": "ProviderPayload", "module": "src/type_aliases.py", "fields": 4},
|
||||
{"name": "UIPanelConfig", "module": "src/type_aliases.py", "fields": 3},
|
||||
{"name": "PathInfo", "module": "src/type_aliases.py", "fields": 3},
|
||||
{"name": "RAGChunk", "module": "src/rag_engine.py", "fields": 4}
|
||||
],
|
||||
"reused_existing_dataclasses": [
|
||||
{"name": "Ticket", "module": "src/models.py", "fields": 15},
|
||||
{"name": "FileItem", "module": "src/models.py", "fields": 10},
|
||||
{"name": "ContextPreset", "module": "src/models.py", "fields": "extended"},
|
||||
{"name": "ToolCall", "module": "src/openai_schemas.py", "fields": 3},
|
||||
{"name": "ToolCallFunction", "module": "src/openai_schemas.py", "fields": 2},
|
||||
{"name": "ChatMessage", "module": "src/openai_schemas.py", "fields": 5},
|
||||
{"name": "UsageStats", "module": "src/openai_schemas.py", "fields": 4},
|
||||
{"name": "NormalizedResponse", "module": "src/openai_schemas.py", "fields": 4}
|
||||
],
|
||||
"consumer_files_migrated": [
|
||||
"src/gui_2.py",
|
||||
"src/app_controller.py",
|
||||
"src/ai_client.py",
|
||||
"src/mcp_client.py",
|
||||
"src/aggregate.py",
|
||||
"src/session_logger.py",
|
||||
"src/multi_agent_conductor.py",
|
||||
"src/conductor_tech_lead.py",
|
||||
"src/rag_engine.py"
|
||||
],
|
||||
"deprecated": [
|
||||
"src/type_aliases.py:CommsLogEntry:TypeAlias = Metadata (replaced by class CommsLogEntry)",
|
||||
"src/type_aliases.py:HistoryMessage:TypeAlias = Metadata (replaced by class HistoryMessage)",
|
||||
"src/type_aliases.py:ToolDefinition:TypeAlias = Metadata (replaced by class ToolDefinition)",
|
||||
"src/models.py:Ticket.get() method (legacy compat; removed in Phase 1.3)"
|
||||
]
|
||||
},
|
||||
"verification_criteria": [
|
||||
"Metadata is @dataclass(frozen=True, slots=True), not dict[str, Any]",
|
||||
"All 107 .get('key', ...) access sites on Metadata consumers replaced",
|
||||
"All 106 ['key'] subscript access sites on Metadata consumers replaced",
|
||||
"tests/test_metadata_dataclass.py: 12+ tests pass",
|
||||
"All 5 sub-aggregate TypeAliases (CommsLogEntry, HistoryMessage, FileItem, ToolDefinition, ToolCall) point to the new Metadata",
|
||||
"Metadata: TypeAlias = dict[str, Any] is UNCHANGED in src/type_aliases.py",
|
||||
"Each new sub-aggregate is its OWN @dataclass(frozen=True, slots=True) in the appropriate module (11 new dataclasses across src/type_aliases.py and src/rag_engine.py)",
|
||||
"Existing per-aggregate dataclasses (Ticket, FileItem, ToolCall, ChatMessage, UsageStats) are REUSED unchanged; their consumers migrate to direct field access",
|
||||
"All 107 .get('key', ...) access sites on KNOWN sub-aggregates replaced with direct field access",
|
||||
"All 106 ['key'] subscript access sites on KNOWN sub-aggregates replaced with direct field access",
|
||||
"Remaining .get() sites are FR2 collapsed-codepath sites (TOML config, generic JSON, polymorphic log) with per-site documented justification in the Phase 11 commit message",
|
||||
"12 per-aggregate regression-guard test files exist and pass (5+ tests per file; 60+ tests total)",
|
||||
"Effective codepaths drops by >= 2 orders of magnitude (< 1e+20; was 4.014e+22)",
|
||||
"All 7 audit gates pass --strict (no regression)",
|
||||
"10/11 batched test tiers PASS (RAG flake acceptable)",
|
||||
"End-of-track report written (docs/reports/TRACK_COMPLETION_metadata_promotion_20260624.md)",
|
||||
"New regression-guard test file (tests/test_metadata_dataclass.py)"
|
||||
"End-of-track report written (docs/reports/TRACK_COMPLETION_metadata_promotion_20260624.md) with the new effective-codepaths number and the per-aggregate classification of the remaining .get() sites",
|
||||
"Planning correction report exists (docs/reports/PLANNING_CORRECTION_metadata_promotion_20260625.md)"
|
||||
],
|
||||
"estimated_effort": {
|
||||
"method": "scope (per workflow.md \u00a7Tier 1 Track Initialization Rules). NO day estimates.",
|
||||
"scope": "1 source file replaced (src/type_aliases.py: 30 lines -> ~200 lines for the dataclass) + 1 new test file (12+ tests) + 10 consumer files modified (~213 access sites total) + 6 phase checkpoint commits; estimated 18-21 atomic commits total"
|
||||
"method": "scope (per workflow.md §Tier 1 Track Initialization Rules). NO day estimates.",
|
||||
"scope": "1 source file extended (src/type_aliases.py: 30 lines -> ~200 lines for 10 new dataclasses + 1 source file extended (src/rag_engine.py: +5 lines for RAGChunk) + 1 source file extended (src/models.py: ContextPreset schema completion) + 9 consumer files modified (~213 access sites total across 12 phases) + 12 new test files (5+ tests each; 60+ tests total) + 1 styleguide clarification + 2 docs reports; estimated 29+ atomic commits total across 13 phases"
|
||||
},
|
||||
"risk_register": [
|
||||
"R1 (medium): 213 access sites have polymorphic keys that don't fit cleanly into a single dataclass - mitigated by Optional[T] for all fields + from_dict() classmethod + to_dict() for serialization",
|
||||
"R2 (low): Some sites do entry['key'] with dynamic keys - mitigated by keeping dict-style access for dynamic keys via entry.to_dict()[var_name]",
|
||||
"R3 (low): to_dict() round-trip loses information for nested dicts - mitigated by careful implementation; nested dicts pass through as dict[str, Any]",
|
||||
"R1 (medium): 213 access sites have polymorphic keys that don't fit cleanly into a per-aggregate dataclass - mitigated by Optional[T] for all fields + from_dict() classmethod filtering unknown keys + to_dict() for serialization (canonical pattern from src/openai_schemas.py and src/models.py:FileItem)",
|
||||
"R2 (low): Some sites do entry['key'] with dynamic keys - mitigated by keeping dict-style access via entry.to_dict()[var_name] for those rare cases",
|
||||
"R3 (low): to_dict() round-trip loses information for nested dicts - mitigated by careful implementation; nested dicts pass through as dict[str, Any] (per the FileItem.to_dict() precedent)",
|
||||
"R4 (medium): Some sites mutate entry (e.g., entry['key'] = value); dataclass is frozen - mitigated by audit + replacement with dataclasses.replace()",
|
||||
"R5 (low): Migration breaks regression-guard tests - mitigated by per-phase regression-guard test runs",
|
||||
"R6 (high): 695 consumer functions are too many for one track - mitigated by 5-phase sub-aggregate migration; each phase independent",
|
||||
"R7 (medium): Dict-shape used for JSON-serialized payloads (comms.log); dataclass breaks JSON layer - mitigated by to_dict() + from_dict() methods on the dataclass"
|
||||
"R5 (low): Migration breaks regression-guard tests for the existing dataclasses (Ticket, FileItem) - mitigated by per-phase regression-guard test runs",
|
||||
"R6 (high): 213 access sites across 12 phases is a large migration - mitigated by per-aggregate phase structure; each phase is small and shippable independently; per-phase regression-guard catches regressions early",
|
||||
"R7 (medium): Dataclass name collisions with existing names (Metadata in models.py vs type_aliases.py; ProviderPayload may collide with existing names) - mitigated by module-qualified imports and naming review in Phase 0",
|
||||
"R8 (low): Some sites use the legacy Ticket.get(key, default) method for backward compat - mitigated by removing the method in Phase 1.3 after all consumers have migrated"
|
||||
],
|
||||
"out_of_scope": [
|
||||
"Modifications to src/code_path_audit*.py (the audit infrastructure is correct)",
|
||||
"The 4 NG1 + 7 NG2 audit violations (already addressed in dc397db7)",
|
||||
"The 4.01e22's nil-check component (per SSDL post-mortem; minor contributor)",
|
||||
"The RAG test pre-existing flake (per docs/reports/SSDL_CAMPAIGN_ABORTED_20260624.md Out of Scope)",
|
||||
"New src/<thing>.py files (per AGENTS.md hard rule; the dataclass goes in src/type_aliases.py)",
|
||||
"The 5 sub-aggregates becoming separate dataclasses each (overkill; they share the same Metadata base)"
|
||||
"The 4.01e22's nil-check component (per docs/reports/SSDL_CAMPAIGN_ABORTED_20260624.md; minor contributor)",
|
||||
"The RAG test pre-existing flake (per SSDL post-mortem)",
|
||||
"New src/<thing>.py files (per AGENTS.md hard rule; new dataclasses go in src/type_aliases.py for type-system aggregates or in the existing parent module)",
|
||||
"Promoting Metadata: TypeAlias = dict[str, Any] itself to a shared mega-dataclass (the original spec's bad inference; rejected 2026-06-25)",
|
||||
"Migrating the FR2 collapsed-codepath sites (self.project.get('paths', {}), self.project.get('conductor', {}), etc.) - these read manual_slop.toml; the shape is genuinely unknown at type level",
|
||||
"Pydantic migration (the canonical pattern is stdlib @dataclass(frozen=True, slots=True); Pydantic is for input validation only)"
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user