core/docs/analysis/pr836-lookback-2026-06-20.md

3 KiB

PR #836 Lookback — feat(kernel): introduce construction-affordance catalog skeleton

This lookback documents the design rationale, implementation details, and verification results for the initial slice of the construction-affordance catalog skeleton.

Rationale & Design Choices

1. Catalog Registry is Diagnostic-Only

Every entry in generate/construction_affordances.py is configured with diagnostic_only=True and serving_allowed=False. This enforces a clean trust boundary:

  • Candidate structures and affordances can be registered, introspected, and traced diagnostically.
  • The runtime serving path remains completely untouched and isolated, preventing any serving-time regressions.

2. Separation of Registry and Dispatch Logic

The contract assessment functions (assess_fraction_decrease and assess_percent_partition in generate/problem_frame_contracts.py) contain construction-specific structural logic, role bindings, and hazard checks.

  • We introduced _CONTRACT_REGISTRY to map candidate organs to catalog entries.
  • To prevent a leaky abstraction and forced interfaces, the actual dispatch in assess_contracts() remains explicit and structural, but references the catalog metadata where applicable.
  • This ensures the registry remains a metadata/introspection layer describing what a construction means, while the assessment functions describe how its obligations are proven.

3. Question-Target Priority Cascade

We documented the priority cascade inside _bound_question_target (in generate/problem_frame_builder.py). This prevents order-fragility in future additions:

  1. Specific regex-based triggers (e.g. _DECREASE_DELTA_QUESTION_RE for proportional decrease delta).
  2. General question clause extraction via _QUESTION_ENTITY_RE (or fallback to unresolved if ? is present).
  3. Clause-level target classification (e.g. more -> difference, originally -> initial, left -> final, etc.).

Closed Test Gaps

We successfully added targeted test coverage to tests/test_problem_frame_contracts.py to close all outstanding edge cases from the proportional-change proof of concept:

  • Scale boundary rejection: Rejects scale values of 0 (0/4), 1 (4/4), or greater than 1 (5/4) with a scale_out_of_range blocker.
  • Multi-base rejection: Ensures multiple candidate relations trigger decrease_relation_ambiguous.
  • State entity continuity: Rejects cases where the state entity in the relation differs from the target entity of the question, triggering state_entity_continuity_unproven.
  • Unit continuity: Rejects cases where the base quantity unit does not match the relation unit, triggering unit_continuity_unproven.
  • Percent-partition blocker specificity: Asserts that unequal-partition confusers correctly surface partition_subgroups_not_distinct and percent_subgroup_links_incomplete.

Verification Results

  • All 46 tests across the targeted test suite pass successfully in < 0.5s.
  • Catalog behavior verified by new dedicated tests in tests/test_construction_affordances.py.