feat(schema): Epic #150 Phase 2.1 — explicit valuation_methods_applicable field#161
Merged
Merged
Conversation
…able field Surfaces the positive-framed count of valuation methods that produced a non-outlier applicable estimate as `StockDetail.valuation_methods_applicable` (top-level + mirrored inside `fair_price` dict). The field is the inverse of the count of `extreme_*_estimate` warnings emitted by `compute.valuation.ensemble._classify_outliers`. Why: per Phase 0 of epic #150, the `extreme_*_estimate` warnings are method-applicability signals, NOT manipulation signals. Today consumers have to count those warnings to derive the applicable-method count; this PR exposes the count directly at the schema-snapshot level so filtering / audits / future UI can read it without unpacking the warning list. Additive only: `extreme_*_estimate` flags stay in `valuation_warnings` for back-compat with `loss_chance.py` (penalty input) and `FairPriceBarChart.tsx` (UI outlier shading). A future PR can migrate those consumers to read the new field; that's out of scope here. Schema bump 0.9.3-phase4h.3 → 0.9.4-phase4h.4. The 0.10.0 minor bump is preserved for the structural Phase 3 work (pillar correlation + top-decile veto → joint-gate). Tests: 7 new cases in `tests/test_valuation/test_ensemble.py` Section J covering helper unit + dict round-trip + integration via full ensemble path + hard-stale default. Existing `to_dict_shape` test updated for the new key. https://claude.ai/code/session_01Nj5sMzisnqDmF46g5ckEJn
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
5 tasks
dackclup
added a commit
that referenced
this pull request
May 21, 2026
…#164) Adds the Phase 3 correlation analysis: a reproducible one-shot script (`scripts/phase3_flag_correlation.py`) plus baseline outputs under `docs/phase3-correlation/` containing firing rates, pairwise φ-coefficients, redundancy candidates, diversity-confirmed pairs, a heatmap PNG, and an interpretive findings doc. Methodology: - φ-coefficient (Matthews correlation for boolean variables) — the proper analog of Pearson for the {0,1} case. - Sources merged: `risk_flags` + `valuation_warnings` + boolean keys in `tier2_events`. - Universe: 502 S&P 500 constituents (production output @5dfe6287, pre-Phase-2.4 so `loss_avoidance_pattern` is still 0% — re-run after the next weekly cron to include it). Headline findings (full version in `findings.md`): - Defense layer is mostly orthogonal — 35 diversity-confirmed pairs (|φ| ≤ 0.05, both base-rates ≥ 5%) vs 15 redundancy candidates (|φ| ≥ 0.30). `altman_distress` is orthogonal to nearly every other flag — its financial-distress signal is genuinely distinct. - `restatement_history` is independent of the Sloan/Beneish/accruals manipulation cluster (φ ≈ 0). Phase 2.2 recalibration can proceed without redundancy concerns. - Warning-band ↔ active-veto pairs (Dechow + Beneish) are correlated by design (φ ≈ +0.6-0.7) — confirms the half-PPV Phase 2.5 calibration of `BENEISH_HIGH_WEIGHT` and `DECHOW_HIGH_WEIGHT`. - `manipulation_triple_flag` is φ-locked to `dechow_high` at current sample size (n=2 each). Watch in Q3 cohort audit — if persistent, downgrade `TRIPLE_FLAG_WEIGHT = 10.0` (currently labeled gut-feel in Phase 2.5 provenance docstring). - `extreme_*_estimate` family clusters (φ ≈ +0.4-0.5) — already surfaced positively as `valuation_methods_applicable` (PR #161). No additional work needed. Decision matrix for downstream Phase 2.x PRs in `findings.md`. Doc + script only — no compute / schema / output change. Re-run after every quarterly cohort audit (next: 2026-08-19) + after each Phase 2.x recalibration PR lands. Closes the Phase 3 deliverable in epic #150. https://claude.ai/code/session_01Nj5sMzisnqDmF46g5ckEJn Co-authored-by: Claude <noreply@anthropic.com>
This was referenced May 21, 2026
dackclup
pushed a commit
that referenced
this pull request
May 21, 2026
Second deliverable from the 14-subagent full self-audit (2026-05-21).
Doc drift surfaced by `docs-reviewer` + `methodology-scientist` against
the actual production state on `a16c887` (2026-05-20 cron) + the schema
version on `compute/config.py:30`.
Five reconciles in lockstep:
(a) PHASE_STATUS.md §Current state — schema `0.9.2-phase4h.2` →
`0.9.4-phase4h.4`; defense layer headline 17 declared → 27 emitted
flags (per PR #154 reconcile); skill inventory 38 → 42; subagent
inventory added (14 in 4 tiers); active-vetoes list explicit
(7 named); recently-merged block refreshed from PR #146-back to
PRs #148-#169 (~20 PRs since `v1.2.0-phase4.5`); next-deliverables
list updated to drop the PR-#148-closed Epic #125 Item 3 entry
and add the `loss_avoidance_pattern` size-invariant follow-up.
(b) SKILL.md schema-version table — 2 missing rows added:
`0.9.3-phase4h.3` (PR #160, explicit `Metadata.tier2_enabled` field,
closes #117/#155) and `0.9.4-phase4h.4` (PR #161, additive
`valuation_methods_applicable` field on `StockDetail` and nested
in `fair_price` dict, additive only — no consumer migration).
(c) WORKFLOW.md Phase 4.5d `loss_avoidance_pattern` task — threshold
description `$5M / $0.05` → `$50M / $0.50` (PR #163 Phase 2.4
10× rescale). Adds the Phase 4 size-invariant follow-up note
(NI / TotalAssets) carried from CLAUDE.md §Gotchas since the
rescale still fires 0% on production.
(d) docs/METHODOLOGY.md — Active vetoes 4 → 7 rows: adds
`beneish_manipulation_veto` (Beneish 1999 *FAJ*),
`dechow_manipulation_veto` (Dechow 2011 *CAR* Model 1), and
`data_quality_input_corruption` (with the dual-path rule —
`risk_overlay.py` snapshot-level TBVPS guard + `ensemble.py`
output-level guard). Known-calibration-drift block refreshed:
`value_trap_risk` (Issue #11 closed via PR #166),
`going_concern_disclosure` (FP rate now 1.0% within Mayew band —
verified 5/502 on production cron),
`loss_avoidance_pattern` (still 0% after Phase 2.4 rescale,
follow-up to size-invariant), `restatement_history` (Phase 2.2
high-confidence complement via PR #165).
(e) README.md §Honest Limitations — adds Phase 2.2
`restatement_high_confidence` and Issue #11 closure (PR #166)
entries; mentions PR #163's 10× rescale on the
`loss_avoidance_pattern` line.
CLAUDE.md §Phase status + AGENTS.md §Phase + version state — matching
"Phase 2 in flight" entries per §Conventions "ship with every PR" rule.
Deferred to a follow-up Phase 2.x PR (too large for this scope):
METHODOLOGY.md annotate-only section full refresh (7 → 14+ flags) +
missing citation blocks (full Hennes-Leone-Miller 2008 *TAR*,
Cohen-Malloy-Pomorski 2012, etc.) — needs `methodology-scientist`
sign-off per the new-defense-flow rule.
Pre-commit verification:
- docs-reviewer NEEDS-CLARITY-PASS → fixed `data_quality_input_corruption`
rule description in METHODOLOGY.md to cover both veto paths
(snapshot-level `risk_overlay.py` + output-level `ensemble.py`).
- methodology-scientist findings: data_quality veto classification
CONFIRMED via dual-surface emission; value_trap / loss_avoidance /
restatement_history all CLEAN.
- phase-coordinator Mode A: COLLISION-RISK with PR #170 (Phase 1
ops hardening on `claude/enable-subagents-standby-7lMN4`) on
CLAUDE.md + AGENTS.md §Phase status block — both PRs append to
the tail. Strategy: PR #170 merges first, then this branch rebases
onto updated main; conflict is mechanical 2-paragraph merge.
No compute / schema / output / dep change. Lint passes (no Python /
TypeScript edited).
https://claude.ai/code/session_01HtcGy4F59TaawNQ7V1Eysc
Co-authored-by: Claude <noreply@anthropic.com>
dackclup
added a commit
that referenced
this pull request
May 21, 2026
…ion (#171) Second deliverable from the 14-subagent full self-audit (2026-05-21). Doc drift surfaced by `docs-reviewer` + `methodology-scientist` against the actual production state on `a16c887` (2026-05-20 cron) + the schema version on `compute/config.py:30`. Five reconciles in lockstep: (a) PHASE_STATUS.md §Current state — schema `0.9.2-phase4h.2` → `0.9.4-phase4h.4`; defense layer headline 17 declared → 27 emitted flags (per PR #154 reconcile); skill inventory 38 → 42; subagent inventory added (14 in 4 tiers); active-vetoes list explicit (7 named); recently-merged block refreshed from PR #146-back to PRs #148-#169 (~20 PRs since `v1.2.0-phase4.5`); next-deliverables list updated to drop the PR-#148-closed Epic #125 Item 3 entry and add the `loss_avoidance_pattern` size-invariant follow-up. (b) SKILL.md schema-version table — 2 missing rows added: `0.9.3-phase4h.3` (PR #160, explicit `Metadata.tier2_enabled` field, closes #117/#155) and `0.9.4-phase4h.4` (PR #161, additive `valuation_methods_applicable` field on `StockDetail` and nested in `fair_price` dict, additive only — no consumer migration). (c) WORKFLOW.md Phase 4.5d `loss_avoidance_pattern` task — threshold description `$5M / $0.05` → `$50M / $0.50` (PR #163 Phase 2.4 10× rescale). Adds the Phase 4 size-invariant follow-up note (NI / TotalAssets) carried from CLAUDE.md §Gotchas since the rescale still fires 0% on production. (d) docs/METHODOLOGY.md — Active vetoes 4 → 7 rows: adds `beneish_manipulation_veto` (Beneish 1999 *FAJ*), `dechow_manipulation_veto` (Dechow 2011 *CAR* Model 1), and `data_quality_input_corruption` (with the dual-path rule — `risk_overlay.py` snapshot-level TBVPS guard + `ensemble.py` output-level guard). Known-calibration-drift block refreshed: `value_trap_risk` (Issue #11 closed via PR #166), `going_concern_disclosure` (FP rate now 1.0% within Mayew band — verified 5/502 on production cron), `loss_avoidance_pattern` (still 0% after Phase 2.4 rescale, follow-up to size-invariant), `restatement_history` (Phase 2.2 high-confidence complement via PR #165). (e) README.md §Honest Limitations — adds Phase 2.2 `restatement_high_confidence` and Issue #11 closure (PR #166) entries; mentions PR #163's 10× rescale on the `loss_avoidance_pattern` line. CLAUDE.md §Phase status + AGENTS.md §Phase + version state — matching "Phase 2 in flight" entries per §Conventions "ship with every PR" rule. Deferred to a follow-up Phase 2.x PR (too large for this scope): METHODOLOGY.md annotate-only section full refresh (7 → 14+ flags) + missing citation blocks (full Hennes-Leone-Miller 2008 *TAR*, Cohen-Malloy-Pomorski 2012, etc.) — needs `methodology-scientist` sign-off per the new-defense-flow rule. Pre-commit verification: - docs-reviewer NEEDS-CLARITY-PASS → fixed `data_quality_input_corruption` rule description in METHODOLOGY.md to cover both veto paths (snapshot-level `risk_overlay.py` + output-level `ensemble.py`). - methodology-scientist findings: data_quality veto classification CONFIRMED via dual-surface emission; value_trap / loss_avoidance / restatement_history all CLEAN. - phase-coordinator Mode A: COLLISION-RISK with PR #170 (Phase 1 ops hardening on `claude/enable-subagents-standby-7lMN4`) on CLAUDE.md + AGENTS.md §Phase status block — both PRs append to the tail. Strategy: PR #170 merges first, then this branch rebases onto updated main; conflict is mechanical 2-paragraph merge. No compute / schema / output / dep change. Lint passes (no Python / TypeScript edited). https://claude.ai/code/session_01HtcGy4F59TaawNQ7V1Eysc Co-authored-by: Claude <noreply@anthropic.com>
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
Epic #150 Phase 2.1 — surfaces the positive-framed count of valuation methods that produced a non-outlier applicable estimate as
StockDetail.valuation_methods_applicable(top-level + mirrored inside thefair_pricedict).0.9.3-phase4h.3→0.9.4-phase4h.4compute.valuation.ensemble._count_applicable_non_outliersEnsembleResultdataclass gainsvaluation_methods_applicable: int = 0compute_fair_price_ensemblecomputes it fromextreme_*_estimatewarnings via the new helper (zero recomputation cost — re-uses the already-emitted warning list)ensemble_result_to_dictemits it (insidefair_price.valuation_methods_applicable)compute/main.pywriter passes it toStockDetailat top levelfrontend/lib/types.tsmirrors in bothFairPriceEnsemble(nested) andStockDetail(top level)frontend/lib/schema-snapshot.jsonregeneratedWhy
Per Phase 0 of epic #150 (Known Limitations):
extreme_*_estimatewarnings are method-applicability signals, not manipulation signals. Today consumers have to count those warnings to derive the applicable-method count. This PR exposes the count directly at the schema-snapshot level so filtering / audits / future UI can read it without unpacking the warning list.Scope: additive-only
This PR does NOT migrate the existing consumers:
compute/scoring/loss_chance.pystill readsextreme_*_estimateflags for the per-flag penaltyfrontend/components/FairPriceBarChart.tsxstill usesextreme_*_estimatewarnings for outlier-bar shadingMigrating those is a follow-up PR (Phase 2.1b). Keeping this PR additive avoids a breaking change to
valuation_warningssemantics and preserves the 0.10.0 minor bump for the structural Phase 3 work.Tests
7 new cases in
tests/test_valuation/test_ensemble.pySection J:J1helper excludes outliers + skipsJ2all-skipped yields 0J3all-outliers yields 0J4EnsembleResultdefault is 0 (covers hard-stale + data-quality null paths)J5ensemble_result_to_dictemits the fieldJ6full-ensemble integration on synthetic IT stock (3 methods compute, no outliers → 3)J7hard-stale short-circuit path (0)Existing
test_I1_ensemble_result_to_dict_shape_matches_ts_typeupdated for the new key.test_schema_version_is_phase4h_4updated to match the bump.Full offline suite: 945 passed, 7 skipped (ipca / qlib not installed), 18 deselected (network).
Test plan
ruff check .cleanpython -m compute.output.schema_checkin syncpython -m pytest tests/ -m "not network"— 945 passed (excluding 3 pre-existing collection errors from missingopenassetpricingin this CI env)cd frontend && npx --no -- tsc --noEmit— no new errors related to this PRworkflow_dispatchgreen (post-merge)Notes
int | Noneon the Pydantic / TS side so legacy snapshots cast cleanly; the writer always emits a non-null int from 0.9.4+https://claude.ai/code/session_01Nj5sMzisnqDmF46g5ckEJn
Generated by Claude Code