W5b-13: FieldSemantics — engine filling + group-summary probability_status (step 2 complete) - #53
Merged
Merged
Conversation
bnsd55
marked this pull request as draft
September 18, 2026 22:52
bnsd55
marked this pull request as ready for review
September 18, 2026 22:55
- jevmlx/api.py: frozen FieldSemantics dataclass (score_source / temperature /
calibrator_id / prior_mode / constraint_changed / dependency_rescored) per
the approved design note (GPT-REVIEW-2 §C9); FieldResult.semantics REQUIRED
(keyword-only, no default) — constructing without it is a loud TypeError;
_build_field_results passes telemetry.get('semantics') through (step 2
fills it in the engine stages).
- README: FieldResult bullet documents semantics + the probability_status
summary downgrade wording from the design note.
- tests/test_field_semantics.py: dataclass contract (frozen, field names,
required kw-only), export surface (single import path — the module-eviction
identity trap), and the engine-filling pins marked xfail(strict=True)
reason 'W5b-13 step 2' (verified: a simulated step-2 pass XPASSes and
fails the suite, so the flip is loud).
672 passed, 2 xfailed; ruff clean.
- F1: FieldResult is now @DataClass(frozen=True, kw_only=True) — semantics loses the kw_only-field + type: ignore hack; 'reason' loses its default (all fields kw_only). Callers updated; the one production constructor (_build_field_results) passes every field by name already. - F2: placeholder summary test deleted; test_probability_status_is_a_summary rewritten cleanly against the step-2 behavior (helper returns the engine status, no duplicated fixture, no placeholder line). - F3: README semantics bullet removed — ships with step 2. - FieldResult.semantics docstring now states the draft truth: the PR does not leave draft until every decided field carries a real record. - Kept: frozen FieldSemantics, the two contract tests, xfail(strict=True) pins (strictness re-verified: simulated step-2 pass XPASSes and fails). 672 passed, 2 xfailed; ruff clean.
…_status becomes the group summary - engine: _field_semantics() is the ONE constructor for the semantics record (dict — the api import graph stays one-way; api.FieldSemantics coerces at the public boundary). - score_scalar_field: score_source from the finalizer's evidence_source (batch -> batched, batch1 -> rescored_batch1); temperature = the fitted scalar T when the bundle applied it, the caller T otherwise; prior_mode from prior_corrected. _cardinality_one_outcome: schema-determined record (temperature None, nothing corrected). - score_multi_field: score_source mirrors the scalar vocabulary (rescored_batch1 when any Y/N pair was band-rescored); temperature None when the calibrated log-odds cut set the selection (it ignores T); calibrator_id from the bundle; constraint_changed from solve_multi_set's reconciled_by. Count row: temperature None (fixed T=1 buckets), its own constraint_changed. - reconcile_case_constraints + the post-dependency MAP: flips set constraint_changed=True on exactly the changed fields. - _selective_second_pass: a dependency re-decide REPLACES the field's semantics (score_source dependency/oracle, dependency_rescored True, prior constraint_changed carried over). - finalize_public_result: probability_status is the group-count SUMMARY — one clause per distinct (score_source, temperature, calibrator_id, prior_mode) group with its field count; the old global-only statement is deleted (kept only as the no-records fallback for fake/baseline paths). - api._build_field_results: coerces telemetry['semantics'] into the frozen FieldSemantics; a missing record is a ValueError naming the field — 'required' is now true at every decide() return. - tests: conftest make_field_semantics factory (default record on every fake telemetry shape); test_field_semantics.py rewritten one-pin-per- behavior (decide coercion, loud missing-record failure, group summary + prior/calibrator clauses via finalize_public_result, engine shapes, constraint flips, calibrated split); old global-string pins updated; xfail marks dropped. - README: semantics bullet + probability_status summary wording. 746 passed -m 'not slow', 2 slow pins green, ruff clean.
bnsd55
force-pushed
the
w5b-semantics
branch
from
September 19, 2026 08:52
14ed2e4 to
6edbcff
Compare
…5/F7/F10
- F1: the old global-only probability_status strings are DELETED; an empty
semantics-group set now raises (every engine path sets records).
- F2: all four None-tolerant sites index directly — finalize_public_result
(ft['semantics']), reconcile_case_constraints, the post-dependency MAP,
_selective_second_pass (prev record + assignment), api boundary
(telemetry['semantics']). grep 'get("semantics")' jevmlx/*.py is EMPTY.
- F3: count-row constraint_changed = reconciled_by == 'count' AND the
trusted count actually ran (dropped_reason None); an untrusted count no
longer claims a constraint.
- F4: multi constraint_changed compares the FINAL selection against the
raw threshold proposal (solve_multi_set now records
telemetry['threshold_proposal']); a trusted non-binding count no longer
claims a change.
- F5: score_scalar_field no longer re-derives the applied temperature —
the temperature argument IS the effective one (_load_calibration
replaced it); cardinality-1 outcome built via _field_semantics.
- F6: three new engine-path pins (prior_correction -> neutral_v1 on a real
run; count-row temperature None + copied score_source; uncalibrated
multi carries caller T) + trusted/untrusted-count constraint_changed
pin — each mutation-verified to fail when its setter is removed.
- F7: contradictory comment in test_engine_sets_semantics_on_all_shapes
fixed (multi carries caller T=1.0 when uncalibrated).
- F8: CHANGELOG Unreleased entry for W5b-13.
- F9: ARCHITECTURE.md — probability_status row = group summary;
'semantics' row in the field_telemetry table and the FieldResult table.
- F10: FieldResult.semantics docstring no longer says 'None until then'.
750 passed -m 'not slow', slow status pin green, ruff clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Steps 1+2 complete per the approved design note (GPT-REVIEW-2 §C9), rebased on main@bb86a3f (#51/#55/#58 in).
Engine filling (step 2):
_field_semantics()— the ONE constructor for the semantics record (dict; api coerces to frozenFieldSemantics; the import graph stays one-way).score_scalar_field:score_sourcefrom the shared finalizer'sevidence_source(batch → batched, batch1 → rescored_batch1); temperature = the fitted scalar T when the bundle applied it, else the caller T;prior_modefrom prior_corrected. Cardinality-1: schema-determined (temperature None).score_multi_field:rescored_batch1when any Y/N pair was band-rescored; temperature None when the calibrated log-odds cut set the selection (it ignores T — exactly the §C9 mix the old global string lied about); calibrator_id from the bundle;constraint_changedfrom solve_multi_set's reconciled_by. Count row: temperature None (fixed T=1 buckets), its own constraint_changed.reconcile_case_constraints+ post-dependency MAP: flips setconstraint_changed=Trueon exactly the changed fields._selective_second_pass: a dependency re-decide REPLACES the field's semantics (score_source dependency/oracle,dependency_rescored=True, earlier constraint_changed carried).finalize_public_result: probability_status is the group-count summary — one clause per distinct(score_source, temperature, calibrator_id, prior_mode)group with its field count. The old global-only statement is deleted (fallback kept for fake/baseline paths without records).api._build_field_results: coerces the record into frozenFieldSemantics; a missing record raises naming the field — 'required' is now true at every decide() return.Verification: 746 passed
-m 'not slow'; slow status pins green; end-to-end fake-engine probes confirm the calibrated-split summary (T=0.7clause +calibrated (bundle …)clause), the dependency-group summary, and the constraint-flip record. One pin per behavior; xfail marks dropped; README carries the semantics + summary wording.STATE: IDLE, awaiting #53 review