feat(factors): D0 paper contracts — availability policy constants + taxonomy pre-assignment + property ledger - #84
Merged
Conversation
…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.
This was referenced Jul 23, 2026
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.
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-levelmarket_dailysplit (onlyopenis 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 currentmain), endpoint closurerequire_known_source(R8), view×basis pairing legality (§1.4), and theAdjustment/OvernightBoundarythree-value enums (single source for D1 spec fields). Leaf module: stdlib-only imports, fully frozen,raisenotassert.tests/test_availability_policy.py(30 tests) — incl. mutation-style derivation tests (bumprefresh_recent_days→ horizon widens), a real drift guard againstdata/cacheendpoint 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_amplitudepools 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
validate-config31/31, phase0 anchor ic 0.9600 / annual 0.8408 unchanged, secret scan on diff 0 hits (no token values, no.config.json).Test plan