Skip to content

fix(scoring): Issue #262 — rename DQIC site-2 emission to valuation_output_anomalous + writer-parity for veto cohort UI#265

Merged
dackclup merged 1 commit into
mainfrom
claude/issue-262-dqic-rename
May 26, 2026
Merged

fix(scoring): Issue #262 — rename DQIC site-2 emission to valuation_output_anomalous + writer-parity for veto cohort UI#265
dackclup merged 1 commit into
mainfrom
claude/issue-262-dqic-rename

Conversation

@dackclup
Copy link
Copy Markdown
Owner

Summary

Closes issue #262 (DQIC dual-surface emission inconsistency) per methodology-scientist Mode B verdict 2026-05-26 (APPROVED-AS-ANNOTATE, Path 3 = rename).

The dual-surface bug

data_quality_input_corruption was emitted from TWO independent check sites with DIFFERENT trigger conditions:

Site File Trigger Surface
1 compute/scoring/risk_overlay.py:411 INPUT-level: TBVPS > $10K/share OR TTM rev < $50M OR |NI| > |rev| risk_flags (VETO)
2 compute/valuation/ensemble.py:545 OUTPUT-level: ANY of 6 method outputs > $10K/share valuation_warnings (ANNOTATE)

Site 2's check is strictly broader than Site 1's.

Universe scan (2026-05-23 cron #3, methodology-scientist walk)

Surface pattern Count Tickers
BOTH risk_flags + valuation_warnings 2 ERIE (rank 69), BRK-B (rank 223)
Site 1 only — veto with NO UI explanation chip 4 MTB (320), CPT (347), MRNA (447), HBAN (460)
Site 2 only — annotate; Top-5-safety gap if rose 1 NVR (267)

The bigger smell than the NVR Top-5 risk is the UI explainability gap: FairPriceCard.tsx:82 reads only valuation_warnings, so MTB/CPT/MRNA/HBAN render the all-null fair-price ensemble with NO explanation chip.

Path 3 fix (this PR)

1. Rename Site 2 emission

compute/valuation/ensemble.py::_data_quality_corrupt_result now emits valuation_output_anomalous:

  • Per-method reason field (line 533)
  • valuation_warnings list (line 545)

Semantically distinct from the input-level data_quality_input_corruption: "a method produced an absurd output despite plausible inputs" is NOT categorical evidence of input untrust — could be residual input bug Site-1 missed, legitimately extreme RIM on a goodwill-heavy filer, OR a method-formula edge case. Annotate-only is the correct Rule 16 surface.

2. Writer-parity emit in compute/main.py

When data_quality_input_corruption is in risk_flags.get(ticker, []) (the VETO surface), ALSO append valuation_output_anomalous to valuation_warnings for UI parity. Closes the veto-only-cohort UI explainability gap (MTB/CPT/MRNA/HBAN now gain the UI chip).

3. Consumer updates

4. Tests

  • tests/test_valuation/test_ensemble.py — 4 assertions updated to expect new identifier
  • tests/test_output/test_tier2_schema.py::test_B4_skip_reasons_count_is_25_is_26
  • tests/test_scoring/test_sanity_smoke.py (2 sites) — unchanged; legacy-snapshot path verified via the OR check
  • tests/test_scoring/test_recommendation.py (2 sites) — unchanged; veto identifier (risk_flags) never renamed

No schema bump

String-identifier rename only — no new Metadata / StockDetail field. SCHEMA_VERSION stays at 0.10.5-phase4.5e. Triple lockstep unchanged.

ZERO composite-rank impact

Composite scores / risk_flags VETO identifiers / Top-5 rotation unchanged. The only behavioral effect is which identifier appears in valuation_warnings (a display field) and gains the writer-parity for the veto cohort UI.

Verification ladder

  • ruff check . — All checks passed
  • python -m compute.output.schema_check — clean (no schema change)
  • pytest tests/ -m "not network"1216 passed, 7 skipped, 24 deselected
  • CI: full lint+test+schema+frontend gauntlet
  • Vercel preview (auto-deploys post-push)

Deferred follow-ups

  • Q3 2026-08-19 quarterly audit — walk the valuation_output_anomalous firing list, decide whether to retire the legacy data_quality_input_corruption identifier from the taxonomy after ≥ 2 crons of clean rename adoption (methodology Q6)
  • φ-correlation re-baseline of valuation_output_anomalous vs existing extreme_*_estimate annotates (methodology Q3) — confirms the new identifier is independent enough to justify the taxonomy slot

Lockstep

Test plan

  • CI: Python lint+test should pass (1216 tests; this PR updates 4 assertions in test_ensemble + 1 in test_tier2_schema)
  • CI: Frontend build should pass (additive identifier in OR check; no behavior change)
  • Spot-check Vercel preview on /stock/MTB / /stock/CPT / /stock/HBAN to verify the UI annotate appears AFTER cron-feat(phase-3a): pillar feature modules — 30+ classical metrics #5 lands (will be missing pre-cron until next compute writes the new identifier)

https://claude.ai/code/session_01JwntEE4PNAXSMkZxRA9BB4


Generated by Claude Code

…utput_anomalous + writer-parity for veto cohort UI

Closes issue #262 (DQIC dual-surface emission inconsistency) per
methodology-scientist Mode B verdict 2026-05-26 (APPROVED-AS-ANNOTATE,
Path 3 = rename).

The bug: data_quality_input_corruption emitted from TWO independent
check sites with different trigger conditions:
- Site 1 (risk_overlay.py:411) — INPUT-level corruption; risk_flags VETO
- Site 2 (ensemble.py:545) — OUTPUT-level anomaly; valuation_warnings ANNOTATE

Site 2's check is strictly broader. Universe scan 2026-05-23 cron #3:
- 2 tickers fire BOTH (ERIE rank 69, BRK-B rank 223)
- 4 tickers fire Site 1 ONLY (MTB/CPT/MRNA/HBAN) — UI explainability gap
- 1 ticker fires Site 2 ONLY (NVR rank 267) — Top-5-safety gap if rose

The bigger smell than NVR Top-5 risk is the UI gap: FairPriceCard.tsx:82
reads only valuation_warnings, so MTB/CPT/MRNA/HBAN render all-null
fair-price with NO explanation chip.

Path 3 fix:
- Rename Site 2 (ensemble.py:533+545) → valuation_output_anomalous
- Writer-parity in compute/main.py: when DQIC veto fires in risk_flags,
  ALSO emit valuation_output_anomalous to valuation_warnings (closes
  UI gap for veto-only cohort)
- applicability.py SKIP_REASONS taxonomy gains valuation_output_anomalous
  (count 25 → 26); legacy data_quality_input_corruption retained for
  backward-compat on pre-rename JSON snapshots
- sanity.py:83 IC-smoke exclusion ORs both identifiers
- FairPriceCard.tsx:82 dataQualityIssue check ORs both identifiers

Tests:
- test_ensemble.py 4 assertions — assert new identifier on Site 2 emit
- test_tier2_schema.py::test_B4_skip_reasons_count → 25 to 26
- test_sanity_smoke.py / test_recommendation.py unchanged
  (legacy-snapshot path verified via OR check; veto identifier
  unchanged)

No schema bump (string-identifier rename only). SCHEMA_VERSION stays
0.10.5-phase4.5e. Triple lockstep unchanged.

ZERO composite-rank impact — composite scores / risk_flags VETO
identifiers / Top-5 rotation unchanged.

Verification: ruff clean / schema_check clean / pytest 1216 passed
(unchanged from PR #264 baseline).

PHASE_STATUS_INFLIGHT.md side-file entry satisfies §Conventions
"ship with every PR" lockstep per PR #237 convention. No CLAUDE.md
/ AGENTS.md substance change — rename doesn't introduce new
invariant; methodology verdict documented in INFLIGHT entry.

https://claude.ai/code/session_01JwntEE4PNAXSMkZxRA9BB4
@vercel
Copy link
Copy Markdown

vercel Bot commented May 26, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
quantrank Ready Ready Preview, Comment May 26, 2026 3:26am

@github-actions
Copy link
Copy Markdown
Contributor

Pre-merge production simulation

Field Value
Duration 353s
Universe size 502
Schema version 0.10.5-phase4.5e
Compute commit 5ec0c8070b7e239c5b280b252d1c592ffa39fd5e
PR-branch output pr-265-compute-output (14-day retention)

Diff vs main

Field Main PR Δ
Universe size 502 502 +0
Schema version 0.10.4-phase4.5e 0.10.5-phase4.5e ⚠️ bumped

Main baseline: 2026-05-26T01:12:47Z (0.1 days old)

Top-10 movers (sorted by |Δcomposite_score|)

Ticker PR rank main rank Δrank PR score main score Δscore
A 282 282 +0 49.56 49.56 +0.00
AAPL 25 25 +0 65.67 65.67 +0.00
ABBV 455 455 +0 38.41 38.41 +0.00
ABNB 335 335 +0 46.60 46.60 +0.00
ABT 438 438 +0 39.81 39.81 +0.00
ACGL 12 12 +0 66.93 66.93 +0.00
ACN 75 75 +0 59.45 59.45 +0.00
ADBE 10 10 +0 67.09 67.09 +0.00
ADI 401 401 +0 42.42 42.42 +0.00
ADM 342 342 +0 46.49 46.49 +0.00

@dackclup dackclup marked this pull request as ready for review May 26, 2026 03:36
@dackclup dackclup merged commit e6013ba into main May 26, 2026
5 checks passed
@dackclup dackclup deleted the claude/issue-262-dqic-rename branch May 26, 2026 03:36
dackclup added a commit that referenced this pull request May 26, 2026
…Craft frontend (#266)

Cuts the v1.3.0-phase4.5e release tag, closing the Phase 4.5e Form-4
insider-clustering ladder (PRs #167+#205+#222+#224+#238) and shipping
the LedgerCraft frontend reskin (A1-A3+B1-B4+animation PRs 1-3+#244
polish+dark-mode tooltip fixes through PR #263) since v1.2.0-phase4.5
(6d414a9, 2026-05-17).

Scope (3 files):
- pyproject.toml — version 0.3.0 → 1.3.0
- docs/release-notes/v1.3.0-phase4.5e.md (NEW) — release body grouped
  by Form-4 cluster / data-quality / defense layer / frontend /
  methodology + agent infra / CI hygiene; ~800 words
- PHASE_STATUS.md — Current state schema 0.10.4 → 0.10.5-phase4.5e,
  defense layer headline 32 → 33 declared flags, production-run
  pointer refreshed to 26423296287

Pre-flight ladder verified by release-captain (opus):
- ruff clean
- pytest 1216 passed (offline)
- schema_check in sync at 0.10.5-phase4.5e
- verify-production-output Section A-G + I-L PASS; Section H 1
  known FAIL (orphan BK.json legacy snapshot, pre-existing)
- frontend build verified via vercel-preview-auditor (sonnet) on
  main HEAD e6013ba — 506/506 routes compiled, types validated,
  runtime clean, 3-route UA probe PASS

Defense scorecard: 7 active vetoes unchanged
(altman_distress / sloan_accruals_top_decile / net_issuance_top_decile
/ non_reliance_filing / beneish_manipulation_veto /
dechow_manipulation_veto / data_quality_input_corruption).
Headline 32 → 33 declared boolean flags
(adds multi_class_aggregate_shares_suspected per PR #264; PR #265
DQIC rename is identifier-shape, not new flag).

Production output: metadata.json reports 0.10.4-phase4.5e from cron
#4 (2026-05-26T01:12); next weekday cron Wed 2026-05-27 22:00 UTC
re-renders at full 0.10.5-phase4.5e semantics. Tag is anchored to
code, not last committed snapshot per release-tag SKILL.md §Gotchas.

CVE baseline 25 → 15 open (0C/6H/7M/2L); all 15 are next@14.x SSR
advisories with zero exploitability on static-export.

Post-merge: tag command + GitHub Release creation require explicit
user authorization per CLAUDE.md §Executing actions with care.

https://claude.ai/code/session_01JwntEE4PNAXSMkZxRA9BB4

Co-authored-by: Claude <noreply@anthropic.com>
dackclup added a commit that referenced this pull request May 27, 2026
…AUDE.md (#271)

Refactors a user-shared research report (Master Prompt + 6 phase sub-prompts
+ CLAUDE.md template) into the existing doc surface without creating a new
.claude/skills/agentic-6-phase/ skill. The report's underlying logic is
already implemented in the 18 subagents + CLAUDE.md §Auto-routing; what
was genuinely missing was a 6-phase mapping table a new session can scan
in < 30 sec on top of the 9 phases.

Scope (2 substance files + 1 INFLIGHT entry):

- WORKFLOW.md — new section "Agentic 6-Phase Cadence" between §"Tools
  You'll Use Daily" and §"Phase Overview". Mapping table (Step × Fire
  trigger × Subagent(s) × Done when) over Planning → Code Gen →
  Integration → Test → Deploy → Monitor + 5 cadence invariants. Reuses
  the 18 standing subagents — no new agent files. Session-start protocol
  cites schema 0.10.5-phase4.5e (PRs #264 + #265; cron #4 still at
  0.10.4, next cron Wed 2026-05-27 re-renders at 0.10.5), defense
  layer 33 declared = 7 vetoes + 26 annotates, tag v1.3.0-phase4.5e,
  CVE baseline 15 open (0C / 6H / 7M / 2L) after PR #194 patch +
  PR #226 triage.
- CLAUDE.md — new §Conventions bullet "Session-start phase
  identification" (~5 lines) pointing readers at PHASE_STATUS.md
  §"Current state" + WORKFLOW.md §"Agentic 6-Phase Cadence" using the
  standing 18 subagents.
- PHASE_STATUS_INFLIGHT.md — new in-flight entry per PR #237 side-file
  lockstep convention.

Out of scope (deliberately NOT done per user direction 2026-05-27):

- NO .claude/skills/agentic-6-phase/ — overhead exceeds benefit
- NO Master Prompt / phase sub-prompts copied into the repo
- NO edits to any of the 18 subagent files under .claude/agents/
- NO AGENTS.md substance edit — the cadence is Claude-Code-subagent-
  specific; cross-tool agents would route differently. INFLIGHT entry
  satisfies §Conventions "ship with every PR" lockstep.

docs-reviewer verdict (2026-05-27, agent id a2c87ed3679f55fe5):
NEEDS-CROSS-REF-FIX — both items applied in this commit:
1. CVE attribution: "after PR #226 triage" → "after PR #194 patch +
   PR #226 triage" (PR #194 closed the 10 advisories; PR #226
   documented the resulting state)
2. Step 4 fire-trigger col: "Sections A-J" → "Sections A-L"
   (Section L added by PR #221 OSAP proxy invariant; internal match
   with the same row's Done-when col)

All else passes: 4 cited numbers, 18 agent names, 3 cross-refs, token
budget (WORKFLOW ≤ 1 page, CLAUDE ≤ 5 lines), Rule 16 + Rule 18 no
contradiction.

Pre-existing SKILL.md schema-version table gap (rows for 0.10.5-phase4.5e
PR #264 + valuation_output_anomalous rename PR #265 missing) escalated
to schema-sentinel as separate doc-only PR per docs-reviewer recommendation
— not blocking on this scope.

Verification:
- ruff check . — N/A (no Python)
- python -m compute.output.schema_check — N/A (no schemas)
- pytest tests/ -m "not network" — N/A (no test surface)
- docs-reviewer subagent — PASS after the 2 fixes above

Co-authored-by: Claude <noreply@anthropic.com>
dackclup pushed a commit that referenced this pull request May 28, 2026
Addresses 3 findings from docs-reviewer (sonnet) substance review of
the housekeeping PR (commit e060cb9):

1. PHASE_STATUS.md:98 — "v1.3.0 release tag" entry in §Next deliverables
   was stale (v1.3.0 shipped 2026-05-26, v1.4.0 shipped 2026-05-27).
   Replaced with forward-look for v1.5.0 gated on Phase 4.5e PR 5 +
   Issue #67 sector-CoE flip.

2. WORKFLOW.md:730 — Phase 4.5 historical task list trailing clause
   "v1.3.0 target pending release-captain ladder (LedgerCraft A-B
   series + this doc-refresh)" was stale. Replaced with the actual
   landing dates + SHAs for both v1.3.0 (5db3b97) and v1.4.0
   (bbca9ca).

3. docs/METHODOLOGY.md — annotate-only flag count out of sync with
   declared flags:
   - Line 16: "21 annotate-only flags" → "23 annotate-only flags"
   - Line 164: section heading "(21)" → "(23)"
   - Added 2 new bullets at end of §Annotate-only flags section:
     - `multi_class_aggregate_shares_suspected` (Issue #261 PR-A,
       PR #264) — CIK-collision detector; identity-equation check
       per Damodaran 2019 Ch. 16; no academic prior (data-quality)
     - `valuation_output_anomalous` (Issue #262, PR #265) — Site-2
       output-anomaly detector renamed from `data_quality_input_corruption`;
       no academic prior (data-quality); semantic distinction from
       Site-1 input-corruption veto documented inline

Both new METHODOLOGY entries are data-quality detectors with no new
academic claim — `multi_class_aggregate_shares_suspected` cites the
existing Damodaran 2019 anchor (already in the file) for the
per-class market-cap identity equation, and `valuation_output_anomalous`
is the renamed Site-2 emission of the existing `data_quality_input_corruption`
defense. Neither requires methodology-scientist verdict per the
"Internal — data-quality" pattern shared with `goodwill_heavy` /
`data_quality_input_corruption` Site-1 already in the section.
dackclup added a commit that referenced this pull request May 28, 2026
…v1.4.0 (#286)

* chore(docs): housekeeping PR-B — drain INFLIGHT + bump pointers post-v1.4.0

Phase B post-tag housekeeping. Drains 7 stale `(in flight, ...)` markers
from PHASE_STATUS_INFLIGHT.md (PRs #269, #267, #271, #280, #281, #282, #285)
to `(merged YYYY-MM-DD, <SHA>)`, and bumps stale schema/tag pointers
across CLAUDE.md / PHASE_STATUS.md / SKILL.md / WORKFLOW.md to reflect
the v1.4.0-phase4.6 release at `bbca9cac`.

Changes:
- CLAUDE.md §Phase status — schema `0.10.2-phase4.5e` → `0.10.7-phase4.6`,
  tag `v1.3.0-phase4.5e` → `v1.4.0-phase4.6` (2026-05-27, `bbca9cac`),
  "Recently merged" list refreshed from PRs #147-#154 → PRs #264-#285
- PHASE_STATUS.md §Current state — mirrored pointer bump; production-run
  pointer → `559c5269` (cron-#5 2026-05-27 chore commit); "Recently
  merged" prepended with 22 entries since v1.3.0, legacy list relabeled
  as "Earlier"
- SKILL.md schema-version table — 3 new rows: `0.10.7-phase4.6`
  (PR #283 release), `0.10.6-phase4.5e` (PR #269 GOOG/GOOGL per-class
  XBRL fix), `0.10.5-phase4.5e` (PR #264 multi-class CIK detector)
- WORKFLOW.md §Agentic 6-Phase Cadence Session-start protocol — pointer
  block bumped to current state
- PHASE_STATUS_INFLIGHT.md — 7 stale markers drained + new entry for
  this PR appended at end

AGENTS.md substance untouched per the existing delegation pattern
(line 372-375: "Canonical 'current state' lives in CLAUDE.md §Phase
status. Schema-version history table is in SKILL.md."). Cross-tool
agents reading state pull from CLAUDE.md as the source of truth.

Doc-only PR — `ruff` / `schema_check` trivially pass; no compute /
schema / scoring / valuation / frontend / Python / TS code change.

* docs(review-fix): docs-reviewer NEEDS-CROSS-REF-FIX — 3 items

Addresses 3 findings from docs-reviewer (sonnet) substance review of
the housekeeping PR (commit e060cb9):

1. PHASE_STATUS.md:98 — "v1.3.0 release tag" entry in §Next deliverables
   was stale (v1.3.0 shipped 2026-05-26, v1.4.0 shipped 2026-05-27).
   Replaced with forward-look for v1.5.0 gated on Phase 4.5e PR 5 +
   Issue #67 sector-CoE flip.

2. WORKFLOW.md:730 — Phase 4.5 historical task list trailing clause
   "v1.3.0 target pending release-captain ladder (LedgerCraft A-B
   series + this doc-refresh)" was stale. Replaced with the actual
   landing dates + SHAs for both v1.3.0 (5db3b97) and v1.4.0
   (bbca9ca).

3. docs/METHODOLOGY.md — annotate-only flag count out of sync with
   declared flags:
   - Line 16: "21 annotate-only flags" → "23 annotate-only flags"
   - Line 164: section heading "(21)" → "(23)"
   - Added 2 new bullets at end of §Annotate-only flags section:
     - `multi_class_aggregate_shares_suspected` (Issue #261 PR-A,
       PR #264) — CIK-collision detector; identity-equation check
       per Damodaran 2019 Ch. 16; no academic prior (data-quality)
     - `valuation_output_anomalous` (Issue #262, PR #265) — Site-2
       output-anomaly detector renamed from `data_quality_input_corruption`;
       no academic prior (data-quality); semantic distinction from
       Site-1 input-corruption veto documented inline

Both new METHODOLOGY entries are data-quality detectors with no new
academic claim — `multi_class_aggregate_shares_suspected` cites the
existing Damodaran 2019 anchor (already in the file) for the
per-class market-cap identity equation, and `valuation_output_anomalous`
is the renamed Site-2 emission of the existing `data_quality_input_corruption`
defense. Neither requires methodology-scientist verdict per the
"Internal — data-quality" pattern shared with `goodwill_heavy` /
`data_quality_input_corruption` Site-1 already in the section.

---------

Co-authored-by: Claude <noreply@anthropic.com>
dackclup added a commit that referenced this pull request May 28, 2026
…(NVR FP) (#293)

* fix(valuation): Issue #289 — retire Site-2 DQIC ceiling per Option C

Closes Issue #289 — NVR ($458 EPS, $6,098 price, ~2.7M shares) tripped
the $10,000 absolute-dollar Site-2 ceiling (`multiples_pe ≈ 22× × $458.86
≈ $10,094`) and got all 6 valuation methods nulled despite legitimate
inputs. `/stock/NVR` rendered empty fair-price section on cron #69.

Per methodology-scientist Mode B verdict 2026-05-28 = Option C
(LITERATURE-ANCHORED on Penman 2013 §7.4 + Damodaran 2019 Ch. 18 +
Huber 1981 §1.4):

- Site-2 was structurally redundant with Defense #4 (`extreme_*_estimate`)
  + Issue #177 `extreme_estimate_majority` (Huber breakdown layer)
- Site-1 input-level check in `risk_overlay.py` already catches the
  upstream units-bug class via TBVPS/revenue/NI patterns
- Cohort impact on cron #69: Option A ($50K) = 0 newly flagged;
  Option B (5× ratio) = 12 NEWLY NULLED tickers (regression);
  Option C = 0 newly missed
- PPV on cron #69 for Site-2: 0/1 = 0% (NVR was the only firing, FP)

Changes (5 files):

- compute/valuation/ensemble.py:450 — Site-2 trigger DELETED
  (`if _has_corrupt_input(methods): return _data_quality_corrupt_result`).
  `_has_corrupt_input` + `_data_quality_corrupt_result` retained below as
  dead code for one cycle per methodology verdict.

- compute/config.py:121-138 — `FAIR_PRICE_DATA_QUALITY_CEILING = 10000.0`
  KEPT ACTIVE. The constant is shared with Site-1
  (`risk_overlay.py:149` TBVPS > $10K input check); commenting it out
  would break the input-corruption veto. Docstring rewritten to confirm
  Site-1 active use + document Site-2 retirement.

- compute/main.py:1495-1499 — Writer-parity emit UNCHANGED. When
  `data_quality_input_corruption` veto fires in `risk_flags`,
  `valuation_output_anomalous` is still appended to `valuation_warnings`
  so the UI explanation chip persists for Site-1 cohort
  (MTB / CPT / MRNA / HBAN per PR #265).

- docs/METHODOLOGY.md — `valuation_output_anomalous` annotate description
  re-anchored: "Site-2 retired; emit remains via writer-parity from
  compute/main.py on Site-1 cohort". Cites Penman 2013 §7.4 + Damodaran
  2019 Ch. 18 + Huber 1981 §1.4 + 0/1 PPV empirical justification.

- tests/test_valuation/test_ensemble.py — 1 test rewritten as retirement
  guard (`test_site2_data_quality_guard_retired_post_issue_289`) +
  3 new Section L tests authored by test-engineer (NVR regression + dead
  code retention + constant preservation guards).

Impact (display-only):
- /stock/NVR now renders fair-price section with median of surviving methods
- NVR composite + rank UNCHANGED (composite = 50.99, rank #252)
- Rule 16 + Top-5 rotation UNAFFECTED
- Site-1 input veto unchanged (4 cohort tickers keep VETO + UI chip)
- Defense layer count unchanged at 33 declared

Verification:
- `ruff check .` — PASS
- `python -m pytest tests/test_valuation/test_ensemble.py -q -m "not network"` — 54 passed
- `python -m pytest tests/ -q -m "not network" --ignore=tests/test_validation` — 1203 passed

Deferred (NOT in this PR):
- Dead-code removal of `_has_corrupt_input` + `_data_quality_corrupt_result`
  after ≥ 1 cron of clean operation confirms no regression
- Site-1 input threshold recalibration — Q3 2026-08-19 cohort audit slot

Mid-PR correction: initial commenting-out of
`FAIR_PRICE_DATA_QUALITY_CEILING` was reverted after grep revealed Site-1
shares the constant. The retirement applies to the Site-2 trigger only,
not to the shared infrastructure constant.

* test(valuation): test-engineer follow-up edits to Section L tests

Post-PR-#293-push edits from `test-engineer` (sonnet) that landed after
the initial 4b5614e commit. Polishes the 3 new Section L Issue #289
retirement-guard tests:

- L1 NVR fair-price methods no longer nulled — synthetic NVR-shape
  fixture cleanup + assertion tightening
- L2 dead-code function-retention guard — confirm `_has_corrupt_input`
  + `_data_quality_corrupt_result` still callable post-Issue-#289
- L3 rewritten as `test_L3_site2_ceiling_not_invoked_when_method_value_exceeds_10k`
  — uses minimal synthetic methods dict (multiples_pe=$10,001 against
  current_price=$3,000 = 3.33× within Defense #4 5× band) so the
  retirement-guard doesn't depend on peer-panel infrastructure;
  confirms neither `extreme_multiples_pe_estimate` NOR
  `valuation_output_anomalous` appears in ensemble warnings post-fix

Net change: +59 / -46 lines on the same file; all 54 tests in
tests/test_valuation/test_ensemble.py pass post-fix. No production
code change.

---------

Co-authored-by: Claude <noreply@anthropic.com>
dackclup added a commit that referenced this pull request May 28, 2026
PR #293 (95e638b, merged 2026-05-28 05:20 UTC) retired the Site-2
output-level data-quality ceiling per methodology-scientist Mode B
Option C verdict (Penman 2013 §7.4 + Damodaran 2019 Ch. 18 + Huber
1981 §1.4). PR #293 deleted the call site at compute/valuation/
ensemble.py Step 4.5 but RETAINED the 2 helper functions as dead code
for "one cycle hold" — explicit retention guard pinned the deferred
state. This PR closes that contract.

Cron Run #71 (368dccd, 2026-05-28 08:44 UTC) confirmed clean
operation:

  - NVR fair-price section renders correctly (was empty pre-PR-#293)
  - valuation_output_anomalous cohort dropped 5 → 4 (NVR removed)
  - No regression on Site-1 veto cohort (MTB / CPT / MRNA / HBAN
    per PR #265 writer-parity emit still firing)

Scope (8 files, net −41 lines):

  - compute/valuation/ensemble.py — REMOVED 2 dead functions:
    - _has_corrupt_input(methods) -> bool (13 lines)
    - _data_quality_corrupt_result(methods) -> EnsembleResult (43 lines)
    Step 4.5 comment block at lines 449-479 refreshed: "kept as dead
    code for one cycle" → "removed in this PR after cron Run #71
    confirmed clean".

  - tests/test_valuation/test_ensemble.py — REMOVED 2 imports +
    3 active tests that exercised the removed functions:
    - test_data_quality_sanity_guard_triggers_on_extreme_method_value
    - test_data_quality_guard_boundary_exactly_at_ceiling
    - test_data_quality_guard_skipped_methods_dont_trigger
    The one-cycle retention guard test_L2_dead_code_functions_still_
    callable_after_site2_deletion REPLACED with new
    test_L2_dead_code_functions_removed_post_one_cycle that pins the
    removal via `not hasattr(_ensemble, "_has_corrupt_input")` +
    `not hasattr(_ensemble, "_data_quality_corrupt_result")` — so a
    future accidental re-introduction surfaces as a clear "Issue #289
    retirement reverted" failure. The 2 surviving tests
    (test_site2_data_quality_guard_retired_post_issue_289 +
    test_L3_site2_ceiling_not_invoked_for_high_share_price_ticker)
    keep verifying POST-RETIREMENT invariants on the NVR cohort.

  - compute/config.py:127-148 — FAIR_PRICE_DATA_QUALITY_CEILING
    STAYS ACTIVE (Site-1 in compute/scoring/risk_overlay.py shares
    the constant). Comment block updated to note "dead-code helpers
    REMOVED in the PR #293 follow-up after cron Run #71 confirmed
    clean".

  - compute/valuation/applicability.py:65-78 — reference to
    _data_quality_corrupt_result replaced with reference to the
    writer-parity emit at compute/main.py on the Site-1 veto cohort.

  - tests/test_scoring/test_risk_overlay.py:520-528 —
    test_D4_data_quality_corruption_fires_at_boundary_strict
    docstring updated: "Mirrors _has_corrupt_input's strict
    inequality" → "Site-1 (here) is the canonical input-corruption
    guard. Site-2 was retired per Issue #289 Option C; the strict `>`
    invariant lives ONLY here now." Test logic UNCHANGED.

  - CLAUDE.md §Phase status — drained "(in flight this PR — Issue
    #67 follow-up)" wording (PR #300 merged); added in-flight note
    for this PR's Site-2 dead-code removal.

  - AGENTS.md open-issues #289 entry — appended "dead-code helpers
    REMOVED in the PR #293 follow-up after cron Run #71 confirmed
    the retirement empirically".

  - PHASE_STATUS_INFLIGHT.md — full in-flight entry appended per
    PR #237 side-file convention.

Verification ladder:

  - ruff check .                          PASS
  - python -m compute.output.schema_check PASS (no schema touched)
  - python -m pytest tests/test_valuation/test_ensemble.py
    tests/test_scoring/test_risk_overlay.py tests/test_config.py -q
                                          120 PASS (was 123 — net -3
                                          as planned: 3 deleted tests
                                          + 1 modified L2 guard)
  - grep -rn "_has_corrupt_input|_data_quality_corrupt_result"
    compute/ tests/                       only legitimate references
                                          remain (retirement comments
                                          + new removal-guard
                                          assertion strings)

Hard constraints honored:

  - No scoring formula change · No Rule 16 / Top-5 violation
  - Schema version UNCHANGED at 0.10.10-phase4.6
  - Site-1 input-corruption veto path UNCHANGED
  - FAIR_PRICE_DATA_QUALITY_CEILING constant retained (Site-1 shared)
  - Writer-parity valuation_output_anomalous emit at compute/main.py
    UNCHANGED — UI explanation chip continues for Site-1 cohort
  - test_L3 PR #293 end-to-end guard UNCHANGED — keeps verifying NVR
    cohort produces non-null median

Closes the PR #293 retirement contract.

https://claude.ai/code/session_01AGU8d6pm4u2fQQ5cebg9qa

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DQIC dual-surface emission inconsistency: BRK-B/ERIE fire on both risk_flags + valuation_warnings; NVR fires only on valuation_warnings

2 participants