feat(atlas): execute deterministic Phase 2 panel selection - #14
Merged
Conversation
Define the offline selector API, fail-closed registration/lock/universe verification, injected identity replay boundary, complete full-universe search, synthetic RED test contract, run-record schema, and no-selection-until-clean workflow without naming candidates or producing a panel. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Define official ClinVar response acquisition, unique-match and unresolved replay rules, external map and candidate-free lock schemas, offline runtime API, synthetic RED tests, and the no-selection-until-mapper-clean boundary without embedding candidate identities. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Add the injectable acquisition seam to the mapper spec and protect 30 synthetic RED contracts covering official unique/zero/ambiguous responses, content and lock drift, path safety, offline runtime, lookup comparands, immutability, network failure, rate limiting, and exclusive publication without real candidate identities. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Implement hash-bound map/lock/official-response verification, exact replay lookups, immutable records, path and junction safety, and a fail-closed out-of-process NCBI acquisition adapter. The protected 30-contract suite and checker hardening suite pass; no real candidate map or panel is produced. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Add exhaustive NLM transcript-to-protein reference pagination, typed endpoint validation, current-title HGVS and residue replay for legacy aliases, schema-v2 wire versioning, and active candidate-free identity-map lock v4. Official replay resolves 25 identities and preserves 10 unresolved without selecting a panel. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Publish candidate-free universe lock v3 and aggregate summaries after official identity-map v4 replay. Three previously resolved aliases become unresolved/ambiguous; all 35 rows and 37 attributable observations are preserved; no panel is selected. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Publish candidate-free universe lock v4 and aggregate summary with identities and observations unchanged from v3, correcting the stale protocol bindings recorded by the inactive lock v3. No selection is performed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Version the panel protocol and registration to v1.0.4, bind valid universe lock v4 and official identity-map lock v4, add fail-closed V7/IM1-IM6 before replay, reject stale lock v3, and preserve all selection seeds, constraints, relaxation and search semantics. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Add the substantive 106-ID protected RED suite and close selector implementability gaps around repo-root custody and raw-inventory hashing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Add src/raptor/atlas/panel.py implementing V1-V7 preconditions, RP1-RP7 normalization replay, strata/lineage recomputation, E1-E8 eligibility, the Section 17 exhaustive relaxation-ladder search and Section 18 disposition classification. Add scripts/run_panel_selection.py as the sole thin CLI adapter (argv/env -> explicit paths -> select_panel -> run record), keeping panel.py statically pure. Extend model.py additively with the selector's frozen dataclasses and typed error hierarchy, and export the 12 spec-pinned public names from __init__.py. 113/117 protected selector tests and 222/226 full Atlas tests pass. The 4 remaining failures are genuine frozen-fixture/test defects (reported separately, not implementation gaps): two forced-full-selection fixtures with zero combinatorial freedom (test_ps_d_001, test_ps_p_007), one self-referential regex bug in the frozen test file's own purity scan (test_ps_x_006), and one real data mismatch between two forbidden, pre-existing fixture files (test_ps_i_001). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Authority: docs/project/atlas/ATLAS_PHASE2_PANEL_SELECTION_PROTOCOL.md, docs/project/specs/atlas-panel-selector-v1.yaml. Protected tests: tests/atlas/test_panel_selection.py (unmodified). 1. Repo-relative path containment (resolve_active_lock / identity-map lock resolution): _repo_relative_path() only rejected a symlink on the leaf, so a Windows directory JUNCTION planted on an ANCESTOR of a tracked artifact (which carries the reparse point on the ancestor, not the leaf) let selection read content outside SelectionInputs.repo_root while still returning PANEL_SELECTED. Added _verify_real_containment(), mirroring citation.py's realpath-containment principle: resolve(strict=True) the full chain and reject anything whose real path escapes repo_root's real path, or whose leaf is itself a symlink/reparse point. A candidate that does not exist anywhere is passed through unchanged so callers' own typed missing-artifact errors are preserved. 2. IM6 identity-map-binding verification (_verify_identity_map_binding_on_universe_lock): only 6 of 9 required fields were compared (missing schema, map_id, lock_id) and the nested pack_binding was never checked, so a tampered map_id/lock_id/schema/pack_binding in the universe lock's identity_map_binding passed silently. Now compares all 9 fields (schema/map_id/map_content_hash/map_version against the verified map manifest; lock_id/lock_version/lock_content_hash/response_bundle_hash/ map_record_count against the verified map lock) plus the nested pack_binding against the universe lock's own K2/V4-verified top-level pack_binding. map_created_at remains excluded (non-governing). The check now runs inside verify_identity_map() (new universe_lock parameter) immediately after the map lock/manifest/mapper are independently verified, so it can never be satisfied by a value this function already trusted for a different check. 3. Section 18 run record (render_run_record): recorded the configured node budget as max(nodes_expanded across attempts) whenever no override was supplied, conflating "configured" with "actually expanded", and omitted selection_seed, search_scope, declared constraints, the full attempt log, per-stratum coverage, the auxiliary secondary-stratum table, recomputed lineage groups with confidence, named discordant cells, and X5 attrition distribution. Now reloads the same caller-supplied, hash-verified registration/universe (no clock/ env/argv/git access) to recompute the true configured search_node_budget (kept distinct from the new max_nodes_expanded field) and to render the complete procedure/result surface. All pre-existing blocks (verified_digests, normalization_replay, identity_map, dispositions, provenance) and pre-existing keys are unchanged/preserved. Verification: all three defects reproduced via a throwaway, non-committed script comparing this fix against the unmodified HEAD (fbb4ac4) module in an isolated namespace -- each now fails closed where it previously succeeded silently. python -m pytest tests/atlas/test_panel_selection.py -q and python -m pytest tests/atlas -q both give the same 113/222 passed with exactly the four pre-existing frozen-suite failures (PS-D-001, PS-P-007, PS-X-006, PS-I-001), all pre-existing and unrelated to this change. git diff --check is clean. Only src/raptor/atlas/panel.py is modified. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
render_run_record() re-loads the registration and candidate universe
from disk to reconstruct the Section 18 procedure/result surface, but
never bound those reloaded bytes back to the digests verified during
the selection run that produced the SelectionRun. A file changed on
disk after select_panel() ran but before render_run_record() was
called (e.g. a rewritten registration_id/search_scope/constraints, or
a rewritten universe) was therefore rendered as if it were the exact
verified input, with no error.
Add _bind_reloaded_snapshot_to_run(): immediately after each reload,
recompute the artifact's authoritative content hash with the existing
registration_content_hash()/candidate_universe_content_hash() selector
primitives and compare it to report.verified_registration_content_hash
/ report.verified_universe_content_hash captured on run.preconditions
at selection time -- never a re-check of the reloaded bytes' own
embedded self-hash, which a self-consistent replacement artifact would
trivially pass. Any mismatch fails closed with the existing
AtlasPanelRegistrationError (RR1) / AtlasUniverseContractError (RR2)
before a single reloaded value reaches the record, so no partial or
success-shaped record is ever returned. Both artifacts are still read
exactly once, so rendering itself opens no second TOCTOU window.
Reproduced both defects (registration and universe post-selection
drift) against the pre-fix module: the old code silently rendered
procedure.search_scope == "tampered_scope" and
procedure.declared_constraints == {"tampered": true} for a mutated
registration, and silently accepted a mutated universe. The fixed
code raises a typed error in both cases, and unchanged inputs
continue to render byte-deterministically.
python -m pytest tests\atlas\test_panel_selection.py -q -> 117 passed
python -m pytest tests\atlas -q -> 226 passed
git diff --check -> clean
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Bring the reviewed Atlas selector onto the cross-platform CI repair baseline before formal execution. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
load_selection_registration() required the synthetic literal
"atlas.phase2_panel_selection_registration.v1", which does not match
the real frozen schema declared by the tracked registration artifact
and by the corrected registration fixtures/assertions in
tests/atlas/test_panel_selection.py: "atlas.panel_selection_registration.v1".
Replace the incorrect literal with the real frozen schema id. No
dual-accept/normalization was introduced -- the loader now requires
exactly the one correct schema string, same as before the bug, just
corrected. No other logic changed; registration content bytes/hash
are untouched (registration_content_hash() of the real registration
still resolves to 5b8980024bd88f9f3c7269badf7fc3e709fef4ba135b3575a7513e5d17ad1653).
Before: load_selection_registration(REGISTRATION_PATH) raised
AtlasPanelInputError ("has schema 'atlas.panel_selection_registration.v1',
expected 'atlas.phase2_panel_selection_registration.v1'").
After: it loads successfully and returns schema ==
"atlas.panel_selection_registration.v1".
tests/atlas/test_panel_selection.py: 117 passed (was 85 failed / 32 passed
at the required RED head 212fa72).
tests/atlas: 226 passed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Preserve the exit-3 schema mismatch as a non-selection audit record; no panel or run result was emitted. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
_verify_identity_map_binding_on_universe_lock() compared the universe
lock's identity_map_binding.schema field against map_manifest["schema"]
("atlas.raw_identity_map.v2", the raw map's own schema). The binding's
"schema" field actually mirrors the map LOCK's schema
("atlas.raw_identity_map_lock.v2") -- confirmed by the real, frozen
registration's identity_map_contract.active block, which declares these
as two distinct named fields ("schema" vs "map_schema"), and by the
corrected test fixtures/assertion in tests/atlas/test_panel_selection.py
(build_world's identity_map_binding, and test_ps_i_001's explicit
"IM6 schema must bind to map_lock, not map_manifest" assertion).
Compare binding.get("schema") to map_lock.get("schema") instead. No
dual-accept was introduced: map_id/map_version/map_content_hash still
compare against map_manifest, and every other IM6 field/nested
pack_binding comparison is unchanged. Docstring corrected to match.
Before (HEAD, real tracked artifacts): verify_identity_map() raised
AtlasIdentityMapBindingError -- "universe lock identity_map_binding
disagrees with the verified identity map: schema" (the same fault
observed executing the real formal-selection CLI, exit code 3).
After (fixed, same real artifacts): verify_identity_map() succeeds,
checks_passed includes IM6; a mutated identity_map_binding.schema is
still correctly rejected with the same typed error (no dual-accept).
tests/atlas/test_panel_selection.py: 117 passed (was 62 failed / 55
passed at the required RED head 7ba6d8c).
tests/atlas: 226 passed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Preserve the IM6 schema mismatch as a non-selection audit record; no panel or run result was emitted. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Preserve the RP4 transcript-pin mismatch as a candidate-free non-selection audit record. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
This commit corrects the synthetic test fixtures to omit transcript_pin from universe records, conforming to protocol sections 4.2 and 4.3. The test suite correctly turns RED against current production since the runner still improperly requires the per-record transcript pin (RP4). PS-R-004 is retargeted to the top-level transcript pin, and PS-I-001 asserts the real universe shape. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
replay_normalization() checked transcript_pin inside the generic per-record RP4 field loop, comparing it against record.get(field). The corrected universe schema (v4) pins transcript identity once, at the universe's top level (universe['transcript_pin']), never per record, since this is a single-gene/single-transcript panel. record.get( 'transcript_pin') therefore always returned None, so every resolved record's real (non-None) replayed transcript spuriously mismatched -- the exact RP4 UNIVERSE_CONTRACT_BREACH exit-3 failure hit during the formal selection run. Fix: remove transcript_pin from the generic per-record loop and add a dedicated comparison: expected transcript is universe['transcript_pin'] when replay.identity_state == 'resolved', else None. Unresolved records must replay with no transcript identity at all; resolved records must match the frozen universe-wide pin. Same AtlasUniverseContractError / UNIVERSE_CONTRACT_BREACH / RP4 shape as before. Other RP4 comparisons (spdi_canonical, hgvs_c, hgvs_p, residue_index, codon_index) preserved unchanged, same evaluation order. Verification: - Real tracked v4 universe/raw-inventory/identity-map artifacts via replay_normalization(): pre-fix code (git show HEAD) raises the exact production error -- raw record field 'transcript_pin' disagrees between the candidate universe and the verified replay (RP4); fixed code no longer raises on transcript_pin for that record and proceeds to a later, unrelated check (RP6 exclusion_flags/exclusion_code disagreement on the same record) -- a separate, out-of-scope defect, confirming the run now reaches beyond transcript RP4. - Mutating the real universe's top-level transcript_pin still correctly raises RP4 with the fix applied (check has teeth). - Synthetic fake-replay probes: resolved+matching passes, resolved+wrong-transcript raises RP4, unresolved+None passes, unresolved+fabricated-transcript-equal-to-real-pin still raises RP4 (no dual-accept / no fabrication loophole for unresolved records). Tests: tests/atlas/test_panel_selection.py 117/117 passed; tests/atlas 226/226 passed. No test or authority-artifact files modified. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
…tion Protocol RP6 compares the replayed ELIGIBILITY exclusion code (section 8.2) with declared exclusion_flags, but rev 2 rendered RP6 as the single mapper field RawIdentityReplay.exclusion_code. The verified mapper is deliberately selection-protocol independent and cannot know the caller-supplied AnchorSpec, so a universe that legitimately declares the anchor exclusion X3 could never satisfy a mapper-only comparand: the frozen input was unexecutable. Rev 3 defines the EFFECTIVE exclusion code -- mapper-owned identity/scope exclusion (authoritative) reconciled with the selector-owned, anchor-derived X3, empty otherwise -- requires declared exclusion_flags to equal its exact singleton/empty list, and raises UNIVERSE_CONTRACT_BREACH(RP6) on any disagreement or mapper/anchor conflict. The mapper is never passed or taught the anchor. - replay_normalization pinned with a required keyword-only AnchorSpec argument - anchor_threading_rule: verify_preconditions supplies inputs.anchor only after V7 returns the attestation; V1,V2,V3,V4,V5,V7,V6 order unchanged - RP6 field mapping re-scoped to mapper-owned + rp6_note ownership split - RawIdentityMapper.anchor_independence - PS-R-007 expanded to four mandatory synthetic RP6 cases - two beat4 inversions for the new seam No selection semantics moved: seed/V3, panel size, strata, lineage, eligibility E1-E8, constraints, relaxation ladder, search, budget, evidence firewall and every frozen input binding are structurally identical to rev 2. Plan-only: one spec file, no code, tests, locks, registration or data. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
…clusion This commit modifies PS-R-007 to incorporate the exact rev 3 specification for the RP6 exclusion reconciliation contract. The new tests verify that mapper-owned exclusions and the selector-owned, anchor-derived X3 are properly reconciled during eplay_normalization(..., anchor=AnchorSpec). All specified test cases are covered (identity anchor X3, residue anchor X3, effective None, anchor injection proof asserting unchanged digests, and mapper/anchor conflict). The tests are currently RED because the production runner lacks the anchor-aware reconciliation logic. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
…r-aware exclusion Rev-3 RP6 reconciliation: replay_normalization now takes pack and a keyword-only AnchorSpec, computing the effective exclusion code as (0) CONFLICT if the mapper's non-null exclusion_code coincides with a resolved, anchor-matching replay (fail-closed, names both codes), (1) the mapper's exclusion_code when non-null (mapper-owned, authoritative), (2) X3 when the resolved replay's spdi_canonical or non-null residue_index matches the anchor (selector-owned), else (3) None. Declared exclusion_flags must equal exactly [effective_code] or []. The anchor is threaded only through inputs.anchor -> replay_normalization's new keyword argument; the mapper never receives it (anchor_isolation preserved). Verification: - tests/atlas/test_panel_selection.py: 115/117 pass; 2 known pre-existing failures proven to be frozen-test-fixture defects unrelated to this implementation (see task report): test_ps_r_007's "anchors" sub-case passes a value-identical AnchorSpec on both its must-pass and must-raise calls (missing an explicit anchor= override matching its own residue-61 setup on the first call), and test_ps_d_001's unrelated "rec-extra2" fixture coincidentally sits at residue/spdi 99, the suite's shared default anchor value, spuriously colliding with real anchor semantics the test predates. - tests/atlas full suite: 224/226 pass (same 2 failures, no other regressions). - Real tsc2-phase2 v4 artifacts: replay_normalization now completes RP1-RP7 with a self-consistent anchor for the one real record the universe already declares X3 for (previously failing under the pre-anchor-aware RP6 check), confirming the fix resolves the real downstream defect found while validating the prior RP4 fix. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
- Fix test_ps_r_007 to pass explicit matching anchor and verify different_anchor fails. - Simplify conflict test to trigger RP6 flag assertion mismatch. - Change test_ps_d_001 rec-extra2 residue to 101 to avoid default anchor residue 99 collision. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the vacuous conflict case with a direct, non-vacuous call to the real replay_normalization production helper where the replay row is resolved, matches the injected AnchorSpec, and carries a non-null mapper-owned exclusion code. The test now proves the dedicated conflict guard is reached, and fails-closed correctly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Replace the in-place object.__setattr__ mutation with copy.copy() to return a fresh replay object with the forged exclusion_code. This isolates the conflict test from the real mapper's cached frozen replay, which is now asserted to remain strictly unchanged before and after the failure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Preserve the Section-17 constraint-shape mismatch as a candidate-free non-selection audit record. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
…ation
The fourth real execution attempt cleared every fail-closed precondition
(V1,V2,V3,V4,V5,V7,V6 and the full RP1-RP7 replay) and then died in the
FORMAL pre-search step with AtlasPanelRegistrationError(INPUT_FAULT)
"unrecognized constraint formula None", before the first attempt was
enumerated and before any run record was written.
The gap is in the spec, not the artifacts. Rev 3 named the Section-17
constraints and required every parameter to be READ from the registration,
but never said where the numeric thresholds live. The frozen registration
has no constraints mapping at all -- it carries the relaxation ladder as
seven prose strings and nothing else -- so a literal implementation looks
up a key that does not exist, gets None, and fails.
Rev 4 closes the seam with a CLOSED canonical constraint contract keyed to
the exact supported protocol version AND its V1-verified doc hash, plus
exact seven-string equality validation of the registration ladder:
- typed error codes CONSTRAINT_CONTRACT_UNSUPPORTED_PROTOCOL and
RELAXATION_LADDER_DRIFT; AtlasPanelRegistrationError.means extended
- authority_and_scope.hardcoding_prohibition_scoped_exception -- one narrow
carve-out for protocol-owned values pinned to version AND doc hash
- frozen types RelaxationStep, ConstraintContract, ActiveConstraints
- module_api.search: materialize_constraint_contract, constraints_at_level;
complete_search and run_attempt_schedule pinned to the structured contract
- module_api.search.constraint_contract: L0 bases, closed threshold grammar,
the seven-string comparand, structured steps, cumulative rung evaluation,
prohibitions and call site
- run_record declared_constraints pinned to the materialized set plus the
validated ladder, never registration.get("constraints")
- DC-12 records the rejected repairs; three beat4 inversions added
- test obligations extended inside existing ids only: PS-A-008, PS-O-001,
PS-O-004, PS-P-005, PS-X-001, PS-D-005, PS-I-001
No selection semantics move. Every threshold keeps its protocol value at
every rung, the ladder keeps its order and terminal step, the gate keeps
INFEASIBLE_COMPLETE as the only advance condition, and UNDETERMINED still
terminates the run. Only the SOURCE of the thresholds and their drift
detection are now defined.
Spec-only change: protocol, registration, locks, code, tests and data
records are untouched.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Removed the synthetic top-level `constraints` mapping and replaced the dict-shaped ladder entries with the exact ordered strings dictated by revision 4. This ensures the synthetic registration mirrors the real shape exactly. Added `materialize_constraint_contract` probes to PS-A-008, enforcing failure codes for protocol versions, hashes, and ladder drift. Inserted `constraints_at_level` checks in PS-P-005 to cover all base/rung thresholds at multiple n values. Appended checks to PS-D-003 to assert that the run record emits non-null, structured `declared_constraints`, and statically asserted that the runner does not fall back to reading `registration["constraints"]` or parsing Markdown semantics. The test suite now correctly fails against current production, proving the required RED evidence for the revision 4 contract constraints. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Aligned test cases with exact revision-4 specifications: 1. Updated materialize_constraint_contract signatures to use strict keyword args (registration, verified_protocol_version, verified_protocol_doc_hash). 2. Standardized unsupported protocol errors to CONSTRAINT_CONTRACT_UNSUPPORTED_PROTOCOL. 3. Updated ladder drift errors to RELAXATION_LADDER_DRIFT. 4. Corrected constraints_at_level calls to explicitly pass the contract object. 5. Replaced dict index property assertions with ActiveConstraints getattr property accesses. 6. Corrected run record constraint mapping block assertions from top-level to procedure.declared_constraints and validated the required spec keys. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Removed the broad try/except block around materialization and rung evaluation in PS-P-005, making the calls mandatory. Corrected the expected 'applied_steps' to be a cumulative tuple of step IDs instead of full ladder strings. These changes ensure PS-P-005 natively fails (direct RED on missing API) without silently swallowing exceptions and continuing with downstream tests. Also removed the duplicated 'constraints_at_level' logic block at the bottom of the test. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Replaced the broken `_constraint_base`/`_constraint_at_rung` pair (which
always read the nonexistent `registration["constraints"]` and always
returned None, raising "unrecognized constraint formula None" on every
attempt) with a real materialize-then-evaluate pipeline:
- model.py (additive): new frozen dataclasses `RelaxationStep`,
`ConstraintContract`, `ActiveConstraints`.
- panel.py:
- `materialize_constraint_contract()` binds the closed, protocol-owned
base thresholds/explicit-logic-constraint ids/relaxation-step table to
one run, gated on an exact `verified_protocol_version` match against
the single supported version "1.0.4", and on `verified_protocol_doc_hash`
matching the registration's own pinned `protocol_doc_hash` (raises
CONSTRAINT_CONTRACT_UNSUPPORTED_PROTOCOL on either mismatch).
- `_validate_declared_ladder()` compares the registration's declared
seven-string `relaxation_ladder` against the canonical comparand
position-by-position (accepting both `list` and `tuple`, since the
frozen runtime registration and the test fixture's writer-side dict
differ in this respect), raising RELAXATION_LADDER_DRIFT naming the
first differing position.
- `constraints_at_level()` evaluates all seven thresholds (C3/D1/D2/D3/
P1/P2/P3) plus `c5_enforced` at one `(level, n)`, applying every
relaxation step at or before that rung cumulatively (last-write-wins).
- `_eval_threshold` extended to parse bare-digit-string thresholds
(e.g. "3"), since base/step values are typed as strings, not ints.
- `_check_constraints`/`_run_attempt`/`select_panel` rewired to thread
one `ActiveConstraints` per attempt instead of reading a registration
threshold mapping that never existed.
- `render_run_record` now re-materializes the contract from the freshly
reloaded, re-verified registration and renders a complete
`declared_constraints` block (protocol_version, protocol_doc_hash,
base_thresholds, explicit_logic_constraints, declared_ladder,
relaxation_steps, levels_evaluated), replacing the old
`registration.get("constraints")` (always None).
`__init__.py` intentionally left unmodified: no test imports the three
new dataclasses by package path, and several other pre-existing "detail"
dataclasses (AttemptOutcome, PreconditionReport, etc.) are likewise not
re-exported at the package level.
Real-input proof (direct `select_panel()` call, not the formal CLI, per
Slot 3): the real v4 registration/protocol/universe clear
`materialize_constraint_contract` (real protocol_version "1.0.4",
real protocol_doc_hash self-consistent, real relaxation_ladder equal to
the canonical comparand verbatim) and 24 real attempts run to completion
across all 8 levels (L0..R7) with no formula-evaluation error, entering
attempts;
outcome details are not reported here per the identity/evidence
non-disclosure convention established across this packet series.
Spec-vs-test divergences documented (concrete tests taken as ground
truth over spec prose, consistent with this packet series' established
precedent):
- The spec's `hardcoding_prohibition_scoped_exception`/DC-12 prose
describes hardcoding both the supported protocol version AND the real
protocol_doc_hash literal. This is mathematically impossible to
reconcile with PS-A-008's happy path, which passes a synthetic world's
own non-real hash and must succeed. Implemented instead: hash
self-consistency against the registration's own pinned digest (a
no-op in production, where V1 already guarantees this equality, but a
real, independently meaningful check for direct callers like PS-A-008).
- DC-12's falsifier prose mentions "a single flipped hex digit"; the
actual PS-A-008 negative case uses `"0" * 64`, not a single-digit flip.
- The spec's hash-mismatch prose does not describe a
"missing registration.protocol_version" clause distinct from the
verified_protocol_version parameter; not implemented, as no test
exercises it.
Tests: tests/atlas/test_panel_selection.py 117 passed (was 35 failed/82
passed at RED head af2421c); tests/atlas full suite 226 passed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
- Map synthetic worlds to exact tracked protocol bytes - Advance synthetic binding versions to 1.0.4/1.0.3 - Author PS-V-001 tests for wrong/missing protocol_version and doc_hash - Prove RED against production's self-consistency fallback (V2) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Restore V1 to digest-only precondition. - Move missing/wrong registration version and doc_hash checks into direct PS-A-008 materialization. - Prove direct RED on missing protocol version validation in revision-4 constraints. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
`materialize_constraint_contract` previously only checked the caller-
attested `verified_protocol_version`/`verified_protocol_doc_hash` pair
(the latter via self-consistency against the registration's own pinned
digest), never reading `registration["protocol_version"]` or re-checking
`registration["protocol_doc_hash"]` against anything absolute. A
registration whose declared `protocol_version` had silently drifted (or
was missing outright) while `protocol_doc_hash` still matched the live
protocol document would still materialize the contract -- the caller's
attestation and the registration's own declaration were never required to
agree, and neither was pinned to a single absolute value.
- panel.py: added `_SUPPORTED_CONSTRAINT_PROTOCOL_DOC_HASH` alongside the
existing `_SUPPORTED_CONSTRAINT_PROTOCOL_VERSION`. `materialize_constraint_contract`
now raises `CONSTRAINT_CONTRACT_UNSUPPORTED_PROTOCOL` unless all four of
`verified_protocol_version`, `verified_protocol_doc_hash`,
`registration["protocol_version"]`, and `registration["protocol_doc_hash"]`
equal the one supported pair exactly (plain string/lowercase-hash
equality; missing values compare `!= ` the supported value and fail
identically to a wrong one; no normalization, no self-consistency-only
acceptance).
- `select_panel`/`render_run_record` call sites now pass
`registration.get("protocol_version")` as `verified_protocol_version`
(the registration-declared value) instead of unconditionally passing
the hardcoded supported-version constant regardless of what the
registration actually declares -- closing the gap where a caller-side
constant could paper over registration drift.
- __init__.py (additive): re-exported `RelaxationStep`, `ConstraintContract`,
`ActiveConstraints` from `raptor.atlas.model`, alphabetically placed in
both the import block and `__all__`.
Before/after real-input probe (direct `select_panel()` call, not the
formal CLI, per Slot 3): identical outcome class before and after this
fix against the real, frozen v4 registration/universe/protocol -- 24
attempts across all 8 levels (L0..R7), terminal_outcome
INFEASIBLE_PANEL, independence_status DECLARED -- because the real
registration's own protocol_version ("1.0.4") and protocol_doc_hash
already equal the one supported pair. The fix only tightens rejection of
drifted/missing registration-side values; it does not change real-data
behavior.
Tests: tests/atlas/test_panel_selection.py 117 passed (was 116 passed/1
failed -- PS-A-008's new wrong/missing-registration-field sub-cases --
at RED head dc3756b); tests/atlas full suite 226 passed (was 225/1
failed).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
Record the independently audited INFEASIBLE_PANEL outcome after 24 exhaustive frozen-ladder attempts, and update public program/todo status without selecting or promoting any candidate. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
srinivasdrona
added a commit
that referenced
this pull request
Aug 6, 2026
Bring the BLOCKED_DATA publication onto main after PR #14 while preserving both public status updates. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c146921-f3dd-4a1e-8cf0-8f574de49204
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.
Summary
INFEASIBLE_PANELafter 24 complete L0-R7 attempts; no panel, selected candidate, claim, or promotionValidation
python -m pytest tests\atlas -q— 226 passedpython -m pytest -q— 1233 passed, 22 skipped; one environment-only failure because optionalpysamis not installedBoundaries
Research-only. The result does not classify variants, accept mechanism claims, authorize clinical use, or permit outcome-dependent candidate substitution.