feat(proof): InferenceOffer as RLM judge backend (no HF proxy) - #223
Conversation
|
@greptileai review |
Greptile SummaryThis update replaces the retired miner training-proxy interpretation with a live RLM judge offer, keeps judge availability fail-closed, and removes miner-side offer binding. The change is not safe to merge while the outstanding correctness issues prevent reliable scoring. Confidence Score: 2/5Not merge-safe: three outstanding blocking correctness issues can cause scoring to be advertised or attempted with an unusable judge configuration. Three previous P1 findings remain outstanding. The configured provider key is checked for presence but is not passed to the evaluation pod, so an authenticated judge can appear available before its provider call fails. Status readiness now checks that an open topic resolves to a complete inference configuration, but it still does not require that the active offer serves that topic; token, mode, model, provider, or required-commitment incompatibility can therefore leave Reviews (2): Last reviewed commit: "fix(proof): rename topic judge commitmen..." | Re-trigger Greptile |
| if let Some(p) = cli.inference_api_key_file.as_deref() { | ||
| match std::fs::read_to_string(p) { | ||
| Ok(s) if !s.trim().is_empty() => { | ||
| tracing::info!("inference api key file present (contents not logged)"); | ||
| } | ||
| _ => tracing::warn!( | ||
| "PROOF_INFERENCE_API_KEY_FILE set but unreadable; eval image auth will fail closed" | ||
| ), | ||
| } | ||
| } |
There was a problem hiding this comment.
If the configured provider requires authentication, PROOF_INFERENCE_API_KEY_FILE is read only to confirm that it is non-empty, and its contents are then discarded. The harvest path launches the eval pod with an empty environment payload, so the host can report can_score=true and rent a pod even though the provider request will fail with 401/403. Pass the key through the pod's secret environment channel and include credential availability in readiness.
Knowledge Base Used:
| fn can_score(&self) -> bool { | ||
| let open = self.store.any_open_scorable(self.epoch).unwrap_or(false); | ||
| scoring_readiness(&self.pin, self.backend, self.live(), open).is_ok() | ||
| scoring_readiness( | ||
| &self.pin, | ||
| self.backend, | ||
| self.live(), | ||
| open, | ||
| self.offer.as_ref(), | ||
| ) | ||
| .is_ok() |
There was a problem hiding this comment.
Readiness ignores compatibility
/v1/status can return can_score: true when the only open, baseline-sealed topic exceeds the active offer's limits. Submissions for that topic are then rejected with 503 because submit does check offer.serves_topic. Make readiness require at least one open scorable topic that the active offer can serve, so clients are not told scoring is available when every submission will fail.
Artifacts
- Runs the authored Axum endpoint-contract test once against the candidate and once in an isolated worktree with the minimal readiness correction, showing the mismatch and expected behavior.
Incompatible-offer endpoint output
- Captured cargo test output for the candidate: GET /v1/status is HTTP 200 with can_score true while POST /v1/submissions is HTTP 503 for offer/topic incompatibility, confirming the defect.
Corrected readiness endpoint output
- Captured cargo test output after a temporary isolated-worktree readiness correction: GET /v1/status is HTTP 200 with can_score false and the incompatible submission remains HTTP 503, showing the expected contract.
| /// Input token cap for this run (min of offer and topic). | ||
| pub max_input_tokens: u32, | ||
| /// Output token cap for this run. | ||
| pub max_output_tokens: u32, | ||
| /// Offer config commitment. | ||
| pub config_commitment: String, |
There was a problem hiding this comment.
Committed settings are omitted
temperature, top_p, and timeout_ms are included in the configuration commitment miners bind to, but HarvestRequest sends only the token caps and commitment hash. The hash cannot recover those values, so an offer that sets them does not provide the eval image with the committed configuration. Transmit these settings so the scored inference matches the advertised offer.
|
Mathis correction (do not weaken fail-closed): The live master
Title/docs/API comments rewritten to match. @greptileai review |
|
Architect lock is pushed on this PR (
Title remains |
Replace the HF proxy_model architecture lock with pin ceilings plus an operator-state InferenceOffer. Miners bind offer_id/config_commitment; missing or closed offers fail closed (can_score false, 503). Co-authored-by: Mathis <echobt@users.noreply.github.com>
Drop miner bind to the live offer. The offer is the RLM eval judge the digest-pinned image calls; miners still submit claim + code + FLOPs + artifact. Missing/closed/incomplete judge stays 503. Co-authored-by: Mathis <echobt@users.noreply.github.com>
Topic optional pin is require_judge_offer_commitment, not a miner bind. Co-authored-by: Mathis <echobt@users.noreply.github.com>
proof-eval/harvest call the offer. Miners still post claim+code+FLOPs vs topic. Pin ceilings bound the judge; topic field is require_judge_offer_commitment. Co-authored-by: Mathis <echobt@users.noreply.github.com>
Co-authored-by: Mathis <echobt@users.noreply.github.com>
b27590e to
3b45e05
Compare
Summary
Rebased onto
mainafter #224 (323db5a4). Architecte/Mathis lock (do not weaken):InferenceOffer= digest-pinned RLM judge backend (proof-eval/ harvest call it)offer_idas a train target; still claim + code + FLOPs + artifact vs a topicrequire_judge_offer_commitment(not a miner-facing bind)Emission is bounty 2000 / proof 8000. Eval digest stays the main pin
sha256:78b614a1f51ce5dd80076c4e343a2b31b85d6c36025e02836cb83929867e7009— do not invent a sha256. Empty digest still fail-closes. Live submits stay 503 until harvest is wired, a baseline is sealed, and ≥1 topic is open.Testeur blockers (this revision)
1. API key reaches the harvest pod
PROOF_INFERENCE_API_KEY_FILE(contents never logged, never onGET /v1/status)teacher.env(OPENAI_API_KEY+PROOF_INFERENCE_API_KEY) andpod.runsources that file; the key is not inHarvestRequestJSONproof-evalsendsAuthorization: Beareron judge/chat/completions(and refusesapi_keyin request.json)can_scoreis false / submit 503 if the open offer needs auth and the key file is missing/unreadable2. Origin is bound into commitment + serve-check
config_commitmenthashes config knobs andprovider.base_urlserves_topicrejects a topic that spoofsinference.base_url(503, before lattice)resolve_inferenceuses the committed offer origin; topic/pin/secret cannot redirect the RLM after serve-checkinference.base_url→ 503 / committed judge originHF
proxy_model/proxy_modelsstay empty. Miners still do not bind submit tooffer_id.Judge config
Pin (git) —
config/proof-pin.tomlnested[inference]plus ceilings that bound the judge:proxy_model/proxy_models[inference]provider,base_url(empty = secret-backed),model,mode, token capsinference_config_schema_version1allowed_modeschat,completions,embeddings(pin may subset)max_input_tokens_ceiling32768max_output_tokens_ceiling8192inference_offer_commitment_algsha256Live InferenceOffer (operator state) —
PROOF_INFERENCE_OFFER_FILE. Auth:PROOF_INFERENCE_API_KEY_FILEstaged as harvestteacher.env. Optional origin:PROOF_INFERENCE_BASE_URL/_FILE(cannot override a committed offer origin).Topic
inference{…}may override provider/model/mode and may only tighten token caps. It must not redirect origin. Optionalrequire_judge_offer_commitmentpins the live judgeconfig_commitment(host 503 on mismatch).Miner submit does not take
inference_offer_id/config_commitment. Host stamps those as judge provenance.architectureis not compared to an HF id.Status: public pin
inferenceand publicinference_offeronly. No origins, no keys.Greptile
Every PR is reviewed by Greptile before merge. Config:
.greptile/.@greptileai reviewTest plan
cargo test -p proof-task -p proof-holdout -p proof-eval -p proof-harvest -p proof-http -p proof-challenge -p proof-challenge-binpython3 -m pytest eval/tests/test_contract.py(12 passed)cargo fmt --all -- --checkcargo clippy -p proof-task -p proof-holdout -p proof-eval -p proof-harvest -p proof-http -p proof-challenge --all-targets -- -D warningscargo run -p xtask -- loc-capcargo run -p xtask -- external-docs-checkRisk
No emission retune (stays 2000/8000). No invented digest. Fail-closed 503 for a down/incomplete/unauthed judge or a spoofed topic origin.
proof-holdoutis a loc-cap split of the existing holdout module (same API viaproof_taskre-exports).Naming
I did not rename
BASE_*environment variables, deployed host paths(
/opt/base,/run/base, …), GHCRbaseintelligence/basepackage names, orbase-*-v1cryptographic domain tags, unless this PR’s purpose is a coordinatedcutover documented in
docs/NAMING.md.