Skip to content

feat(schema): Epic #150 Phase 2.1 — explicit valuation_methods_applicable field#161

Merged
dackclup merged 1 commit into
mainfrom
claude/session-close-audit-wrap-QkvFz
May 20, 2026
Merged

feat(schema): Epic #150 Phase 2.1 — explicit valuation_methods_applicable field#161
dackclup merged 1 commit into
mainfrom
claude/session-close-audit-wrap-QkvFz

Conversation

@dackclup
Copy link
Copy Markdown
Owner

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 the fair_price dict).

  • Schema bump 0.9.3-phase4h.30.9.4-phase4h.4
  • New helper: compute.valuation.ensemble._count_applicable_non_outliers
  • EnsembleResult dataclass gains valuation_methods_applicable: int = 0
  • compute_fair_price_ensemble computes it from extreme_*_estimate warnings via the new helper (zero recomputation cost — re-uses the already-emitted warning list)
  • ensemble_result_to_dict emits it (inside fair_price.valuation_methods_applicable)
  • compute/main.py writer passes it to StockDetail at top level
  • frontend/lib/types.ts mirrors in both FairPriceEnsemble (nested) and StockDetail (top level)
  • frontend/lib/schema-snapshot.json regenerated

Why

Per Phase 0 of epic #150 (Known Limitations): 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.

Scope: additive-only

This PR does NOT migrate the existing consumers:

  • compute/scoring/loss_chance.py still reads extreme_*_estimate flags for the per-flag penalty
  • frontend/components/FairPriceBarChart.tsx still uses extreme_*_estimate warnings for outlier-bar shading

Migrating those is a follow-up PR (Phase 2.1b). Keeping this PR additive avoids a breaking change to valuation_warnings semantics and preserves the 0.10.0 minor bump for the structural Phase 3 work.

Tests

7 new cases in tests/test_valuation/test_ensemble.py Section J:

  • J1 helper excludes outliers + skips
  • J2 all-skipped yields 0
  • J3 all-outliers yields 0
  • J4 EnsembleResult default is 0 (covers hard-stale + data-quality null paths)
  • J5 ensemble_result_to_dict emits the field
  • J6 full-ensemble integration on synthetic IT stock (3 methods compute, no outliers → 3)
  • J7 hard-stale short-circuit path (0)

Existing test_I1_ensemble_result_to_dict_shape_matches_ts_type updated for the new key. test_schema_version_is_phase4h_4 updated to match the bump.

Full offline suite: 945 passed, 7 skipped (ipca / qlib not installed), 18 deselected (network).

Test plan

  • ruff check . clean
  • python -m compute.output.schema_check in sync
  • python -m pytest tests/ -m "not network" — 945 passed (excluding 3 pre-existing collection errors from missing openassetpricing in this CI env)
  • cd frontend && npx --no -- tsc --noEmit — no new errors related to this PR
  • Section A-J + Section I Playwright spot-check on next workflow_dispatch green (post-merge)

Notes

https://claude.ai/code/session_01Nj5sMzisnqDmF46g5ckEJn


Generated by Claude Code

…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
@vercel
Copy link
Copy Markdown

vercel Bot commented May 20, 2026

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

Project Deployment Actions Updated (UTC)
quantrank Ready Ready Preview, Comment May 20, 2026 7:06pm

@dackclup dackclup marked this pull request as ready for review May 20, 2026 19:11
@dackclup dackclup merged commit a16c887 into main May 20, 2026
4 checks passed
@dackclup dackclup deleted the claude/session-close-audit-wrap-QkvFz branch May 20, 2026 19:12
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>
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>
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.

2 participants