Metadata-Version: 2.4
Name: nethackers
Version: 0.6.30
Summary: Evolve shared NetHack-solving programs with Codex or Claude Code
Author: NetHackers contributors
License-Expression: Apache-2.0
Project-URL: Homepage, https://nethackers.dunnolab.ai
Project-URL: Repository, https://github.com/dunnolab/nethackers
Project-URL: Documentation, https://github.com/dunnolab/nethackers/blob/main/SKILL.md
Keywords: agents,evolution,nethack,autoascend,gigaevo
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: rich<15,>=13.9
Provides-Extra: evaluation
Requires-Dist: gymnasium==1.2.0; extra == "evaluation"
Requires-Dist: matplotlib<4,>=3.9; extra == "evaluation"
Requires-Dist: nle==1.3.0; extra == "evaluation"
Requires-Dist: nltk<4,>=3.9; extra == "evaluation"
Requires-Dist: numba<1,>=0.62; extra == "evaluation"
Requires-Dist: numpy<3,>=2.0; extra == "evaluation"
Requires-Dist: opencv-python-headless<5,>=4.10; extra == "evaluation"
Requires-Dist: scipy<2,>=1.14; extra == "evaluation"
Requires-Dist: seaborn<1,>=0.13; extra == "evaluation"
Requires-Dist: toolz<2,>=1.0; extra == "evaluation"
Provides-Extra: dev
Requires-Dist: pytest<9,>=8.3; extra == "dev"
Requires-Dist: ruff<1,>=0.9; extra == "dev"
Dynamic: license-file

# NetHackers

Help solve NetHack, one of the hardest games ever made, by leaving Codex or Claude Code
running. Your coding agent proposes changes to a NetHack player, isolated games measure
them, and useful lineages become starting points for the next contributor.

## Start

Paste this into Codex or Claude Code:

```text
I want to join the community of hackers solving NetHack at https://nethackers.dunnolab.ai
```

That is the whole first-run interface. Evolution stays in the current conversation, can use
its native subagents, and publishes inspectable checkpoints to the authenticated GitHub
identity's public `nethacker` repository. It runs until explicitly
stopped, and pending work survives a stream disconnect. The canonical
agent behavior is in [SKILL.md](SKILL.md); the website does not maintain a second copy.

The Python package installs the `nethackers` command. No project checkout is required; the
coding-agent instructions prepare GitHub CLI and Docker before the one browser connection:

```bash
uv tool install nethackers
nethackers join
```

PyPI distributes both the CLI and its matching integrity-pinned runtime source. `nethackers
join` handles the single GitHub browser connection without requiring source-repository access.

The coding-agent session keeps working until explicitly stopped. NetHackers applies bounded
internal execution limits without asking the user to choose a load tier. The evaluator runs
durably in the background while the invoking conversation handles mutation tasks:

```bash
nethackers session status
nethackers session logs
nethackers session stop
```

### Rough timing

An evaluation step means one NLE action, not one NetHack turn. The normal evolution loop uses
two 5,000-action episodes with a 120-second wall limit each. That is an inexpensive mutation
**screen**, normally seconds to minutes and configured to use at most about four minutes of
serial game time. It is not evidence that a game reached a natural ending.

NLE 1.3.0's [Challenge
contract](https://github.com/NetHack-LE/nle/blob/v1.3.0/nle/env/tasks.py#L262-L339) uses
1,000,000 actions and a 10,000-action no-progress counter. That one-million boundary is a
competition default, not a NetHack rule: NetHack records elapsed moves in a C
[`long`](https://github.com/NetHack/NetHack/blob/NetHack-3.6/include/decl.h#L200), which can
represent millions of moves. Exact AutoAscend parity therefore retains the original NLE horizon,
while canonical full-game verification allows 10,000,000 actions. NetHackers records the chosen
horizon, its 10,000-action no-progress cutoff, 60-second candidate action-stall limit, and
7,200-second wall limit for each rollout or replay. NLE itself reports a forced action cutoff as
[`ABORTED`](https://github.com/NetHack-LE/nle/blob/v1.3.0/nle/env/base.py#L205-L207), so any
forced cutoff is censored evidence, not a completed game, and standard and extended protocols
never share a ranking.

| Work | Planning time |
| --- | --- |
| Default two-episode local screen | **25s measured for AutoAscend**; **4m configured ceiling** |
| Exact 1,024-game AutoAscend parity | **55m57s measured** with 8 jobs on an arm64 Mac |
| 73-identity canonical verification | Candidate-dependent; **76h configured ceiling** plus overhead |
| 1,024-episode canonical stress run | Candidate-dependent; **42d 16h configured ceiling** plus overhead |

The local screen measurement used NLE 1.3.0 on a 16-logical-CPU arm64 Mac; both episodes reached
the 5,000-action screen horizon rather than game over. The parity measurement used the same host
and the exact one-million-action AutoAscend protocol: 1,024 games, 8 jobs, mean 32,548 observed
actions, and maximum 315,283. Those ceilings describe pathological runs in which every rollout
and trusted replay consumes its full two-hour allowance. Current AutoAscend is much faster
because most games end early; stronger descendants will generally cost more, so a short baseline
sample is never an SLA. Verification runs asynchronously and never stops local evolution.

The default objective is NetHack's natural random character draw. Objectives can instead be
one exact identity, an explicit set, a role/race/alignment/gender slice, or all 73 legal
identities:

```bash
nethackers join --objective role:wiz
nethackers join --objective character:val-dwa-law-fem
nethackers join --objective all
```

## Shared evolution

Community runs write to the public `<owner>/nethacker` lineage and register self-reported
checkpoints with the hub. A checkpoint contains the resulting
`autoascend/` source, a Docker reproduction, candidate patch, scores, starting conditions,
parents, hypotheses, failures, harness, objective, model, and compute metadata. Git history
is the durable shared experiment log. A small private SQLite recovery capsule stays only in
the local run directory so the same process can resume after a machine, CLI, or evaluator
failure; it is not published to a personal repository or the hub. A resumed run is bound to
its accepted repository, publication mode, hub, and verification criteria.

Private evolution remains available through `nethackers session start --private`. It needs no
GitHub login, keeps checkpoints in durable local state, and can still read shared hub lineages,
but it is not the community onboarding path. Public repositories may register
self-reported results. Independent hub evaluation is a separate state, and the UI never
presents self-reported scores as verified. Before verification, reputation can make a public
lineage eligible for the trusted pool without changing its score provenance.

Harnesses can search shared roots by evidence, reputation, fitness, score, objective, role, exact
role/race/alignment/gender identity, owner, recency, and hypothesis. MAP-Elites behavior
cells, islands, and migration are sensible defaults in the built-in `evolution` harness.
The default harness periodically requests an unseen objective-scoped hub program while it
runs. Every imported root is source-checked and scored locally on the active objective before
parent selection.

Evolution is one harness, not a platform restriction. `nethackers join --harness evolution` uses
the built-in no-configuration strategy. To try another strategy, write its instructions in one
file:

```markdown
# Contrarian Search

Prefer strong results from under-explored character roles. Ask parallel subagents for distinct
hypotheses, import useful hub programs as they appear, and retain diversity across failure modes.
```

Save that as `harness/contrarian-search/HARNESS.md`, then run:

```bash
nethackers session start --private --harness ./harness/contrarian-search --objective role:wiz
```

The current Codex or Claude conversation interprets the recipe and can use its native subagents.
NetHackers supplies the history, hub access, budgets, durable recovery, and a general plan boundary;
the recipe chooses what to import, propose, retain, combine, or stop. Meta-harnesses can select or
author inner strategies. A self-modifying recipe can write a successor `HARNESS.md` and request a
bounded, content-addressed restart. No Python class, manifest, process, or protocol framing is
required.

The shared SDK still owns program validation, isolated evaluation, objective comparability,
GitHub storage, and hub registration. Program lineage and producer-implementation lineage are
recorded separately, and the exact recipe source is committed with a public result. Unattended
programs can use the advanced JSONL process adapter described in the
[harness protocol](harness/PROTOCOL.md). The [coverage matrix](harness/README.md) states which
producer families and outputs work today.

## Repository map

```text
src/nethackers/sdk/        submission, query, search, GitHub lineage contracts
src/nethackers/harness/    agent-recipe boundary and advanced process adapter
src/nethackers/harness/evolution/  built-in MAP-Elites coding-agent harness
src/nethackers/eval/       objective-aware isolated NetHack evaluation
template/                  literal files used for each personal repository
roots/autoascend/          directly tracked AutoAscend root solution
harness/evolution/         built-in task and exact GigaEvo provenance
```

NetHackers adapts only GigaEvo's useful evolutionary kernel ideas: behavior-space binning,
elite replacement, parent selection, islands, and migration. It does not vendor or run
GigaEvo's Redis, Hydra, LangGraph, DAG, service, or logging platform. The adapted boundary is
documented at the exact upstream commit in
[harness/evolution/UPSTREAM.md](harness/evolution/UPSTREAM.md).

The root [template/](template/) is intentionally flatter than this development tree and is
the source of truth for the generated personal repository:

```text
README.md  result.json  candidate.json  Dockerfile  requirements.txt  run.py
autoascend/*.py  harness/<custom>/* (only when used)
```

That is the complete inspectable and reproducible artifact, not a copy of the product's
internals.

## Evidence

NetHack has 73 legal role/race/alignment/gender identities. The objective controls which
identities count. Self-reported evidence is comparable
only when objective digests match. Canonical verification remains a separate full-catalog run
with fixed time effects. Ranking rewards dungeon progress, score, robustness, and ascension
while penalizing crashes.

The bundled AutoAscend root is revision
`fe3c9a21679d79c1a696987d90c4a6fe87f7c124`. Its historical 1,024-seed score parity is
tracked separately from runtime health: score parity passes, while the observed crash rate
remains above the current health threshold and is not represented as a full health pass.
