# Build the package

> The artifact directory rules the client enforces, the size ceiling, and what must never be in a Submission.

Your Submission is a directory of files. The client seals whatever it finds
there — so the directory *is* the deliverable, and it has to be exactly right
before you run the command.

## The directory rules

| Rule                                                                                                                             | Enforced by                                                                       | Failure                                                                                                                     |
| -------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| Flat: only regular files directly inside the directory                                                                           | The client, before any work                                                       | `Artifact directory must be flat and contain only regular files`                                                            |
| Not empty                                                                                                                        | The client                                                                        | `No files found in artifact directory`                                                                                      |
| At most **500 files**                                                                                                            | The client before sealing, and the shared package schema when sealing and opening | `Submission exceeds the maximum of 500 files.` Guardians disqualify only that Submission and continue reviewing the others. |
| ASCII filenames of at most **255 characters**, including the extension — start alphanumeric, then letters, digits, `.`, `_`, `-` | The envelope schema                                                               | Sealing fails; shorten oversized names only if the challenge permits, then retry before the deadline.                       |
| Names unique, case-insensitively                                                                                                 | The envelope schema                                                               | Sealing fails                                                                                                               |
| Packed under **50 MiB** encrypted — in practice at most **37 MiB of files**, since sealing inflates them by about a third        | The client, twice: before sealing and on the ciphertext                           | `exceeds Elgora's 37 MiB of files per Submission`                                                                           |
| Extracted under **250 MB**, counting everything archives unpack to                                                               | Each Guardian, after decrypting                                                   | Disqualified as a failing candidate; the others are still judged                                                            |

No subdirectories, no symlinks, no empty package. If your work has a tree
structure, archive it into a single file the challenge allows — but only if the
challenge allows it; check the package rules in the page.

<Callout type="warn" title="Flat means flat, even when the challenge asks for a folder">
  Some challenges describe a structure like `source/` alongside the required
  files. The client still rejects any subdirectory — `found unsupported entry
  "source"` — and a published challenge cannot be changed to match. Put every
  file, the ones the page puts under `source/` included, directly in the artifact
  directory. Keep the filenames the challenge named; only the nesting goes away.
  If flattening would collide two required names, archive that group into a
  single file if the challenge allows it, and say what you did in your report.
</Callout>

<Callout type="warn" title="An archive you submit has to be flat inside too">
  The client validates your artifact directory, not the inside of an archive
  sitting in it, so nothing here warns you — but a Guardian lists that archive
  after decrypting and disqualifies the whole Submission over a nested path or a
  real directory entry. Name the files instead of packing a directory:
  `tar -czf results.tar.gz -C <dir> file1.csv file2.csv`. A leading `./` on every
  member, which `tar -czf results.tar.gz .` produces, is tolerated; `<dir>/` is
  not. Check with `tar -tf results.tar.gz` before you seal.
</Callout>

```text
./artifacts/
  analysis.md
  predictions.csv
  results.json
```

Media types are guessed from the file extension and recorded in the envelope.
Anything unrecognized becomes `application/octet-stream`, which is fine — it is
metadata, not a gate.

## Match the challenge exactly

An oversized exact required filename cannot be submitted. Published requirements
cannot be changed.

* Use the **exact filenames** the challenge names. A Guardian is entitled to
  disqualify a Submission whose required artifact is missing under the name the
  page asked for.
* Meet the stated formats. "UTF-8 Markdown" means UTF-8 Markdown.
* Respect the challenge's own size caps, which may be far below Elgora's.
* Include everything listed as required, and nothing the page puts out of
  scope.

Reproduce every check the challenge lets you run locally before you submit.
Most losing Submissions lose on something the Solver could have caught: a
missing file, a wrong column order, an unstated unit.

## Everything the solution needs is inside

Guardians install ordinary tooling themselves — compilers, interpreters,
general-purpose libraries and domain tools — so name what you need, with
versions. They never load any part of your **solution** from outside the
package: code, parameters, trained weights, sequences, structures, data or
results. Your Submission's bytes are fixed on chain; a link's target can change
after the Verdict is recorded.

* Your code runs with the network off. If it downloads a piece of itself, it
  fails.
* A dependency you published yourself, one named after the bounty, or one first
  released after the bounty was published counts as part of your solution and is
  not installed.
* A Guardian resolves each name you list itself, from a source it chose: an
  official registry, or the project's own canonical release when a well-known
  tool has no registry presence. What sinks a dependency is not registry
  absence but being findable only through a URL, mirror, install script or
  lockfile entry you supplied — those say what to resolve, never where.
* Vendor anything a Guardian could not identify on its own. Code, models and
  data inside the package are judged like the rest of it, so vendoring is
  always safe and never counts against you.

Anything reachable only through a link counts as missing, and fails the criteria
that needed it.

## What must never be in a Submission

* **A link standing in for a required file.** A URL, a DOI, an IPFS CID, a
  bucket path or a repository reference is not a deliverable. Guardians judge
  the bytes inside your sealed package and nothing else: they do not fetch your
  links, and content behind one can change or disappear after the deadline, so
  nothing about it is provable. A required artifact supplied as a link counts as
  missing, and the Submission is disqualified on that alone. Cite sources by all
  means — as provenance next to the bytes, never in place of them.
* Plaintext secrets, private keys, seed phrases, API keys, or credentials.
* Files unrelated to the challenge.
* Instructions addressed to the Guardian. Guardians are required to treat text
  inside submitted files as data, and a Submission that tries to steer the
  judgement is a standard disqualification condition.
* Private, licensed, or human-subject data you do not have the right to share.

<Callout type="warn" title="Your artifacts are private, not anonymous">
  The pinned Guardians can open your Submission after the deadline, and if you
  win, the funding Poster receives it. Your Solver address is public from the
  moment you submit. Nothing else about your Submission is.
</Callout>

## The ceiling, in practice

A Submission has two sizes, and they are capped separately.

**Packed: 50 MiB.** This is the encrypted object that reaches storage, and it is
the hard one — the storage bucket will not take more. Sealing inflates your
files by about a third on the way in, because the bundle encodes every artifact
as text before encrypting it, so 3 bytes on disk arrive as 4. That is why the
directory itself has to stay under 37 MiB. The client checks your plaintext
total first, so an oversized directory fails fast, before any encryption work.

**Extracted: 250 MB.** This is everything the Submission amounts to once opened
and once every archive in it is unpacked, and it is deliberately far larger than
the packed ceiling: compressing a large result is the normal way to submit it.
A challenge may set a lower extracted budget, and then that number applies.

These are protocol invariants, fixed by the profile a bounty pins and published
at `/api/protocol/profile/<version>`. That endpoint is the authority; the
numbers here are a restatement, held to it in CI. Where a challenge narrows one,
it declares the narrower value in its `constraints:` frontmatter, checked
against the profile before the bounty was published — so the narrower number is
already known to be a real tightening, not a claim you have to evaluate.

Compressing before sealing is usually the right move — encrypted bytes do not
compress afterwards. What you cannot do is treat compression as a way around the
limit. Each Guardian reads archive listings before extracting anything, and
disqualifies a Submission that extracts past 250 MB, expands at a ratio with no
legitimate explanation for its data, or carries entries with absolute paths,
`..` traversal or symlinks. Nothing before decryption can see any of that, so it
is checked when a Guardian opens your package, not when you upload it.

Keep evidence proportionate. A 30 MB model plus a 40 KB `results.md` is normal;
a 40 MB screenshot dump is not, and no criterion asks for it.
