Skip to content

fix(alpha): gate live-capable formula missions before persistence - #67

Merged
proerror77 merged 6 commits into
mainfrom
codex/alpha-live-capability-gate
Jul 17, 2026
Merged

fix(alpha): gate live-capable formula missions before persistence#67
proerror77 merged 6 commits into
mainfrom
codex/alpha-live-capability-gate

Conversation

@proerror77

@proerror77 proerror77 commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Change contract

A Formula that cannot be constructed with live runtime semantics is rejected before evaluation and candidate persistence. Governance revalidates prior walk-forward evidence, direct mission and durable-loop entrypoints reject impossible engines before state access, and live MCTS emits only formulas accepted by the shared capability gate.

Scope and atomic exception

This PR is 18 files and +1261/-255 after rebase. The capability definition, kernel persistence rule, evaluator and governance checks, MCTS checkpoint contract, and CLI/loop preflight are one security boundary. Splitting them would leave a bypassable transition.

Explicit merge authority: proerror77 instructed this Codex task to complete the reviewed and green PR merges on 2026-07-17.

Included safeguards

  • Rejected live-incompatible Formula candidates have crash evidence but no durable candidate or evaluation artifact.
  • Canonical Formula bundles use strict live validation; legacy bundles remain forensic-readback only.
  • MCTS live mode validates its seed fields, emits the restricted grammar, and rejects incompatible checkpoints.
  • Authenticated pre-v2 MCTS checkpoints cannot resume; the explicit recovery command forks a fresh mission and preserves source evidence.
  • Existing walk-forward candidates are revalidated before governed progression.

Focused validation

  • cargo test -p alpha-engine -p alpha-domain -p alpha-store -p alpha-harness -p hft-factor-dsl -p hft-strategy-formula -- --test-threads=1 (225 executed; one external LLM test ignored)
  • cargo clippy -p alpha-harness -p alpha-engine -p alpha-domain -p alpha-store --all-targets -- -D warnings
  • cargo fmt --check -p alpha-harness -p alpha-store
  • git diff --check

Dependency and merge order

Rebased on main after #75 (0b8ce2b). No remaining PR dependency.

Out of scope

  • Supplying trade_count in the raw OHLCV data contract. The current loader does not emit it, so a separate data-contract change must provide it before such a mission can pass dataset registration.
  • Historical Formula migration and live execution enablement.

Rollback

Revert this PR to restore the prior gate behavior. It introduces no live activation, order path, or deployment mutation.

Summary by CodeRabbit

  • New Features

    • Added live formula validation to ensure generated strategies use supported fields, operators, and event domains.
    • Research rows now include OHLCV values, bar returns, and return features.
    • MCTS supports live-only execution and improved checkpoint compatibility.
  • Bug Fixes

    • Unsupported engines and invalid formulas are rejected before execution or durable state is created.
    • Legacy checkpoints now report more specific recovery reasons.
  • Documentation

    • Updated mission and loop instructions, including required comma-separated feature fields and engine limitations.

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 72380eb8-eba5-4483-b117-d7f2f9f343e3

📥 Commits

Reviewing files that changed from the base of the PR and between 2daaf4d and 9bfbea8.

⛔ Files ignored due to path filters (1)
  • rust_hft/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (17)
  • rust_hft/alpha-harness/README.md
  • rust_hft/alpha-harness/app/Cargo.toml
  • rust_hft/alpha-harness/app/src/cli.rs
  • rust_hft/alpha-harness/app/src/data_mission.rs
  • rust_hft/alpha-harness/app/src/governance.rs
  • rust_hft/alpha-harness/app/src/loop_control.rs
  • rust_hft/alpha-harness/app/src/mission.rs
  • rust_hft/alpha-harness/app/src/mission_runner.rs
  • rust_hft/alpha-harness/domain/src/lib.rs
  • rust_hft/alpha-harness/engine/Cargo.toml
  • rust_hft/alpha-harness/engine/src/engines/mcts.rs
  • rust_hft/alpha-harness/engine/src/formula_evaluator.rs
  • rust_hft/alpha-harness/engine/src/lib.rs
  • rust_hft/alpha-harness/engine/src/llm.rs
  • rust_hft/alpha-harness/store/src/lib.rs
  • rust_hft/research-core/factor-dsl/src/lib.rs
  • rust_hft/strategy-framework/strategies/formula/src/lib.rs
🚧 Files skipped from review as they are similar to previous changes (11)
  • rust_hft/alpha-harness/app/src/data_mission.rs
  • rust_hft/alpha-harness/engine/Cargo.toml
  • rust_hft/alpha-harness/engine/src/llm.rs
  • rust_hft/alpha-harness/app/src/cli.rs
  • rust_hft/alpha-harness/app/src/mission_runner.rs
  • rust_hft/research-core/factor-dsl/src/lib.rs
  • rust_hft/alpha-harness/app/src/loop_control.rs
  • rust_hft/alpha-harness/engine/src/formula_evaluator.rs
  • rust_hft/strategy-framework/strategies/formula/src/lib.rs
  • rust_hft/alpha-harness/engine/src/lib.rs
  • rust_hft/alpha-harness/domain/src/lib.rs

📝 Walkthrough

Walkthrough

The PR introduces shared live-formula capability validation, applies it to strategies, governed artifacts, missions, and evaluation, requires explicit live feature fields, adds OHLCV-derived research features, restricts durable execution, and records structured live-capability failures.

Changes

Live Capability Enforcement

Layer / File(s) Summary
Shared live formula contract
rust_hft/research-core/factor-dsl/src/lib.rs
Defines live event domains, capability errors, supported fields/operators, constant checks, and AST validation.
Strategy and governed artifact validation
rust_hft/strategy-framework/strategies/formula/src/lib.rs, rust_hft/alpha-harness/domain/src/lib.rs, rust_hft/alpha-harness/app/src/governance.rs, rust_hft/alpha-harness/store/src/lib.rs
Routes formula strategy and governed artifact validation through the shared validator, separates runtime validation from readback validation, and rejects non-live governance candidates.
Mission and loop preflight
rust_hft/alpha-harness/app/src/cli.rs, rust_hft/alpha-harness/app/src/mission.rs, rust_hft/alpha-harness/app/src/loop_control.rs, rust_hft/alpha-harness/app/src/mission_runner.rs, rust_hft/alpha-harness/app/src/data_mission.rs
Requires explicit feature fields, validates live fields and event domains before durable state creation, restricts durable execution to MCTS, and adds OHLCV plus bar_return features.
Live MCTS checkpoints
rust_hft/alpha-harness/engine/src/engines/mcts.rs
Adds live-only MCTS construction, restricted expansion actions, versioned checkpoints, and live validation during checkpoint restoration.
Evaluation and search enforcement
rust_hft/alpha-harness/engine/src/lib.rs, rust_hft/alpha-harness/engine/src/formula_evaluator.rs, rust_hft/alpha-harness/engine/src/llm.rs, rust_hft/alpha-harness/engine/Cargo.toml
Rejects non-live formulas before evaluator calls, persists structured failure classes, and adds deterministic coverage across proposal engines and LLM-generated formulas.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant Mission
  participant LiveValidator
  participant AlphaStore
  participant AutoResearchKernel
  participant Evaluator
  CLI->>Mission: provide engine and feature_fields
  Mission->>LiveValidator: validate live mission and formula capabilities
  LiveValidator-->>Mission: capability result
  Mission->>AlphaStore: open state after successful preflight
  AutoResearchKernel->>LiveValidator: validate candidate formula
  LiveValidator-->>AutoResearchKernel: live or rejected
  AutoResearchKernel->>Evaluator: evaluate live-compatible candidate
Loading

Possibly related PRs

  • proerror77/monday#12: Updates governance formula handling and sealed evaluator version selection in related code paths.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 51.49% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: gating live-capable formula missions before persistence and execution.
Description check ✅ Passed The description covers the core contract, validation, dependencies, tests, out-of-scope work, and rollback, with only minor template naming gaps.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/alpha-live-capability-gate

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

}

fn temporary_db_path(name: &str) -> PathBuf {
std::env::temp_dir().join(format!(
@proerror77
proerror77 marked this pull request as ready for review July 16, 2026 10:41

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@rust_hft/alpha-harness/domain/src/lib.rs`:
- Around line 1655-1663: Move artifact validation into the
evaluation_protocol_hash branch: apply artifact.validate_for_readback() only
when processing legacy bundles with an empty protocol hash, while canonical
bundles use the canonical validation path without permissive formula readback.
Preserve the existing hash validation and calculation behavior in both branches.

In `@rust_hft/alpha-harness/engine/src/lib.rs`:
- Around line 379-390: Update the live formula validation gate before evaluator
invocation to call the AST’s structural validate method first, then run
validate_live_formula only when that succeeds. Apply this to
CandidateArtifact::Formula in the proposal evaluation flow, preserving the
existing live_capability rejection and error mapping so malformed ASTs cannot
reach the evaluator.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fe63e78b-4f91-477a-9fef-dc151a3482cc

📥 Commits

Reviewing files that changed from the base of the PR and between 513207c and 2daaf4d.

⛔ Files ignored due to path filters (1)
  • rust_hft/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (15)
  • rust_hft/alpha-harness/app/Cargo.toml
  • rust_hft/alpha-harness/app/src/cli.rs
  • rust_hft/alpha-harness/app/src/data_mission.rs
  • rust_hft/alpha-harness/app/src/governance.rs
  • rust_hft/alpha-harness/app/src/loop_control.rs
  • rust_hft/alpha-harness/app/src/mission.rs
  • rust_hft/alpha-harness/app/src/mission_runner.rs
  • rust_hft/alpha-harness/domain/src/lib.rs
  • rust_hft/alpha-harness/engine/Cargo.toml
  • rust_hft/alpha-harness/engine/src/formula_evaluator.rs
  • rust_hft/alpha-harness/engine/src/lib.rs
  • rust_hft/alpha-harness/engine/src/llm.rs
  • rust_hft/alpha-harness/store/src/lib.rs
  • rust_hft/research-core/factor-dsl/src/lib.rs
  • rust_hft/strategy-framework/strategies/formula/src/lib.rs

Comment thread rust_hft/alpha-harness/domain/src/lib.rs Outdated
Comment on lines +379 to +390
let live_capability = match &proposal.artifact {
CandidateArtifact::Formula(ast) => validate_live_formula(ast)
.map(|_| ())
.map_err(|error| error.to_string()),
_ => Ok(()),
};
match live_capability {
Err(error) => Err(("live_capability_reject", error)),
Ok(()) => self
.evaluator
.evaluate(&proposal, &evaluation_context)
.map_err(|error| ("evaluation_error", error))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Validate the AST structure before invoking any evaluator.

This generic gate calls only validate_live_formula, while formula_evaluator.rs explicitly calls ast.validate() first. A malformed supported-node AST from deserialization/direct construction could reach a permissive evaluator and be persisted as Keep.

Proposed fix
 CandidateArtifact::Formula(ast) => validate_live_formula(ast)
-    .map(|_| ())
-    .map_err(|error| error.to_string()),
+    .and_then(|_| ast.validate().map_err(Into::into))
+    .map_err(|error| error.to_string()),

Prefer structural validation first if deterministic error precedence matters.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let live_capability = match &proposal.artifact {
CandidateArtifact::Formula(ast) => validate_live_formula(ast)
.map(|_| ())
.map_err(|error| error.to_string()),
_ => Ok(()),
};
match live_capability {
Err(error) => Err(("live_capability_reject", error)),
Ok(()) => self
.evaluator
.evaluate(&proposal, &evaluation_context)
.map_err(|error| ("evaluation_error", error))
let live_capability = match &proposal.artifact {
CandidateArtifact::Formula(ast) => validate_live_formula(ast)
.and_then(|_| ast.validate().map_err(Into::into))
.map_err(|error| error.to_string()),
_ => Ok(()),
};
match live_capability {
Err(error) => Err(("live_capability_reject", error)),
Ok(()) => self
.evaluator
.evaluate(&proposal, &evaluation_context)
.map_err(|error| ("evaluation_error", error))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@rust_hft/alpha-harness/engine/src/lib.rs` around lines 379 - 390, Update the
live formula validation gate before evaluator invocation to call the AST’s
structural validate method first, then run validate_live_formula only when that
succeeds. Apply this to CandidateArtifact::Formula in the proposal evaluation
flow, preserving the existing live_capability rejection and error mapping so
malformed ASTs cannot reach the evaluator.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2daaf4dbdf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


fn validate_loop_args(args: &LoopRunArgs) -> anyhow::Result<()> {
mission::validate_live_mission_args(&args.mission)?;
if !matches!(args.mission.engine, EngineChoice::Mcts) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use a live-only MCTS grammar for loops

When LoopRun accepts Mcts as the only live-capable durable engine here, the MCTS grammar still expands actions 0-2 to rank, delta, and mean in engine/src/engines/mcts.rs, all of which the new live gate rejects. With the CLI default seed 7, the first root expansion selects mean, so a one-candidate loop records only live_capability_reject and exhausts research without any evaluation. Please route loop MCTS through a live-only grammar or reject configurations that can propose research-only operators.

Useful? React with 👍 / 👎.

Comment on lines +201 to +205
pub(crate) fn validate_live_formula_engine(engine: EngineChoice) -> anyhow::Result<()> {
if matches!(engine, EngineChoice::Bayesian) {
bail!(BAYESIAN_WINDOW_SEARCH_LIVE_CAPABILITY_ERROR);
}
Ok(())

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject OfflineRL before it burns candidate budget

Only Bayesian is rejected in this live preflight, but OfflineRlEngine::ast_for_action can only emit rank, delta, mean, or zscore, and the new validate_live_formula path rejects all of those before evaluation. A standalone mission run --engine offline-rl with otherwise valid live feature fields therefore opens/updates the store and consumes candidates as live_capability_reject with no possible successful evaluation; either fail fast here or give OfflineRL a live-capable action set.

Useful? React with 👍 / 👎.

match &proposal.artifact {
CandidateArtifact::Formula(ast) => {
ast.validate().map_err(|error| error.to_string())?;
validate_live_formula(ast).map_err(|error| error.to_string())?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Bump the formula evaluator version

When this line starts rejecting formulas that purged-walk-forward-v3 used to evaluate before (for example signal, rank, or mean) while the evaluator version string stays at v3, existing persisted v3 walk-forward records are still accepted by governance::validated_walk_forward_evidence_in_lineage without revalidating the candidate. That can mark a research-only legacy candidate as WalkForwardKept even though a fresh evaluation now fails; please bump the formula evaluator version or filter stored candidates through the live contract before accepting v3 evidence.

Useful? React with 👍 / 👎.

Ok(result)
})
let live_capability = match &proposal.artifact {
CandidateArtifact::Formula(ast) => validate_live_formula(ast)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Constrain LLM proposals to live operators

When a standalone mission run --engine llm is used, this new live-capability check rejects any formula the LLM returns with rank, delta, mean, or zscore. The LLM response schema in engine/src/llm.rs still explicitly allows those operators, and abandon does not add these crashes to prior outcomes, so such responses consume candidate/token budget and may be repeated instead of evaluated. Please narrow the LLM schema to live operators before enabling it under this gate.

Useful? React with 👍 / 👎.

@proerror77
proerror77 marked this pull request as draft July 16, 2026 12:43
@proerror77
proerror77 force-pushed the codex/alpha-live-capability-gate branch from 2daaf4d to eb91748 Compare July 16, 2026 17:42
@proerror77
proerror77 marked this pull request as ready for review July 16, 2026 23:20

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: eb91748e69

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +444 to +445
let persist_candidate =
is_novel && failure_class != "live_capability_reject";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Record live rejects in replay state for GP resumes

When standalone GP is run in small resume slices (for example --max-new-iterations 1) and its deterministic sequence hits a research-only operator such as delta or mean, this branch records only a crash iteration and no candidate/evaluation. The default history-replay checkpoint then has no observation to restore, so the next resume starts GP from the same seed and can regenerate the same rejected formula, spending candidate budget repeatedly on an already-rejected proposal; persist enough rejected-fingerprint state or make GP abandon/restore live rejects.

Useful? React with 👍 / 👎.

Comment on lines +195 to +196
"best_bid" | "best_ask" | "mid_price" | "spread" | "spread_bps" | "bid_size"
| "ask_size" | "book_imbalance" => LiveEventDomain::Snapshot,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Align live fields with the LOB materializer

The governed LOB materializer emits depth-qualified fields such as book_imbalance_top5, bid_depth_top5, and ofi_top5, but the live whitelist here only accepts the unqualified book_imbalance/size names. Any mission execute using the materializer's default imbalance or order-flow fields is now rejected by validate_live_feature_fields before state is created, leaving only mid_price/spread_bps from that artifact usable; either emit the whitelisted names or accept/runtime-map the materializer's live equivalents.

Useful? React with 👍 / 👎.

@proerror77
proerror77 force-pushed the codex/alpha-live-capability-gate branch from eb91748 to 9bfbea8 Compare July 17, 2026 00:08
@proerror77
proerror77 merged commit 4337503 into main Jul 17, 2026
35 checks passed
@proerror77
proerror77 deleted the codex/alpha-live-capability-gate branch July 17, 2026 00:38
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