Implements byte-size budget enforcement for the ACMS context assembly
pipeline. enforce_size_budget() filters context fragments against
max_file_size (per-fragment) and max_total_size (cumulative) limits
defined in a ContextView. New domain models BudgetViolation and
BudgetEnforcementResult provide structured violation reporting.
Pipeline integration in ACMSPipeline.assemble() applies enforcement
as a pre-filter when a context_view is provided.
Review feedback addressed:
- Fixed PR milestone to v3.4.0 (matching ticket #847)
- Rebased branch onto latest master
- Added CHANGELOG.md entry
- Extracted duplicated enforcement logic into _apply_budget_enforcement()
shared method on ACMSPipeline, called by both parent and subclass
- Fixed _make_fragment return type from object to ContextFragment
- Moved all imports to top of files (acms_pipeline.py, steps file)
- Added errors="replace" to encode("utf-8") for surrogate safety
- Documented thread-safety caveat on last_enforcement_result property
- Added short-circuit early return when both limits are None
- Added multi-byte Unicode content test scenario
- Added total_size assertions to key scenarios
- Added violation type verification to mixed limits scenario
- Merged duplicate singular/plural step definitions
- Added edge case scenarios (empty list, all exceed, exact boundary)
- Fixed misleading docstring in ContextAssemblyPipeline.assemble()
- Re-exported VALID_PHASES through core __init__.py public API
ISSUES CLOSED: #847