core/docs/adr/ADR-0236-engineering-principles-for-masterful-cleanup.md

14 KiB

ADR-0236: Engineering Principles for Masterful Cleanup

Status: Proposed

Date: 2026-06-25

Scope: Whole codebase; refactors, capability PRs, diagnostics, Workbench, runtime/kernel boundaries, eval/reporting surfaces

Depends on:

  • ADR-0223 Semantic Substrate Affordance Audit and Foundation Alignment
  • ADR-0224 Quantity-Entity foundational seam
  • ADR-0228 GeometricSearchRun envelope
  • ADR-0229 Contract/Proof Replay Adapter boundary
  • ADR-0230 Sealed Practice Trace boundary
  • ADR-0231 First Candidate Operator boundary
  • ADR-0232 CandidateAttempt Run-Binding boundary
  • ADR-0233 Bound Practice Episode Sealing
  • ADR-0234 Second Candidate Operator Selection
  • ADR-0235 Apple Silicon UMA acceleration lanes
  • INV-30 open-world determination never asserts False
  • Existing wrong-zero, replay, provenance, and proposal-first discipline

1. Summary

CORE is now large enough that ordinary cleanup is not sufficient. Refactors must serve the architecture rather than only reduce file size, silence lint, or make code look conventional.

This ADR establishes the engineering principles that future cleanup and implementation PRs must cite when changing boundaries, splitting modules, retiring legacy seams, adding diagnostics, or promoting new capability paths.

The principles are intentionally ordinary software engineering principles, but interpreted through CORE's load-bearing requirements:

Deterministic cognition
Exact provenance
Proposal-first construction
Authority separation
Wrong-zero serving discipline
Replay equivalence
Fail-closed behavior
No hidden normalization
No approximate recall
No downstream phase manufacturing upstream evidence

The short form:

extractors observe
proposers hypothesize
binders ground
contracts assess
proof/verifiers admit or refuse
renderers disclose
Workbench observes unless explicitly allowlisted
serving remains separately authorized

2. Problem

As CORE adds ProblemFrame construction, contract residuals, candidate operators, sealed practice, Workbench evidence surfaces, and native acceleration lanes, some modules can accumulate too many responsibilities.

The immediate motivating example is generate/problem_frame_builder.py. It has historically acted as all of the following:

scalar extraction
unit extraction
hazard extraction
process-frame detection
construction proposal generation
mention extraction
mention binding
quantity-kind disposition
bound relation construction
question-target binding
ProblemFrame assembly
post-build contract/assessment coordination

That mixture weakens auditability even when behavior is currently correct. A future change can accidentally move evidence across phase boundaries, give a proposal assessment authority, treat absence as proof, or make a diagnostic path look like a serving path.

CORE therefore needs a repeatedly citeable engineering canon for cleanup.

3. Decision

Future cleanup and implementation PRs SHOULD be organized around the principles below. A PR that intentionally violates one of these principles MUST explain the violation, identify the bounded exception, and add a test or ADR-scoped non-goal that prevents the exception from becoming doctrine drift.

3.1 Single Responsibility / One Reason to Change

A module, object, or function should have one conceptual job and one primary reason to change.

For CORE, responsibility boundaries are semantic, not merely syntactic:

extractors observe raw/evidenced surface facts
proposers create diagnostic hypotheses
binders attach exact spans and roles
contracts assess existing evidence
proof/verifiers admit or refuse
renderers disclose state without deciding it
Workbench reads evidence unless an action is explicitly allowlisted

A file is suspect when it changes for unrelated reasons such as extraction, proposal timing, binding topology, assessment authority, and rendering policy.

Required cleanup posture:

When a file changes because of multiple independent concepts, split by pipeline
phase before adding more capability.

3.2 Authority Boundary Principle

Only one layer may have authority to make a given class of decision.

Examples:

ConstructionProposal may propose only.
ContractAssessment may declare runnable/refused diagnostic readiness.
determine() may determine open-world True, never open-world False.
FrameVerdict may handle closed-world local verdicts under its own firewall.
Renderer may disclose; it may not decide.
Workbench may observe unless an action is explicitly allowlisted.

Forbidden drift:

proposal object carrying runnable/refused state
builder manufacturing proposals from assessment output
renderer deciding epistemic state
UI route mutating runtime truth state without an allowlisted action
heuristic parser silently becoming a serving fact producer

Required cleanup posture:

Every object/function should have a documented authority level. If the authority
is unclear, rename, split, or remove the path.

3.3 Phase Separation Principle

CORE pipelines must preserve phase order.

Canonical construction sequence:

surface evidence
-> ConstructionProposal
-> exact mentions and bindings
-> ContractAssessment
-> proof/derivation or refusal
-> independent verification
-> admission/refusal
-> disclosure/rendering

Downstream phases MUST NOT manufacture upstream evidence. A ContractAssessment may inspect proposals and bound evidence, but it must not create the proposal that supposedly justified the assessment.

Required cleanup posture:

No downstream phase may create, repair, or backfill upstream evidence unless a
separate ADR explicitly defines a replayable repair phase with its own evidence
and authority boundary.

3.4 Explicit Evidence Over Implicit Defaults

Absence is not proof.

Forbidden patterns:

no unit found -> count
no contradiction found -> true
no error raised -> safe
no reviewer present -> accepted
no evidence span -> synthetic placeholder treated as provenance

CORE posture:

absence of evidence -> unresolved or refused
positive evidence -> candidate
contract/proof/verifier -> admitted within scope

Required cleanup posture:

Remove silent defaults that create semantic state. Replace them with explicit
unresolved, refused, or no-disposition outcomes.

3.5 Dependency Direction / No Backward Imports

Import direction must follow pipeline direction.

Preferred shape:

builder imports extractors/proposers/binders
proposers import construction catalog/factory only
binders import frame/kernel facts only
contracts import ProblemFrame/read evidence and catalog metadata
renderers import disclosure/read models only
Workbench imports read APIs and explicit action APIs

Suspicious shape:

extractor imports contract
proposal factory imports assessment
contract creates proposal
builder imports serving dispatcher
UI imports mutable runtime internals

Required cleanup posture:

If import direction contradicts pipeline direction, stop and refactor before
adding capability.

3.6 Invariants as Code, Not Comments

An architectural rule is not durable until it is machine-pinned.

Acceptable pins include:

unit test
property test
AST/source-boundary test
import-boundary test
replay test
schema validator
lane SHA
gold/holdout eval
contract assertion

Examples of rules that should be pinned:

ConstructionProposal.status == "proposed" only
ContractAssessment never creates ConstructionProposal
open-world determine() never emits answer=False
no hidden normalization inside propagation
no diagnostic-only module imported by serving dispatch
replay-stable canonical ordering for emitted artifacts

Required cleanup posture:

Every important architectural sentence should eventually become a test, a lane,
or an explicit ADR-scoped non-goal.

3.7 Fail-Closed / Refusal-First

Unknown or ambiguous states must not become authority by default.

Forbidden patterns:

except: return answer
missing pack: continue
ambiguous relation: choose first
failed verification: use candidate anyway
unknown unit: assume count

Required cleanup posture:

Any fallback must prove that it cannot increase authority. If it cannot prove
that, it must fail closed, refuse, or emit an unresolved diagnostic state.

3.8 Determinism / Replay Equivalence

Same inputs must produce the same semantic trace unless a declared nondeterminism boundary exists.

Required properties:

canonical ordering
stable IDs
content-addressed or claim-addressed keys where appropriate
no set/dict-order leakage in emitted artifacts
no time/random/environment dependence in reasoning
same input -> same frame/proposals/contracts/disclosure

Required cleanup posture:

Any emitted artifact must have deterministic ordering and replay-stable identity.

3.9 Diagnostic Is Not Serving

Diagnostic artifacts may aid humans, tests, Workbench, and future candidate operators. They do not grant serving authority.

Diagnostic examples:

ProblemFrame
ConstructionProposal
ContractAssessment
ContractResidual
CandidateOperatorResult
CandidateAttemptRunBinding
SealedPracticeTrace
Workbench trace panels
eval/readiness reports

Forbidden drift:

diagnostic_only=True object imported by serving dispatcher
eval readiness metric changing runtime behavior
candidate score admitted without proof or verifier
Workbench evidence card mutating truth state

Required cleanup posture:

Diagnostic artifacts may inform review and practice; they may not serve unless a
separate reviewed PR grants serving authority and adds proof/replay gates.

3.10 Locality and Exact Provenance

Semantic claims must be tied to exact source evidence.

Required properties:

exact SourceSpan
stable mention ID
explicit binding edge
explicit role
explicit evidence_spans
span text matches source text
no synthetic spans masquerading as observed provenance

Required cleanup posture:

No semantic object without provenance. No provenance without exact span integrity.

3.11 No Clever Abstractions Before Repeated Proof

CORE should prefer duplicated clarity over premature generalization until shared structure is proven by multiple real families and tests.

Suspicious abstractions:

generic universal graph
generic semantic parser
generic all-constructions engine
generic proposal status machine
generic contract runner that hides family-specific obligations

Required cleanup posture:

Keep narrow family-specific logic until at least two or three real use cases
prove the abstraction and its invariants.

3.12 Small Load-Bearing PRs

A cleanup PR should strengthen one named invariant.

Preferred PR names:

refactor(kernel): split ProblemFrame proposal extraction
fix(kernel): remove assessment-backed proposal fallback
fix(kernel): require positive quantity-kind grounding
test(algebra): pin raw-vs-closed versor boundaries
docs(workbench): separate diagnostic and teaching proposal vocabulary

Forbidden PR shape:

refactor everything in ProblemFrame and improve contracts and update Workbench

Required cleanup posture:

One PR = one primary invariant strengthened.

4. Cleanup Review Checklist

Every cleanup or capability PR SHOULD answer these questions in its description or tests when relevant:

Responsibility:
- Does each touched module have one clear reason to change?

Authority:
- Did any object/function gain decision authority it should not have?

Phase order:
- Did any downstream phase create upstream evidence?

Evidence:
- Are all semantic claims tied to exact spans/provenance?

Failure:
- Do unknown/ambiguous cases refuse or remain unresolved?

Determinism:
- Is output order/id generation canonical and replay-stable?

Serving boundary:
- Did diagnostic-only code remain non-serving?

Tests:
- Is the architectural rule pinned by a test, lane, schema, or explicit non-goal?

Scope:
- Is this PR strengthening one primary invariant rather than many unrelated ones?

5. Immediate Application to ProblemFrame Cleanup

This ADR authorizes using the above principles to guide a sequence of bounded ProblemFrame cleanup PRs. It does not itself implement those changes.

Recommended order:

1. Pin proposal-first assessment boundary with regression tests.
2. Remove assessment-backed proposal synthesis and retire make_proposal().
3. Split problem_frame_builder.py by pipeline phase while preserving behavior.
4. Add import/source-boundary tests for proposal creation authority.
5. Fix quantity-kind grounding so absence of a unit does not imply count.
6. Add raw-vs-closed versor boundary tests for Python/Rust runtime use.
7. Apply the same authority/read-only discipline to Workbench read models.

Suggested module split, if and when performed:

generate/problem_frame_builder.py
    public facade and orchestration only

generate/problem_frame_extractors.py
    scalar, unit, hazard, process-frame extraction

generate/problem_frame_proposals.py
    construction proposal detection only

generate/problem_frame_mentions.py
    mention and MentionBinding extraction

generate/problem_frame_bound_relations.py
    quantity-kind dispositions, bound relations, bound question target

The split should be behavior-preserving. Semantic hardening should happen in separate PRs unless the existing behavior is already violating a pinned invariant and the PR scope explicitly names that invariant.

6. Non-Goals

This ADR does not:

  • implement any refactor;
  • alter runtime behavior;
  • change serving admission;
  • mutate packs, reports, sealed traces, or eval artifacts;
  • authorize broad rewrites;
  • introduce a universal intermediate representation;
  • promote diagnostic artifacts to serving authority;
  • relax wrong-zero, replay, evidence, or proof gates.

7. Consequences

Positive consequences:

  • Refactors become strategically organized rather than aesthetic.
  • PRs can cite a common engineering doctrine.
  • Authority leaks become easier to detect and reject.
  • Workbench and diagnostics can grow without silently becoming serving paths.
  • ProblemFrame and candidate-operator work can remain coherent as capability expands.

Costs:

  • Some cleanup will take more PRs.
  • Files may remain temporarily large while invariants are pinned first.
  • Contributors must justify dependency direction and authority boundaries.
  • Premature abstraction is deliberately slowed.

This cost is accepted because CORE values truthfulness, replayability, mechanical auditability, and wrong-zero discipline over short-term refactor speed.