Skip to content

feat(research): add immutable prediction dispatcher - #247

Merged
proerror77 merged 1 commit into
mainfrom
codex/prediction-research-dispatcher-242
Jul 23, 2026
Merged

feat(research): add immutable prediction dispatcher#247
proerror77 merged 1 commit into
mainfrom
codex/prediction-research-dispatcher-242

Conversation

@proerror77

@proerror77 proerror77 commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Parent: #240

Closes #242

Change contract

Add alpha-harness prediction dispatch render|submit so one authenticated, digest-bound prediction research submission deterministically renders and creates one immutable Secret plus one isolated Kubernetes Job, with fail-closed duplicate and create-outcome reconciliation.

Out of scope

Read-only status/evidence reporting (#246), collector or production deployment changes, snapshot construction, evaluator/MCTS behavior, promotion, and live execution.

Dependency or merge order

None. #246 may build on this after merge.

Focused validation

  • prediction_dispatch tests: 9 passed
  • alpha-harness full suite on rebased exact head: 89 passed
  • cargo clippy -p alpha-harness -- -D warnings
  • targeted rustfmt check and git diff --check
  • kubectl client dry-run accepted the rendered immutable Secret and Job
  • two independent read-only reviews: APPROVE

Rollout / rollback impact

No automatic rollout and no collector/runtime mutation. Operators must explicitly provide context and namespace to submit. Roll back by reverting this PR; Jobs already created remain independently auditable by immutable result identity.

Scope guardrail

4 files, 747 insertions and 2 deletions; below the 750 non-generated changed-line split threshold. Status remains isolated in #246.

Summary by CodeRabbit

  • New Features
    • Added commands to render prediction submissions as Kubernetes manifests and submit them to a cluster.
    • Added validation for submission metadata, secure URLs, pinned images, output bindings, and resume information.
    • Added duplicate-submission protection and recovery handling for interrupted submissions.
    • Added documentation covering private submission files, command usage, sensitive rendered data, and duplicate detection.
  • Tests
    • Added coverage for command parsing, manifest rendering, and invalid submission inputs.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds prediction dispatch render and submit commands for validating prediction submissions, rendering Kubernetes manifests, and creating immutable input Secrets and ACK Jobs with duplicate detection and failure reconciliation.

Changes

Prediction dispatch

Layer / File(s) Summary
Dispatch CLI wiring
rust_hft/alpha-harness/app/src/cli.rs, rust_hft/alpha-harness/app/src/main.rs
Adds render and submit subcommands, their arguments, command routing, module registration, and CLI parsing coverage.
Submission validation and manifest rendering
rust_hft/alpha-harness/app/src/prediction_dispatch.rs
Validates bounded submission JSON, digest-pinned images, HTTPS objects, identity bindings, resource profiles, and resume pairs, then renders an immutable Secret and configured ACK Job manifest.
Kubernetes submission and reconciliation
rust_hft/alpha-harness/app/src/prediction_dispatch.rs, deployment/aliyun/research/README.md
Checks duplicate result identities, submits the Secret and Job through kubectl, reconciles failed Job creation, cleans up input Secrets when needed, and documents the render/submit workflow and sensitive fields.

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

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant alpha-harness
  participant kubectl
  participant Kubernetes
  User->>alpha-harness: submit JSON with context and namespace
  alpha-harness->>kubectl: check result identity
  kubectl->>Kubernetes: list matching Jobs
  Kubernetes-->>kubectl: existing Job metadata
  alpha-harness->>kubectl: create Secret and ACK Job
  kubectl->>Kubernetes: submit manifest
  Kubernetes-->>alpha-harness: creation result
  alpha-harness-->>User: submission status
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed Clearly describes the main change: adding an immutable prediction dispatcher for research submissions.
Description check ✅ Passed All required sections are present and filled with relevant details, including scope, validation, rollout, and merge order.
Linked Issues check ✅ Passed Matches #242: render/submit dispatcher validates immutable mission inputs, rejects duplicates, and creates only the ACK Job plus short-lived Secret.
Out of Scope Changes check ✅ Passed Changes stay within the dispatcher and docs; no unrelated scheduler, deployment, collector, or live-trading work is introduced.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ 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/prediction-research-dispatcher-242

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.

@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: 1

🤖 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/app/src/prediction_dispatch.rs`:
- Around line 87-93: The prediction input Secret creation flow around
kubectl_with_input and ensure_kubectl_success must be retry-safe. Handle
AlreadyExists by reading the existing Secret and verifying it matches the
deterministically rendered, digest-bound submission identity; proceed only on an
exact match, and fail closed on any mismatch or read error, while preserving
normal creation behavior.
🪄 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 Plus

Run ID: eeda8866-9a14-401e-bd6d-dd5c9685e086

📥 Commits

Reviewing files that changed from the base of the PR and between 5d38626 and f148924.

📒 Files selected for processing (4)
  • deployment/aliyun/research/README.md
  • rust_hft/alpha-harness/app/src/cli.rs
  • rust_hft/alpha-harness/app/src/main.rs
  • rust_hft/alpha-harness/app/src/prediction_dispatch.rs

Comment on lines +87 to +93
let output = kubectl_with_input(
&args.context,
&args.namespace,
["create", "-f", "-"],
&secret_body,
)?;
ensure_kubectl_success(output, "create immutable prediction input Secret")?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Interrupted submit orphans the immutable input Secret and deadlocks retries.

The Secret is created (Line 87–93) before the Job, and ensure_result_available (Line 84) only inspects Jobs. If the process is killed between a successful Secret create and Job success, the immutable Secret is left behind with no Job. On retry the availability check passes (no Job), but kubectl create of the Secret then fails with AlreadyExists — and because it is immutable: true it cannot be replaced — leaving the operator stuck until they manually delete prediction-<label>-inputs.

Since the Secret content is deterministically derived from the (already validated, digest-bound) submission, consider making the Secret create idempotent: on AlreadyExists, read back the existing Secret and proceed only if it matches the rendered identity, otherwise fail closed. That keeps retries safe without a manual cleanup step.

🤖 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/app/src/prediction_dispatch.rs` around lines 87 - 93,
The prediction input Secret creation flow around kubectl_with_input and
ensure_kubectl_success must be retry-safe. Handle AlreadyExists by reading the
existing Secret and verifying it matches the deterministically rendered,
digest-bound submission identity; proceed only on an exact match, and fail
closed on any mismatch or read error, while preserving normal creation behavior.

@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: f14892429a

ℹ️ 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".

"spec": {
"backoffLimit": 0,
"activeDeadlineSeconds": ACTIVE_DEADLINE_SECONDS,
"ttlSecondsAfterFinished": 86400,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve duplicate identities beyond Job TTL

When the same result URL is submitted after 24 hours and the operator has followed the README's terminal-state Secret cleanup, the TTL controller has deleted the only Job record queried by existing_result_jobs, so the duplicate check passes and launches the experiment again. The immutable OSS PUT prevents overwriting only after the duplicate run has consumed its resources; retain the result identity in a non-expiring resource or do not expire the duplicate ledger.

AGENTS.md reference: AGENTS.md:L93-L96

Useful? React with 👍 / 👎.

Comment on lines +156 to +157
validate_identifier("mission id", &submission.mission_id)?;
validate_identifier("evaluator version", &submission.evaluator_version)?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Bind claimed identities to the fetched mission

When a submission's mission_id or evaluator_version differs from the authenticated mission, these syntax-only checks still accept it and neither expected value is passed to prediction execute. A valid mission can therefore complete while the Job annotations claim different identities from execution-evidence.json (and even a non-digest evaluator value such as foo is accepted), corrupting the immutable audit metadata; cross-check both fields after fetching the mission.

AGENTS.md reference: AGENTS.md:L50-L54

Useful? React with 👍 / 👎.

["create", "-f", "-"],
&secret_body,
)?;
ensure_kubectl_success(output, "create immutable prediction input Secret")?;

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 Reconcile ambiguous Secret creation

If the API server creates the Secret but kubectl reports an error because its response is lost or times out, this immediate return performs no readback. No Job is launched, and every retry passes the Job duplicate check but then fails because the deterministic Secret already exists, leaving the submission stuck until manual cleanup; reconcile an existing exact Secret just as the following Job-create path reconciles an ambiguous outcome.

AGENTS.md reference: AGENTS.md:L93-L96

Useful? React with 👍 / 👎.

},
"spec": {
"backoffLimit": 0,
"activeDeadlineSeconds": ACTIVE_DEADLINE_SECONDS,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Align the Job deadline with valid mission budgets

For a valid prediction mission whose search_budget.max_seconds exceeds 1,800 seconds—the runtime accepts values up to 86,400—the Job controller reaches this deadline and terminates the container before the governed loop can finish. Because that kills alpha-harness externally rather than letting it observe the runner's exit, it also bypasses the promised result/evidence upload; either reject missions outside this resource profile before launch or set a deadline that covers the accepted budget plus staging and publication time.

AGENTS.md reference: AGENTS.md:L93-L96

Useful? React with 👍 / 👎.

Comment on lines +165 to +167
let mission_object = canonical_https_object("mission", &submission.mission_url)?;
let snapshot_object = canonical_https_object("snapshot", &submission.snapshot_url)?;
let result_object = canonical_https_object("result", &submission.result_put_url)?;

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 result objects that alias an input object

When the query-free result object equals the mission, snapshot, or resume object, all URL checks pass even though the immutable PUT cannot succeed: the input object already exists, so x-oss-forbid-overwrite: true rejects publication after the run has consumed its resources. This is especially easy during resume because GET and PUT signatures for the same object have different queries; compare the canonical object identities and require the output to be distinct from every input.

AGENTS.md reference: AGENTS.md:L50-L54

Useful? React with 👍 / 👎.

Comment on lines +368 to +370
let (repository, digest) = image
.rsplit_once("@sha256:")
.context("prediction image must be pinned by @sha256 digest")?;

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 Validate the complete OCI image reference

When the repository portion is malformed, such as repo name@sha256:<64 hex> or repo@sha256:dead@sha256:<64 hex>, this split-and-digest check still accepts the submission because it only requires a nonempty prefix. Kubernetes can create the Job but the kubelet then reports an invalid image name and never starts the runner, while the Job reserves the result identity; parse and validate the complete OCI reference before creating cluster resources.

AGENTS.md reference: AGENTS.md:L50-L54

Useful? React with 👍 / 👎.

@proerror77
proerror77 merged commit b23e1cd into main Jul 23, 2026
38 checks passed
@proerror77
proerror77 deleted the codex/prediction-research-dispatcher-242 branch July 23, 2026 04:06
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.

Submit immutable prediction missions through the existing ACK Job contract

1 participant