The harness that won the first ARC-AGI-3 milestone runs a 27B open weight model, gives it a Python prompt instead of a game controller, and scored 1.21% on the official Kaggle leaderboard. Its own authors measured the same submission scoring as low as 0.77% on another run, and 1.6% on the public games with a standard deviation of 0.45.
Those are small numbers for a winning entry, and they are the honest ones. Tufa Labs published the full write-up, the notebook, the code and the run directory, so the Duck harness can be read rather than admired. Here is what it does, line by line where it matters.
What the Duck harness runs on, and under what limits
The base model is Qwen 3.6 27B at FP8, served with vLLM. The write-up is explicit that the choice was forced by the competition rather than preferred: Kaggle “provides a RTX Pro 6000 GPU with 96 GB of VRAM and 9 hours of runtime to play 110 games in any order”, so the design targets “open-source models that fit the VRAM constraint”. No internet at scoring time means no frontier API, and the competition rules require the whole thing to be open sourced; the code dataset is MIT and the notebook Apache 2.0, per the authors’ reply in the thread.
Three design principles follow, in their words: open models that fit, “generic ARC-AGI-3 problem solving” with nothing about the training games encoded in the harness, and “a lightweight harness, that still attempts to utilize the underlying model’s capabilities as much as possible”. The last one is the interesting choice. The model is kept “in the driver seat”, and the harness is built to be replaced under a stronger model rather than to compensate for a weaker one.
The lineage is stated too. The Duck succeeds Stochastic Goose, which won the agent preview competition, and borrows from two published approaches: Symbolica’s ARCgentica, which “achieved a score of 36% the day after the release of the public official games” using recursive self calls on frontier models, and the RGB Agent, which wrapped a generic coding harness, OpenCode, around the model and stored the game history in a log the agent could grep.
How the Duck harness exposes a game as Python variables
The core idea is that the model never presses a key. It writes Python, and the Python presses keys.
The game state lives in a REPL as pre loaded variables. current_frame holds the latest board, with .ascii for the grid and .segmentation for its connected components. previous_frame holds the one before. history pairs each past .action with its .frame; transitions lists state, action, state triples; and last_transition, last_action and last_action_result give the most recent step without searching. valid_actions says what is legal, and an action() function executes one or several moves, which lets the model act “in the loop or while tracking an object”.
The tool that runs the code has limits chosen for a model, not a person: “a maximum time limit of 30 seconds and maximum output size of 4096 characters”, and “the REPL environment is reset between every toolcall”. Actions get natural names, UP, DOWN, LEFT, RIGHT, SPACE, MOUSE and RESET. UNDO is deliberately withheld: “the model fails to use it efficiently: it undoes big batches of actions that wastes energy”. The write-up carries a warning worth repeating: the REPL “is not fully isolated” and running the harness “can lead to arbitrary code execution”.
That is the mechanism our smallest REPL experiment copied: one model call, a policy in Python, an engine that runs it at thousands of actions a second. What the Duck adds is everything around it.
How the Duck harness sees the board
Perception is three things at once. Every turn, “a 4× upscaled image of the board is injected into its context”, because “Qwen’s encoder processes images in 16×16 pixel patches” and the upscale “gives the model the best visual understanding of the scene”. The ASCII grid is there for detail. And a segmentation tool locates “the 4-connected components in pixel space, denoting adjacency and child-parent relationship between the nodes”, because a common failure was the model printing the whole grid and polluting its own context.
Two things they tried and dropped are as informative as what stayed. More frames or video animations did not help, since “small models struggle with extracting details and acting on them”, with the stated consequence that the agent does not see animation feedback that matters in games like sb26 and tn36. And hand built tools made things worse: “Against our intuition, hand-crafting specific tools for the model did not help, as it seems to hinder the creative abilities of the model.”
The image finding matches what one measured pair showed on this stack: a picture of the board costs a fraction of the hex grid to read.
What the Duck harness scores, and how much that varies
On the 25 public games, 20 tries each, the mean is “1.6002 (+/- 0.4475)”. Performance is “rather uneven, with some games being solved consistently for over 40% of the levels, while for some not even the first level is solved”. The official leaderboard figure is 1.21%, after a 1.30% result “was retracted by Kaggle”, and the authors report “a large variance in scores for the same submission”, with a best submission scoring as low as 0.77%.
Read that against the scoring and it makes sense. A per level score is the squared ratio of human to agent actions, weighted towards later levels and capped by levels completed. An agent that clears early levels at several times the human’s move count, and rarely reaches the later ones, lands in single digits however clever it is. The variance is the same effect every single run on a local reasoning model shows, multiplied across a hundred games.
The Tufa Labs blog post of 1 July adds the cost comparison: running frontier models inside the same harness, they describe it as “an order of magnitude cheaper on each game” than a competing executable world model agent on GPT 5.4. The harness works with API keys as well as vLLM, so the comparison is the same code with a different brain.
What to take from the Duck harness for a local stack
Three things, each of which the write-up states directly.
Let the model write code rather than choose keys. The Python tool is the whole interface, and it turns a model that is slow per move into one that is fast per game, which is the economics this hardware needs.
Give it a picture and a segmentation, not a wall of digits. The upscaled image every turn and the connected components tool are the two perception choices that survived; dumping full boards into context was the failure they were built against.
Expect to write a lot of prompt. The discussion section is candid that “we had to encode a lot of specific knowledge into the prompts”, steering the model away from treating an energy bar as the goal, from hallucinating “classical game sprites, like robots”, and from solving the board as an Atari game. The harness is lightweight; the system prompt is not.
And take the number seriously. A 27B model on a single GPU, with the best open harness anyone has published, scores between one and two per cent on the benchmark’s own metric. That is the current state of the art for a local model that plays, and the context eviction that lets it keep playing at all is the part of the design most worth understanding next.
