Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions crates/db/migrations/0013_design_quota_manual.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-- Split the design daily run quota by run origin.
--
-- `design_quota.runs_used` counted *every* sandbox run against a single
-- 10-run/hotkey/day ceiling, and the organizer's own round scheduler charged
-- the same bucket as the miner's `POST /v1/harness`. A full UTC day dispatches
-- `ROUNDS_PER_DAY (10) × PROMPTS_PER_ROUND (3)` = 30 runs to every registered
-- harness, so an honest, fully participating miner exhausted the day's quota
-- after ~3.3 rounds, sat out the remaining rounds, and could not even submit
-- (intake 409s when scheduling fails).
--
-- `manual_runs_used` isolates the anti-spam ceiling that actually belongs to
-- miner-initiated submissions; organizer-scheduled work is `runs_used -
-- manual_runs_used` and is bounded by a separate cap derived from the live
-- round schedule. Existing rows backfill to 0 manual runs, which only ever
-- widens a live miner's submission budget.

ALTER TABLE design_quota
ADD COLUMN manual_runs_used INTEGER NOT NULL DEFAULT 0;

ALTER TABLE design_quota
ADD CONSTRAINT design_quota_manual_runs_nonneg CHECK (manual_runs_used >= 0);
97 changes: 94 additions & 3 deletions crates/design-challenge-task/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub const ROUNDS_PER_DAY: u64 = 10;
/// (`DESIGN_AGENT_RUN_TIMEOUT_SECS` override).
pub const AGENT_RUN_TIMEOUT_SECS: u64 = 1_800;

/// Prompts selected per round (~2–3 × harness under daily quota).
/// Prompts selected per round (each becomes one organizer-scheduled sandbox run).
///
/// Default only — runtime code must use [`prompts_per_round`]
/// (`DESIGN_PROMPTS_PER_ROUND` override).
Expand All @@ -60,8 +60,19 @@ pub const PROMPTS_PER_ROUND: usize = 3;
/// [`SCORING_WINDOW_ROUNDS`] rounds, cheat excluded.
pub const SCORING_WINDOW_ROUNDS: u64 = 10;

/// Max sandboxed runs per hotkey per UTC day.
pub const DAILY_RUN_QUOTA: u32 = 10;
/// Anti-spam ceiling on **miner-initiated** sandbox runs per hotkey per UTC
/// day — runs created by `POST /v1/harness`. Organizer-scheduled round runs
/// draw on [`scheduled_daily_run_cap`] instead, so a harness that participates
/// in every round of the day is never blocked from submitting.
///
/// Default only — runtime code must use [`manual_daily_run_quota`]
/// (`DESIGN_MANUAL_DAILY_RUN_QUOTA` override).
pub const MANUAL_DAILY_RUN_QUOTA: u32 = 10;

/// Headroom multiplier on the derived organizer-scheduled daily run cap. The
/// cap is a runaway-scheduler guard, not a participation limit, so it must
/// stay comfortably above the full-day schedule volume.
pub const SCHEDULED_DAILY_RUN_HEADROOM: u32 = 2;

/// Minimum annotations required per pair before Elo consume.
pub const MIN_ANNOTATIONS_PER_PAIR: u32 = 3;
Expand Down Expand Up @@ -107,6 +118,61 @@ pub fn prompts_per_round() -> usize {
.unwrap_or(PROMPTS_PER_ROUND)
}

/// Rounds in a UTC day under the effective [`round_secs`]. Equals
/// [`ROUNDS_PER_DAY`] in production; staging compresses rounds, so scheduling
/// limits must derive from this and never from the constant.
#[must_use]
pub fn rounds_per_day_effective() -> u64 {
(86_400 / round_secs()).max(1)
}

/// Sandbox runs the organizer dispatches to one harness across a full UTC day
/// (`rounds/day × prompts/round`). This is the volume an honest, fully
/// participating harness must be allowed to execute.
#[must_use]
pub fn scheduled_runs_per_day() -> u32 {
let per_round = u64::try_from(prompts_per_round()).unwrap_or(PROMPTS_PER_ROUND as u64);
u32::try_from(rounds_per_day_effective().saturating_mul(per_round)).unwrap_or(u32::MAX)
}

/// Effective anti-spam ceiling on miner-initiated runs per hotkey per UTC day
/// (`DESIGN_MANUAL_DAILY_RUN_QUOTA` override; default
/// [`MANUAL_DAILY_RUN_QUOTA`]).
#[must_use]
pub fn manual_daily_run_quota() -> u32 {
u32::try_from(env_u64(
"DESIGN_MANUAL_DAILY_RUN_QUOTA",
u64::from(MANUAL_DAILY_RUN_QUOTA),
1,
))
.unwrap_or(MANUAL_DAILY_RUN_QUOTA)
}

/// Effective ceiling on organizer-scheduled runs per hotkey per UTC day
/// (`DESIGN_SCHEDULED_DAILY_RUN_CAP` override; default
/// [`scheduled_runs_per_day`] × [`SCHEDULED_DAILY_RUN_HEADROOM`]).
///
/// The floor is [`scheduled_runs_per_day`]: an operator override can never sit
/// below the day's own schedule, which is the bug this cap replaced.
#[must_use]
pub fn scheduled_daily_run_cap() -> u32 {
let floor = scheduled_runs_per_day();
let default = floor.saturating_mul(SCHEDULED_DAILY_RUN_HEADROOM);
u32::try_from(env_u64(
"DESIGN_SCHEDULED_DAILY_RUN_CAP",
u64::from(default),
u64::from(floor),
))
.unwrap_or(default)
}

/// Total sandbox runs one hotkey may accumulate in a UTC day across both
/// origins (display / dashboard value; enforcement is per-origin).
#[must_use]
pub fn daily_run_quota() -> u32 {
manual_daily_run_quota().saturating_add(scheduled_daily_run_cap())
}

/// Compute round id from unix seconds under an explicit round length.
#[must_use]
pub const fn round_id_at_with(unix_secs: u64, round_secs: u64) -> u64 {
Expand Down Expand Up @@ -160,6 +226,31 @@ mod tests {
assert_eq!(round_secs(), ROUND_SECS);
assert_eq!(agent_run_timeout_secs(), AGENT_RUN_TIMEOUT_SECS);
assert_eq!(prompts_per_round(), PROMPTS_PER_ROUND);
assert_eq!(manual_daily_run_quota(), MANUAL_DAILY_RUN_QUOTA);
}

#[test]
fn scheduled_cap_covers_a_full_day_of_rounds() {
// The bug this replaced: a 10-run/day cap against a 10-round × 3-prompt
// schedule locked an honest harness out after ~3.3 rounds.
assert_eq!(rounds_per_day_effective(), ROUNDS_PER_DAY);
assert_eq!(
scheduled_runs_per_day(),
u32::try_from(ROUNDS_PER_DAY).unwrap() * u32::try_from(PROMPTS_PER_ROUND).unwrap()
);
assert_eq!(scheduled_runs_per_day(), 30);
assert!(scheduled_daily_run_cap() >= scheduled_runs_per_day());
assert_eq!(
scheduled_daily_run_cap(),
scheduled_runs_per_day() * SCHEDULED_DAILY_RUN_HEADROOM
);
assert!(daily_run_quota() > scheduled_runs_per_day());
Comment on lines +237 to +247

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check lint configuration for design-challenge-task and its test module.
set -euo pipefail

fd -t f 'lib.rs' crates/design-challenge-task/src --exec sed -n '1,30p' {}
rg -n 'unwrap_used' crates/design-challenge-task Cargo.toml crates/design-challenge-task/Cargo.toml 2>/dev/null || true
rg -n 'unwrap_used|\[workspace.lints|\[lints' Cargo.toml

Repository: BaseIntelligence/base

Length of output: 1234


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workspace lint config =="
sed -n '1,40p' Cargo.toml

echo
echo "== crate config around lib.rs and workspace package config =="
sed -n '70,180p' Cargo.toml
echo
sed -n '1,80p' crates/design-store/src/store.rs

echo
echo "== design-challenge-task files and test module outline =="
git ls-files 'crates/design-challenge-task/src/**'
rg -n 'mod tests|#\[cfg\(test\)\]|assert_eq!|unwrap\(\)' crates/design-challenge-task/src/lib.rs crates/design-challenge-task/src -S

Repository: BaseIntelligence/base

Length of output: 9614


Allow clippy::unwrap_used in the design-challenge-task test module.

Cargo.toml denies clippy::unwrap_used, and crates/design-challenge-task/src/lib.rs uses unwrap() inside #[cfg(test)] mod tests. Add #![allow(clippy::unwrap_used)] at the top of that module, or remove/replace the unwrap() calls before Clippy gates fail.

🤖 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 `@crates/design-challenge-task/src/lib.rs` around lines 237 - 247, Allow
clippy::unwrap_used within the #[cfg(test)] mod tests module in lib.rs, or
replace its unwrap() calls with equivalent non-panicking handling; preserve the
existing test assertions and behavior.

Source: Coding guidelines

// An operator override below the schedule clamps back up to it, so no
// env value can re-create the lockout. (Own var name: env is global.)
let floor = u64::from(scheduled_runs_per_day());
std::env::set_var("BASE_SCHEDULED_CAP_CLAMP_TEST", "1");
assert_eq!(env_u64("BASE_SCHEDULED_CAP_CLAMP_TEST", 60, floor), floor);
std::env::remove_var("BASE_SCHEDULED_CAP_CLAMP_TEST");
}

#[test]
Expand Down
182 changes: 182 additions & 0 deletions crates/design-challenge/src/corpus.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
//! Shared anti-cheat corpus: other hotkeys' prior art only.
//!
//! Same-hotkey revisions are never comparison material. Review victims must be
//! strictly earlier than the candidate. Gate + review share this module so they
//! cannot drift. Pass the candidate row explicitly (not via recent-list lookup).

use challenge_agentic::{CorpusEntry, GateCorpusEntry};
use design_store::HarnessRow;

const BASELINE_AGENT: &str =
include_str!("../../../docs/external-miner/examples/design-baseline/agent.py");

fn other_miners<'a>(
candidate: &'a HarnessRow,
recent: &'a [HarnessRow],
) -> impl Iterator<Item = &'a HarnessRow> {
let miner = candidate.miner_hotkey.to_ascii_lowercase();
recent
.iter()
.filter(move |h| h.id != candidate.id && h.miner_hotkey.to_ascii_lowercase() != miner)
}

fn corpus_id(h: &HarnessRow) -> String {
format!("harness:{}", h.id)
}

/// Pre-LLM copy-gate corpus (`created_at_ms` kept for gate ordering).
#[must_use]
pub fn gate_corpus(candidate: &HarnessRow, recent: &[HarnessRow]) -> Vec<GateCorpusEntry> {
other_miners(candidate, recent)
.map(|h| GateCorpusEntry {
id: corpus_id(h),
source: h.agent_py.clone(),
created_at_ms: h.created_at_ms,
})
.collect()
}

/// Reviewer corpus: baseline + other hotkeys' earlier harnesses.
/// Untimestamped rows are dropped; a legacy candidate (`created_at_ms == 0`)
/// keeps every timestamped other-hotkey row so the corpus cannot go empty.
#[must_use]
pub fn review_corpus(candidate: &HarnessRow, recent: &[HarnessRow]) -> Vec<CorpusEntry> {
let mut corpus = vec![CorpusEntry {
id: "baseline".into(),
source: BASELINE_AGENT.to_owned(),
}];
let cand_ts = candidate.created_at_ms;
corpus.extend(other_miners(candidate, recent).filter_map(|h| {
if h.created_at_ms == 0 || (cand_ts > 0 && h.created_at_ms >= cand_ts) {
return None;
}
Some(CorpusEntry {
id: corpus_id(h),
source: h.agent_py.clone(),
})
}));
corpus
}

#[cfg(test)]
mod tests {
use super::*;

fn harness(id: &str, miner: &str, source: &str, created_at_ms: u64) -> HarnessRow {
HarnessRow {
id: id.into(),
miner_hotkey: miner.into(),
agent_py: source.into(),
pyproject_toml: "[project]\nname='x'\nversion='0.1.0'\n".into(),
extra_files: std::collections::BTreeMap::new(),
active: true,
eliminated_until_round: 0,
created_at_ms,
}
}

const AA: &str = "aa";
const BB: &str = "bb";

fn ids(entries: &[CorpusEntry]) -> Vec<&str> {
entries.iter().map(|e| e.id.as_str()).collect()
}

fn gate_ids(entries: &[GateCorpusEntry]) -> Vec<&str> {
entries.iter().map(|e| e.id.as_str()).collect()
}

#[test]
fn own_previous_version_is_never_compared_against() {
let v1 = harness("h1", AA, "def run(t):\n pass\n", 1_000);
let v2 = harness("h2", AA, "def run(t):\n pass\n", 2_000);
let recent = vec![v2.clone(), v1];

assert!(
gate_corpus(&v2, &recent).is_empty(),
"a miner's own v1 must not be a copy victim for their v2"
);
assert_eq!(
ids(&review_corpus(&v2, &recent)),
vec!["baseline"],
"self-revision must not reach the LLM corpus either"
);
}

#[test]
fn hotkey_match_is_case_insensitive() {
let mine_old = harness("h1", "AABB", "old\n", 1_000);
let mine_new = harness("h2", "aabb", "new\n", 2_000);
let recent = vec![mine_new.clone(), mine_old];
assert!(gate_corpus(&mine_new, &recent).is_empty());
assert_eq!(ids(&review_corpus(&mine_new, &recent)), vec!["baseline"]);
}

#[test]
fn other_miner_prior_art_stays_in_both_corpora() {
let victim = harness("h1", BB, "def run(t):\n pass\n", 1_000);
let copier = harness("h2", AA, "def run(t):\n pass\n", 2_000);
let recent = vec![copier.clone(), victim];

assert_eq!(gate_ids(&gate_corpus(&copier, &recent)), vec!["harness:h1"]);
assert_eq!(
ids(&review_corpus(&copier, &recent)),
vec!["baseline", "harness:h1"]
);
}

#[test]
fn candidate_outside_the_recent_window_still_excludes_itself() {
// The candidate is deliberately absent from `recent` (aged out): the
// rules must come from the candidate row, not from a lookup.
let mine_old = harness("h1", AA, "old\n", 1_000);
let theirs = harness("h3", BB, "theirs\n", 1_500);
let mine_new = harness("h2", AA, "new\n", 2_000);
let recent = vec![theirs, mine_old];

assert_eq!(
gate_ids(&gate_corpus(&mine_new, &recent)),
vec!["harness:h3"]
);
assert_eq!(
ids(&review_corpus(&mine_new, &recent)),
vec!["baseline", "harness:h3"]
);
}

#[test]
fn review_corpus_holds_prior_art_only() {
let candidate = harness("h1", AA, "mine\n", 1_000);
let later = harness("h2", BB, "later\n", 5_000);
let unknown = harness("h3", BB, "legacy\n", 0);
let recent = vec![later, unknown];

// A later copycat must never make the original look like the copier.
assert_eq!(ids(&review_corpus(&candidate, &recent)), vec!["baseline"]);
// The gate keeps both and orders them itself.
assert_eq!(gate_corpus(&candidate, &recent).len(), 2);
}

#[test]
fn legacy_candidate_keeps_timestamped_other_hotkeys() {
let legacy = harness("h0", AA, "legacy\n", 0);
let prior = harness("h1", BB, "prior\n", 1_000);
let recent = vec![prior];
assert_eq!(
ids(&review_corpus(&legacy, &recent)),
vec!["baseline", "harness:h1"],
"unknown candidate timestamp must not empty the review corpus"
);
}

#[test]
fn baseline_is_always_available_to_the_reviewer() {
let candidate = harness("h1", AA, "mine\n", 1_000);
let corpus = review_corpus(&candidate, &[]);
assert_eq!(ids(&corpus), vec!["baseline"]);
assert!(
corpus[0].source.contains("def run("),
"baseline agent source"
);
}
}
24 changes: 13 additions & 11 deletions crates/design-challenge/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@
//! `challenge_id = "design"`.

#![forbid(unsafe_code)]
#![allow(clippy::missing_errors_doc)]
#![allow(clippy::doc_markdown)]
#![allow(clippy::cast_possible_truncation)]
#![allow(clippy::cast_sign_loss)]
#![allow(clippy::too_many_lines)]
#![allow(clippy::duration_suboptimal_units)]
#![allow(clippy::map_unwrap_or)]
#![allow(clippy::cast_possible_wrap)]
#![allow(clippy::result_large_err)]
#![allow(
clippy::missing_errors_doc,
clippy::doc_markdown,
clippy::too_many_lines
)]
#![allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
#![allow(clippy::duration_suboptimal_units, clippy::map_unwrap_or)]
#![allow(clippy::cast_possible_wrap, clippy::result_large_err)]
#![allow(clippy::case_sensitive_file_extension_comparisons)]
#![allow(clippy::struct_field_names)]

pub mod backfill;
pub mod corpus;
pub mod host_sim;
mod orchestrator;
pub mod score;
Expand All @@ -28,8 +28,10 @@ pub use challenge_common::{
GatewayClient, GatewayClientConfig, LeafEmitError,
};
pub use design_challenge_task::{
agent_run_timeout_secs, prompts_per_round, round_id_at, round_secs, CHALLENGE_ID,
CHALLENGE_ID_BYTES, DAILY_RUN_QUOTA, PROMPTS_PER_ROUND, ROUND_SECS, SCORE_MAX, SCORING_VERSION,
agent_run_timeout_secs, daily_run_quota, manual_daily_run_quota, prompts_per_round,
round_id_at, round_secs, rounds_per_day_effective, scheduled_daily_run_cap,
scheduled_runs_per_day, CHALLENGE_ID, CHALLENGE_ID_BYTES, MANUAL_DAILY_RUN_QUOTA,
PROMPTS_PER_ROUND, ROUNDS_PER_DAY, ROUND_SECS, SCORE_MAX, SCORING_VERSION,
SCORING_WINDOW_ROUNDS,
};
pub use design_http::{
Expand Down
Loading
Loading