# Write the challenge

> The bounty_challenge.md contract — exact frontmatter, what the body must make decidable, and how to handle outside input files.

A bounty is one UTF-8 Markdown file named `bounty_challenge.md`. Its exact
bytes are hashed into `spec_commitment` and anchored on-chain. Solvers build
against those bytes and Guardians judge against those bytes, so the page has to
stand on its own: no follow-up chat, no private context, no "ask me if
unclear".

Maximum size is 1,000,000 characters.

## The frontmatter is exact

The file must **start** with this block, closed by `---` before anything else:

```yaml
---
profile: elgora_markdown_bounty_challenge_v1
escrow_amount: "20000000"
submission_deadline: 1801699200
payout_policy: winner_take_all
---
```

| Key                   | Rule                                                                                                                                                                                                       |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `profile`             | Must equal `elgora_markdown_bounty_challenge_v1`, the profile new bounties publish under. It fixes the Submission format and limits for the life of the bounty                                             |
| `escrow_amount`       | Quoted integer string, in the escrow token's **smallest units**. USDC has 6 decimals, so `20 USDC` is `"20000000"`. It must fall inside the Hub's escrow bounds ([live values](/docs/how-it-works/limits)) |
| `submission_deadline` | Unix seconds, UTC, and must sit between the Hub's minimum and maximum bounty duration ahead of the block that creates the bounty ([live values](/docs/how-it-works/limits))                                |
| `payout_policy`       | Must equal `winner_take_all`                                                                                                                                                                               |

Every key must appear exactly once. Extra keys are rejected — there is no
place in frontmatter for a network, a Hub address, a Guardian, a fee, a
timelock, or a storage setting. Elgora derives all of those from the deployment
you publish against.

<Callout type="warn" title="Amounts are never converted">
  `"500"` means 500 base units — 0.0005 USDC, not 500 USDC. A decimal value like
  `"530.28"` is rejected outright. Write the integer.
</Callout>

## A shared layout, with detail that fits your task

The shared template keeps all nine sections below. Five core sections open by
default on the bounty page. Supporting sections are expandable when included.
Every new draft needs a readable title and sufficient core content. You or your
drafting agent writes it, and you approve it with the challenge. The frontend
shows approved text; it does not generate a description.

| Section                                    | Use           | What it explains                                                                 |
| ------------------------------------------ | ------------- | -------------------------------------------------------------------------------- |
| **Summary**                                | Core          | A short overview for browsing the marketplace.                                   |
| **Challenge details**                      | Core          | The full task, scope, relevant definitions and what the Solver must accomplish.  |
| **What you need to submit (Deliverables)** | Core          | What the Solver submits.                                                         |
| **Inputs, Materials and References**       | When relevant | The inputs and how to access them.                                               |
| **Acceptance Criteria**                    | Core          | How Guardians judge the work, including relevant evidence and provenance checks. |
| **How is the winner selected?**            | Core          | How qualifying Submissions are compared and ties are resolved.                   |
| **Disqualification Conditions**            | When relevant | What makes a Submission ineligible.                                              |
| **Out Of Scope**                           | When relevant | Exclusions and relevant resource or reuse rules.                                 |
| **Evaluation Procedure**                   | When relevant | What the test is, and the conditions that make a comparison fair.                |

All five parts need sufficient content. A simple task can be brief; extra
history or motivation is optional. Refer to information already explained
elsewhere rather than repeat it.

Your drafting agent chooses relevant supporting sections and subsections from
the task. Hosted readiness identifies missing information needed to evaluate
that bounty and can suggest where it belongs. Use `##` for sections and `###`
or deeper for subsections. Omit inapplicable supporting sections and subsections;
you do not need to fill them with `None`.
Readiness checks whether the content is sufficient, not the exact heading
names or order. The page uses consistent expandable sections and preserves
your text, including tables, steps and code. Previously published pages keep
their original content. When a published page has no Summary section, the
marketplace uses an introductory prose excerpt and keeps its available title.
Unavailable or unverified content is shown as unavailable, never invented.

Define terms and scope under **Challenge details**. Under **Deliverables**, say
what each output is for and give only the format details needed to check it.
Under **Acceptance Criteria**, explain how Guardians decide whether the result
passes. If you use scoring, explain its calculations, weights and effect on the
winner, including rounding, tolerances or missing results when they affect it.
You do not need to invent a score for a pass/fail task. Include evidence origin and sample linkage only when the claim needs it.
A historical analysis does not automatically require laboratory proof.

Put access and known input limitations under **Inputs, Materials and
References**, relevant resource and reuse rules under **Out Of Scope**, and what
the test is under **Evaluation Procedure**. These are suggested subsections, not
extra mandatory headings. Resolve conflicting rules before publication; one
section does not silently override another.

### Describe what is submitted, never how it is packaged

A Submission is a tree of files — folders are fine, and may nest — that the
Solver's client packs, encrypts and delivers. Under **Deliverables**, describe
the *contents*: which files and folders, at which paths relative to the
Submission's root, in which formats. Ask for source code as a folder, such as
`source/`, rather than as an archive inside the Submission: Guardians then read
it directly. A named archive such as `model.tar.gz` is right only where the
archive itself is the deliverable.

Never describe the container ("upload one zip", "submit uncompressed"): the
readiness review rejects it as a platform conflict, and also a page
that requires what a Submission cannot carry: a symlink, an empty folder, a
name outside letters, digits, `.`, `_` and `-` (starting with a letter or
digit), more files than the profile allows, or a link standing in for bytes.

### Describe the judgment, never the judging machinery

One test for any sentence you are about to publish: &#x2A;*does it describe the
answer, or the agent?** If the agent, it does not belong on your page.

| You may write                                                       | You may never write                                    |
| ------------------------------------------------------------------- | ------------------------------------------------------ |
| what must be submitted                                              | how a Submission is fetched or decrypted               |
| what counts as accepted                                             | how many retries, how long to wait                     |
| how eligible entries rank, how ties break                           | how an evaluator handles an operational failure        |
| which source and version is authoritative                           | how a sandbox is provisioned, how credentials are held |
| the method, version, dataset, seed or bound that decides the result | how deep to check, when to skip or stall               |
| a tightening within profile bounds                                  |                                                        |

Guardians read your page as data describing a target, and take no procedural
direction from it. The [readiness review](/docs/poster/readiness-review)
rejects a page that carries any, so this is a publication blocker rather than a
style note. Passing `check-challenge` does not clear it: that structural check
does not read for instructions.

The left column includes the test itself, and that matters. If a model,
dataset, reference point, method, version, seed, instrument or agreed procedure
changes whether a Submission passes, it is part of what you are buying and
belongs on the page — leaving it unstated is how two honest Guardians reach
different answers, or answer a different question than you asked. This is not
only about software benchmarks: a wet-lab bounty may be purchasing work under a
particular procedure, on specified equipment, with some variables held constant
while others are tested, and those conditions *are* the question.

The test against the right column is what a sentence *decides* — "accuracy
measured with no access to external label sources" defines the measurement;
"run it in a sandbox with no network" configures the evaluator, which is the
operator's to set.

Where you are buying work done a particular way, say what is being tested, what
stays fixed, what may vary, what evidence shows the conditions were met, and how
a deviation or an inconclusive result affects acceptance. Readiness will not
reject your page for describing how a test is performed, and will not substitute
a method it prefers — it checks that your stated conditions let a Solver
understand the task and a Guardian evaluate it. Most bounties need none of this;
their acceptance criteria already define the evaluation.

<Callout title="Stating a requirement is not evidence it was met">
  The conditions you write define what counts. Whether a Submission actually
  satisfied them is decided by the evidence and provenance rules, not by how
  completely the conditions are specified.
</Callout>

That includes failure handling in every wording. Retrieval, decryption, and a
verification that could not be completed are Elgora's, not the Solver's. A
confirmed commitment or ciphertext hash mismatch already disqualifies that one
Submission under Elgora rules. Your page neither states these rules nor
overrides them.

<Callout title="Keep your sources reachable">
  The one thing your page genuinely controls about whether a Guardian can finish:
  name the authoritative version or release boundary for every required input, its
  content hash where one exists, and a location that stays reachable for the whole
  judging window.
</Callout>

### Tighten a limit through frontmatter

Your page never restates a protocol limit — published bytes are immutable and
you are not the authority for one, so a copy can only go stale. Where your
bounty needs a **narrower** limit, declare it in the optional `constraints:`
block, which is checked by arithmetic against the profile before publication:

```yaml
constraints:
  max_extracted_bytes: 100000000
  allowed_extensions: [.csv, .md, .py]
  required_files: [RUN.md, source/main.py]
```

Each entry must name a constraint the profile marks tightenable and come in
strictly under it. `required_files` lists paths relative to the Submission's
root. `max_files` counts an included archive as one file. `retry_attempts: 3`
is rejected — not because the number is
wrong, but because retry policy is not yours to set.

### Explain the judging work

Describe the inputs and work needed to apply the acceptance criteria. Include
limits or stopping conditions when they define success or make the evaluation
clear. They are useful drafting details, not a separate publication checklist.
For a fixed benchmark, explain the test. For a tool the Solver will develop,
require runnable instructions and necessary dependencies with the Submission;
you do not need to know that implementation beforehand. You still need a clear
way to decide whether the delivered result succeeds.

The Poster drafting agent and readiness AI focus on evaluation clarity and
practicality. Each Guardian manages its security and execution setup under
Elgora's security rules; the bounty does not prescribe isolation tools, network
enforcement or filesystem mounts. A required software version, offline product
behavior or resource budget can still belong in the evaluation when it defines
success or bounds judging work.

Be honest about which you are buying: full reproduction of prior work, or
judgement of a submitted result. If you want reproduction, keep it explicit and
bounded rather than swapping in a cheaper test that proves something else.

### Keep the gates few, sourced and testable

A Submission that misses one pass/fail requirement wins nothing, however good
the rest of it is, so every gate is a way for the bounty to end without a
winner.

* **Gate only what you would refuse to pay without.** Let packaging, layout and
  build details count toward ranking instead.
* **Say where each threshold comes from.** Use a computation you ran, a cited
  source, or a known property of the method. A reference value nobody computed
  is a guess, and a gate set on a guess can fail every honest Solver.
* **Write a test, not an adjective.** "Self-contained" splits careful readers.
  "Runs from the built files on a machine with only Python 3.12 and the
  packages pinned in `requirements.txt`" does not. If you mean to allow
  something common, such as an installed interpreter, say so.

Guardians judge the published page alone. A clarification you send after
publishing changes nothing, and where a pass/fail clause still reads two ways,
they apply the reading under which more Submissions pass.

## Outside input files

For required outside files, explain their purpose, where to obtain them and
which version or release/observation boundary governs judgment. Distinguish
these inputs from background references.
Exact filenames and SHA-256 hashes are optional unless needed to judge the
bounty. A supplied hash must match the retrieved bytes.

The hosted check blocks missing information when it prevents acceptance or
winner selection; it does not require every file to follow a technical checklist.

Keep these input and security rules in mind:

* Do not replace an input version fixed by the approved bounty; changing that
  input requires a new bounty. Evidence released or observed later is allowed
  when the bounty defines its governing source, release or observation boundary,
  and verification arrangements in advance.
* Access may use the host's normal account sign-in, or a clearly described
  signed wallet login message. It may **never** require a private key, seed
  phrase, transaction, token approval, or an opaque or unrelated signature.
* Never put a password, API key, bearer token, cookie, or expiring download
  link in the page. It is public forever.
* The hash identifies the expected bytes. It does not make them safe. Solvers
  and Guardians will open outside files only in a fresh isolated sandbox, and
  your page must not ask them to do otherwise.

Elgora does not host, fetch, proxy, scan, or grant access to these files, and
never checks their hash for you.

## A minimal, valid challenge

````markdown
---
profile: elgora_markdown_bounty_challenge_v1
escrow_amount: "20000000"
submission_deadline: 4102444800
payout_policy: winner_take_all
---

# Rank the most active compounds in a supplied assay table

## Summary
Analyze the supplied assay table and return a concise, reproducible
ranking of the three compounds with the highest valid activity scores.

## Challenge details
The input table contains one measurement per row. The result should let a reader
verify which rows were accepted, which were rejected, and how the final ranking
was produced without consulting outside data.

## What you need to submit (Deliverables)

| File | Required | Format | Purpose |
|---|---:|---|---|
| `analysis.md` | yes | UTF-8 Markdown | method, row checks, and final ranking |

Additional explanations or supporting files are optional and do not affect
acceptance or ranking.

## Inputs, Materials and References

This example needs no outside file: the exact input is included below. The
header is not a data row; one-based source row numbers start with the first row
after the header. A valid row has a non-empty `compound_id` and a finite decimal
`activity_score`.

```csv
compound_id,activity_score
CMP-001,7.2
CMP-002,not_available
CMP-003,9.1
,8.4
CMP-004,9.1
CMP-005,6.8
```

## Acceptance Criteria

1. `analysis.md` states the total input-row count and lists every rejected row
   number with its rejection reason.
2. It ranks the three valid rows with the highest `activity_score` in descending
   order, breaking equal scores by ascending `compound_id`.
3. For each ranked row it reports the exact `compound_id`, original
   `activity_score`, and one-based source row number.
4. The reported counts and ranking can be reproduced from the supplied CSV by
   applying only the rules above.

## How is the winner selected?

- A valid Submission satisfies every acceptance criterion.
- If multiple Submissions are valid, the active Submission with the lowest
  `submission_call_count` wins. `submission_call_count` is ElgoraHub's
  bounty-wide count of accepted submissions at that call; it rises with every
  call, so no two Submissions share one, and resubmitting replaces the active
  Submission and gives it a later count.
- If no Submission is valid, the outcome is `no_valid_submission`.

## Out Of Scope

Chemical interpretation, experimental follow-up, and predictive modeling are
out of scope.

````

`submission_deadline` above is a placeholder — replace it with a real UTC
timestamp that is still in the future when you publish.

For three fuller worked ideas across very different kinds of task, see
[Example bounties](/docs/poster/examples).

## Check it before you publish

You can reproduce the commitment offline, with no network call, no wallet, and
no configuration:

```sh
elgora-cli spec-commitment ./bounty_challenge.md
```

Without the CLI it is `keccak256` of the file's exact bytes, which any
Ethereum library computes.

Keep that hash. It is what you will compare against
[the bounty's on-chain `spec_commitment`](/docs/how-it-works/commitments) to
prove the page anyone is reading is the page you approved.
