Skip to content

feat(factors): D0 paper contracts — availability policy constants + taxonomy pre-assignment + property ledger - #84

Merged
StackOverFlow11 merged 3 commits into
mainfrom
feat/factor-refactor-d0-contracts
Jul 23, 2026
Merged

feat(factors): D0 paper contracts — availability policy constants + taxonomy pre-assignment + property ledger#84
StackOverFlow11 merged 3 commits into
mainfrom
feat/factor-refactor-d0-contracts

Conversation

@StackOverFlow11

Copy link
Copy Markdown
Owner

First implementation step (D0) of the factor-layer deep refactor, per the v3.2 design (tmp/design/factor_refactor_design_v3.md, adversarially reviewed — 24 revisions R1–R25 folded in).

What (pure addition, +1148/−0, 3 new files)

  • data/availability_policy.py (399 lines) — single code-constant source for the §1.3 two-view availability table: field-level market_daily split (only open is SAME_DAY under the decision view — R7), three DOMAIN ASSUMPTION flags (R2), revision horizons derived from caller-passed config values with no hardcoded 14/400 and a loud raise when the fina override is missing (R5 — the silent-fallback shape found in current main), endpoint closure require_known_source (R8), view×basis pairing legality (§1.4), and the Adjustment/OvernightBoundary three-value enums (single source for D1 spec fields). Leaf module: stdlib-only imports, fully frozen, raise not assert.
  • tests/test_availability_policy.py (30 tests) — incl. mutation-style derivation tests (bump refresh_recent_days → horizon widens), a real drift guard against data/cache endpoint ids (independent import, not a copied string), per-case readable-error keyword assertions, frozen-ness via actual assignment attempts, and a bool-rejection test added from review with run mutation evidence (removing the guard clause reds it, rc=1).
  • docs/factors/refactor_d0_contract.md — taxonomy semantics (author-once: references constants, restates no numbers); pre-assignment table for the 14 closing-set factors with file:line evidence (9 RETURNS_INVARIANT / 5 NONE / 0 PRICE_LEVEL; valley_price_quantile = CROSSED_DISCLOSED, plus one flagged divergence: minute_ideal_amplitude pools 10 days of minute bars ranked by raw close → CROSSED_DISCLOSED candidate pending a PR-L-style bias measurement at D1, both resolution paths documented); two-directional property ledger (11 property classes ↔ 107 verified existing test references, four "out-of-catalog" test families listed honestly, NET-NEW properties stamped and pinned: adjustment→D3, overnight_boundary→D2, single-point-fill≡batch-fill→D4, view-isolation→D1/D3/D4).

Acceptance

  • Independent review (adversarial, per-item file:line): APPROVE-WITH-NITS — 0 CRIT/HIGH/MED, 1 LOW (bool guard untested) fixed in this PR with mutation evidence.
  • Gates re-run independently by the lead: pytest 1806 passed (baseline 1776 + 30 new, zero failures), ruff clean, validate-config 31/31, phase0 anchor ic 0.9600 / annual 0.8408 unchanged, secret scan on diff 0 hits (no token values, no .config.json).
  • No engine code (materializer/store/registry deliberately out of scope — D1+); no existing file touched; nothing imports the new module yet (revert = rollback, as designed for D0).

Test plan

  • Full suite green (1806)
  • New-file suite green (30) incl. raises-message keyword assertions
  • Mutation evidence run for the bool guard (mutated rc=1, restored rc=0)
  • phase0 anchor unchanged; 31/31 configs validate; ruff clean; secret scan 0

…ct (D0)

Single source of truth for the design v3.2 availability table (section 1.3):

- View / ReturnBasis enums (closed) + LEGAL_VIEW_BASIS_PAIRS +
  require_legal_pairing (only decision with exec_to_exec and close with
  close_to_close are legal; anything else raises readably).
- Adjustment / OvernightBoundary three-value taxonomy enums for the
  future FactorSpec fields (D1 imports them from here).
- Per-endpoint frozen AvailabilityRule rows; market_daily is declared
  per FIELD (R7: only 'open' is final by the 14:50 decision).
- DOMAIN ASSUMPTION flags on exactly the three declared assumptions
  (daily_basic evening publish / stk_limit pre-open / suspend+ST
  pre-open, the last covering two endpoints) - R2.
- require_known_source: R8 endpoint closure, readable error listing the
  declared endpoints (never a dict.get fallback).
- revision_horizon derives from caller-supplied cache config values
  (refresh_recent_days / recent_tail_overrides) - nothing hardcoded
  (R5); a missing fina_indicator override raises instead of silently
  falling back; the minute endpoint's 0 is semantic (write-once bars).

Leaf module: stdlib only, no qt/feed/cache imports. Tests are the
independent witness (expected sets hard-coded in the test file) and
include mutation-style derivation checks (widen refresh_recent_days and
the horizon widens) plus a drift guard against the cache layer ids.
…rty ledger)

docs/factors/refactor_d0_contract.md, three parts (design v3.2 D0 row):

(a) Taxonomy semantics for adjustment / overnight_boundary: the two axes
    govern different failure modes (cache staleness vs ex-date basis
    break), value domains are quoted from data/availability_policy.py
    (author-once, no restated tables), and each declared value carries
    its testability requirement, including the clarified reading of the
    overnight 'none' test as a uniform prior-basis rescale.

(b) Pre-assignment table for the closing 14-factor roster (11 minute
    factors + value_ep / value_bp / volatility_20) with file:line
    evidence read from the actual modules. One divergence from the
    design anchor is flagged: minute_ideal_amplitude ranks a 10-day
    pooled set by RAW minute close, which crosses the overnight basis
    like PR-L does, so it is pre-assigned crossed_disclosed pending the
    missing deviation measurement (PR-L-style) before D1 lands the spec
    field.

(c) Bidirectional property ledger for the 11 migration properties of
    design section 5: property-to-existing-test (every cited test name
    grep-verified on main @ 1f9d85e), existing-test-to-property with an
    out-of-ledger section (secret-hygiene guards, boundary-complement
    positive controls, alpha-layer walk-forward, data-layer ops), and a
    NET-NEW chapter pinning empty cells to their D gates: adjustment
    testability -> D3, overnight_boundary testability -> D2,
    single-point-fill == batch-fill -> D4, view-as-identity -> D1 (+D3
    key, +D4 pairing re-assertion). Closes with the mutation-evidence
    discipline reference.
bool is an int subclass; without the explicit guard True would coerce
to 1 and silently pass as a day count. Review (D0, LOW) found the guard
untested; mutation evidence: removing the guard clause reds this test.
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.

1 participant