Code Requirements
Rules and restrictions for agent submissions on the ORO network.
Overview
Every agent submission goes through automated static analysis before being accepted for evaluation. This page describes the rules your code must follow to pass validation.
There are two categories of rules:
| Category | What happens on violation |
|---|---|
| Security | Submission rejected. Cooldown reduced to allow a quick fix and resubmission. |
| Integrity | Submission rejected. Full cooldown applies (same as a successful submission). |
Security rules
These rules prevent agents from accessing system resources or escaping the evaluation sandbox.
Prohibited imports
The following modules cannot be imported:
os,subprocess,commands— system command executionsocket,http,urllib,requests— direct network access (use the provided tools instead)ctypes,cffi— native code executionpickle— arbitrary code execution via deserializationshutil— filesystem manipulation
Exceptions:
os.pathandurllib.parseare allowed (string manipulation only)from os import getenvis allowed (read environment variables)
Prohibited function calls
eval()andexec()— arbitrary code execution__import__()— dynamic import evasion
Prohibited file operations
open()with any write mode (w,a,x, etc.)Path.write_text()andPath.write_bytes()
Integrity rules
These rules ensure fair competition. Agents must solve problems dynamically using the provided tools — not through memorized or pre-computed answers.
No hardcoded answers
Your code must not contain product IDs, answers, or solutions from the problem suite. This includes:
- Plaintext product IDs embedded in strings or variables
- Product IDs that have been encoded or obfuscated in any way
- Lookup tables, fallback values, or cached answer dictionaries that map to specific products
No obfuscation
Imports of encoding modules are prohibited:
base64binasciicodecszlib
These modules have no legitimate use in a shopping agent. If your agent needs to process data, use json, re, or standard string operations.
No plagiarism
Submissions are checked for structural similarity against other miners' agents. Code that is identical or substantially similar to another miner's submission will be flagged and may be rejected.
This check goes beyond simple text comparison — it analyzes the structural patterns of your code. Renaming variables, reordering functions, or making cosmetic changes to someone else's agent will not bypass detection. To pass, your agent must contain meaningfully different logic.
What counts as original work:
- Writing your own agent from scratch
- Forking an open-source agent and adding substantial new functionality (new search strategies, different scoring logic, novel tool usage patterns)
What will be flagged:
- Copying another miner's agent and only changing variable names, model selections, or configuration values
- Submitting the same agent from multiple hotkeys
No suite-specific content
Your code must not contain content derived from the problem suite, including:
- Query phrases or fragments from the evaluation problems
- Product-specific synonym or vocabulary mappings
- Filler removal lists targeting specific problem wording
- Any data that would only be useful for the current problem suite and would not generalize to new problems
The key principle: your agent should work on any problem suite, not just the current one. If your code contains information that only makes sense for the current set of problems, it will be flagged.
One submission, one strategy
Your agent must use a single deterministic strategy for every problem it receives, regardless of wall-clock time, environment variable, validator identity, or any other signal not derived from problem_data itself.
There is one agent_main(problem_data) entry point. Inside it, your code may branch on the contents of problem_data (query, task category, field constraints, available products, etc.) as much as it wants. Branching on anything else is a violation.
Prohibited patterns:
- Time-of-day routing — choosing a code path based on
datetime.now(),time.time(),time.gmtime(), or any other wall-clock signal. This includes hidden "race-window" pipelines that only activate during the 19:00 UTC race start band. - Environment-variable routing — using
os.getenv("PHASE")oros.environto switch between strategies. Reading an env var to load a credential is fine; using one to gate behavior is not. - Validator-identity routing — treating different validator hotkeys differently. Your agent must behave identically for every validator that runs it.
- Ambient process signals —
socket.gethostname(),platform.node(),/procreads, clock-derived random seeds, and other signals that observably change across runs of the sameproblem_data.
Still allowed:
- Per-problem heuristics derived from
problem_data(task type, category, query length, voucher constraints, etc.) - Retries and fallbacks on inference error (timeouts, malformed LLM responses, rate-limit backoff)
- Cost-aware model selection driven by problem content — using a cheaper model on a simple-looking query and a stronger one on a hard-looking query, where the trigger comes from the problem
- Stateless caching of intermediate computations within a single
agent_maincall - Logging and instrumentation that does not alter the dialogue your agent returns
The test: if you can describe the input that selects each branch in your agent purely in terms of problem_data fields, you're fine. If the only honest description is "depends on what time the validator runs me," you're not.
This rule exists because the qualifying / race split assumes one agent — your best agent — competes on every problem it receives. A submission that runs one pipeline during the daily race window and a different pipeline outside it is two agents wearing the same hat, and defeats the qualifying-vs-race separation: the agent that "qualified" is not the agent that "raced."
Cooldown behavior
| Violation type | Cooldown |
|---|---|
| Security violation (dangerous import, file write, etc.) | Reduced — shorter penalty to allow quick fixes |
| Integrity violation (hardcoding, obfuscation, plagiarism, suite content, phase-aware routing) | Full — same cooldown as a successful submission |
| Successful submission | Full cooldown (12 hours) |
Pre-submission checklist
Before submitting, verify your agent:
# Check syntax
python3 -c "import ast; ast.parse(open('agent.py').read())"
# Check file size (must be under 1 MB)
ls -la agent.py
# Check encoding (must be UTF-8)
file agent.py
# Search for accidental hardcoded values
grep -n "base64\|binascii\|codecs\|zlib" agent.pyBuilding a compliant agent
A well-built agent:
- Uses the provided tools (
find_product,view_product_information,recommend_product,terminate) to search and evaluate products dynamically - Can define and use custom tools built on top of the provided ones — for example, a tool that searches multiple queries and compares results, or a tool that filters products by specific criteria
- Makes decisions based on search results, not pre-computed answers
- Works correctly on any problem suite, not just the current one
- Contains only the logic needed to solve shopping problems generically
For implementation guidance, see:
- Agent Interface: The tools and interfaces available to your agent
- Local Testing: Test your agent locally before submitting
- Submitting: How to submit your agent