01 Null silver

We took three rules from the name. Null is our darkest colour and silver is our lightest. A cut into a page of pure null would be invisible, so the page is null mixed with 5% silver, and pure null is one step darker than the page.

1. Null is the cuta print, a tile

Where there is silver, we do not draw a mark on top of it. We cut the mark out of the silver, so a plate appears as a hole in its print or in a silver tile.

This rule applies only at larger sizes. Next to a title, in a README or as an icon, a plate at 16 to 32px is a solid glyph placed directly on the background, without a tile.

2. Null is a valueone treatment everywhere

Threshold
0.6
Final split
not read yet
Outcome
untested
GPU time
3.40 h
c0007debugc00060.710
c0006improvec0004invalid
c0003draftnone0.440

When a value is missing, its cell keeps its place and its label, but its background is cut away to null. The reason the value is missing is written in the cell in the dimmer text colour.

We use this for every kind of missing value: not read yet, untested, invalid, or none. A missing value is not an error and not a loading state, so nothing turns red and nothing animates.

3. Silver is halidePlate, in grain

Our images, which we call prints, are modelled on photographic film. Silver is laid on null as grain or through a screen, in two tones only, and the project's plate is the clear, unexposed area.

We leave out the usual film decoration: borders, sprocket holes and frame numbers.

02 Principles

Every page has a narrow margin and a wide column. The margin holds a key for each entry, such as a date, and the content sits in the column next to it. We use pills for names, sheets for anything larger, and thin lines to separate the values inside a sheet. The site is designed to be read at night, for more than a few seconds at a time.

Colours
2
Family
1
Weights
2
Sizes
5
Shapes
2
Curve
1

The margin holds only keys

The margin contains the mark, a date, a number, a time or the chapter index, and nothing else. All other content is placed in the column next to it, which extends to the far edge of the page.

Two shapes, one rule

A pill is a single line that names something. A sheet has a 12px corner and holds anything taller than one line. Inside a sheet, a 1px line separates the cells. We do not use borders or shadows.

Three depths, one light

There are three background levels: pure null, the page, and a sheet. We reserve solid silver for three things: the current page in the header, the main action on a view, and the best row in a table.

One typeface, two weights

We use one type family at two weights and five sizes. Body text is 17px at regular weight, in silver instead of white. We show hierarchy by switching between silver and a dimmer tone that we call clay, and never with bold or capitals.

Images are the lightest part

Prints and figures are lighter than the page around them. A print fades to dark before it reaches its own edge, so that an image does not put a hard bright edge on a dark page.

What is shown is true

Placeholder content is labelled as a placeholder, and an empty log is shown empty. We avoid any description that the data does not support.

We learned much of this from gentle.systems, in particular the margin, the column, and the use of pills for names.

04 Colour

We use two colours, null and silver. Every other value is either null with a little silver mixed in or one of the two at reduced opacity, and each value has a single job. The numbers below are measured from the stylesheet in your browser when the page loads.

Nullthe cut

Cuts: a plate inside a print, and any missing value

The pagenull with 5% silver

The page background. Text is set directly on it

Silverthe light

Text and lines. A solid fill only for the current page, the main action and the best row

Table 1Roles: the colours a component may use

Role Used for Token Composite Contrast
Ink Text, lines and marks, in full silver ink not read yet not read yet
Clay Secondary text: captions, notes and cell labels clay not read yet not read yet
Page The page background: null with 5% silver paper not read yet none
Void Cuts and missing values: pure null void not read yet none
Clay on void The reason a value is missing on-void not read yet not read yet
Fill Pills and sheets at rest fill not read yet none
Clay on fill Labels inside a sheet clay not read yet not read yet
Stock The background of a figure or a plate stock not read yet none
Clay on stock Axis labels and captions inside a figure clay not read yet not read yet
Line The 1px line between ruled cells, never used for text line not read yet none
Silver Solid fills: the current page in the header, the main action, the best row silver not read yet none
On silver Text on silver, in null on-silver not read yet not read yet
Clay on silver Secondary text on silver on-silver-clay not read yet not read yet

Contrast is measured against the background each role is used on. Clay is the dimmest value we use for text, and line and wash are never used for text. Silver on the page has a contrast of 13.2:1, compared with 21:1 for white on black.

On paperthe same roles, remapped with one attribute

Labloop

specimen-w0a search still running

Best, search split
0.74
Final split
not read yet
Threshold
0.6
Outcome
untested

In words

In the light version the page becomes off-white, silver becomes the background of a figure, and solid fills become null. A missing value is shown in white, the only tone lighter than the page, just as null is the only tone darker than the page in the dark version.

No component changes for the light version. Each role above is given a second value under data-tone="paper" in tokens.css. Prints do not change either, and stay silver on null. The light version is a proof of concept that we have not tuned yet.

05 Type

We set everything in Satoshi. Large text uses the light weight and small text the regular weight, and we do not use bold, capitals or letterspaced labels. There are five sizes. The smallest is the only monospaced one, and we use it only for code and for columns of numbers that need to line up.

44 / 300

Independent research, in the open.

22 / 300

Nullsilver is a research initiative based in Italy, focused on language models and the systems around them.

17 / 400

Failed and invalid experiments remain in the record, together with their configurations and outcomes. The intention is to preserve what actually happened, rather than only the attempts that worked.

14 / 400

Labloop: a research harness for coding agents. Artifacts, released, 1 min.

13 mono

0.740 0.735 0.720 0.690

The five sizes are display, statement, read, label and code. Display and statement shrink on a phone, to 34 and 19px, and the other three stay the same. Read and label are each one pixel larger than we would use on a light page, because light text on a dark background looks smaller than it is.

SatoshiFontshare Free Font License

ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789
& ? ! ( ) / ° ×

IBM Plex MonoSIL OFL 1.1

0123456789
c0011  0.735
2026-08-07T09:12Z

06 Space and shape

The page has a 20px edge, a 104px margin, and then eleven columns that run to the far edge. A single 6px gap separates a pill from the content below it, and one column from the next. There are two shapes, a pill for a name and a 12px corner for anything taller, and one kind of line, 1px wide, between the cells of a sheet.

The gridthe chapter index on the left is in the margin

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11

The margin is exactly as wide as the widest thing it holds, which is a date in a pill. Running text is limited to about 68 characters per line. Entries, figures, tables and prints are laid out on the columns.

Table 2Space

6Gapbetween a pill and its content, and between columns
12Padinside a pill and a cell
18Sheet padabove and below the text in a sheet
24Blockbetween the blocks of an entry
64Entrybetween entries
112Sectionbetween chapters

Shape999px, 12px, 1px

A pill: a single line that names something, 28px high

A sheet: anything taller12px corner, 18px above and below
A ruled cell
one value
Beside it
no value

A table row is a 34px line inside a sheet. That is the height of a pill plus one gap, so a table has the same rhythm as a stack of pills. We do not use any other corner radius.

07 Motion

All motion uses one easing curve, which only decelerates. A silver highlight appears quickly and fades slowly, an arrow moves by 2.5px, and a print fades in once when it is first drawn. Nothing loops. If you have asked your system for reduced motion, everything is shown in its final state immediately.

Fig. 2The curve

cubic-bezier(0.22, 0.61, 0.24, 1)

Table 3Durations: point at a row to play it

160 msIna highlight or an underline appearing
420 msMovean arrow moving, a print fading in
520 msOuta highlight or an underline fading

We animate only colour and transform, and never layout.

Under the header

Content that scrolls under the header is blurred in five stacked steps, each one stronger and closer to the top of the screen. The content is blurred but not faded out, and the pills in the header stay opaque.

08 Controls

We choose a component by asking what the content is. A name or a command is a pill. A value that belongs to a set is a cell in a ruled sheet, and the cell is cut to null when the value is missing. A destination is a plain link. Everything else is plain text on the page. No component changes shape when you point at it.

A pilla name, or a command

Lab log

Searching

Labloop README.md Read the entry

A pill is a single line that names the content next to it or below it, or it is a button. A straight arrow means the link stays on this site, and a slanted arrow means it leaves. The main action on a view is solid silver. When a pill is only slightly wider than its text, like the date above, the text is centred. When it has 24px or more to spare, like the pill under the date, the text starts at the left.

A ruled cella value in a set

Kind
Artifacts
Status
Released
13:42c0013 launched
12:58c0009, new best
12:02c0006 invalid

We use ruled cells for the facts of an entry, the rows of a table and the lines of a log. The cells share one sheet and are separated by 1px lines. The most important row is filled with solid silver.

A plain linka way somewhere

A link inside a sentence is already underlined.

We use plain links in the chapter index, in the footer and inside sentences. When you point at a link it gains an underline, and it never turns into a pill. In the chapter index, the chapter that is on screen is shown in silver, together with its part of the line next to the index.

Nothing

Running text, captions and notes.

Text on the page does not need a container.

A pill's statesfixed, for reference

Rest

Pointer over

Keyboard focus

Unavailable

The pointer state is shown only to a pointer that can hover. On a touch screen a pill, a link or a row does not change when it is tapped, so nothing stays highlighted after the tap.

A link's statesfixed, for reference

RestResearch
Pointer overResearch
Keyboard focusResearch
In an index, another chapterResearch
In an index, this chapterResearch

09 Data

We show data as a summary of the key numbers, followed by a figure and its table. The table is the full record, and the plot is one view of it. Figures are drawn in silver on the lightest sheet. The main result is in full silver, other measurements are dimmed, and different kinds of marks have different shapes. A value that does not exist yet is cut to null in the summary, in the table and on the plot.

Searching

specimen-w0 last written
Candidates
12 / 14
settled / launched
Best, search split
0.74
c0009
Final split
not read yet
one read, after the search
Threshold
0.6
fixed before the search
Outcome
claim untested
the search is running
GPU time
3.40 h
across every slot

Fig. S1 Search fitness, in launch order c0009, improve, 0.74, best

0.20.40.60.8threshold 0.6unreadfinalc0000c0004c0008c0012 0.20.40.60.8threshold 0.6not read yetfinalc0000c0002c0004c0006c0008c0010c0012
Search fitness is what the loop steers by, so it is optimistic by construction. The claim rests on the one read of the final split, made after the search stopped.

Population 14, newest first

Candidate Operator Parents State Fitness
c0013 improve c0011 running not yet
c0012 improve c0009 running not yet
c0011 improve c0009 completed 0.735
c0010 crossover c0009, c0005 completed 0.72 
c0009 improve c0007 completed 0.74 
c0008 improve c0007 completed 0.69 
c0007 debug c0006 completed 0.71 
c0006 improve c0004 invalid none
c0005 crossover c0002, c0004 completed 0.63 
c0004 improve c0002 completed 0.66 
c0003 draft none completed 0.44 
c0002 draft none completed 0.61 
c0001 draft none completed 0.48 
c0000 baseline none completed 0.21 

Log 7 lines, newest first, Rome time

  1. c0013 improve from c0011 on gpu 1
  2. c0011 improve search fitness 0.735
  3. c0012 improve from c0009 on gpu 0
  4. c0010 crossover search fitness 0.72
  5. c0009 improve search fitness 0.74 (new best)
  6. c0006 improve invalid: evaluator rejected output
  7. campaign specimen-w0 started: 2 slot(s)

This example shows a search that is still running, before its final split has been read. The campaign is a placeholder that we made up for this page, and none of its numbers are results. The value in the figure's pill follows your pointer and returns to the best candidate when the pointer leaves, so the plot does not need a tooltip. The square indicator next to a running search is lit but does not blink, because a search that has stalled should not look busy.

This table is the record that the plot is drawn from. The best row is filled with solid silver. Fitness is the only monospaced column, because its numbers need to line up.

Lab logplaceholder rows

No entriesThe log stays empty until there is something that can be checked.

Each line has its date in the first column, a short description next to it and its time at the end. Lines are listed newest first, in Rome time. A line that leads somewhere is a link: its text is underlined when you point at it, and the row does not change shape. Below the example is the log as it is today. It is empty, so it is shown as a cut to null.

10 Entries

An entry has its date in the margin and its content in the column. The title is a pill that includes the project's plate, placed above the project's print. Next to it, under a link to the source document, a single sheet gives a one-sentence description, followed by the entry's kind, status and reading time.

Labloop

An experimental research harness for running coding agents through a sequence of experiments, evaluating their results, and keeping a record of what happened.

README.md
What it is
A research harness for coding agents
Kind
Artifacts
Status
Released
Reading
1 min

This is how an entry appears in the feed. The title and the print are a single link, so pointing at either one turns the title silver. The facts are not links, so they are not pills and they do not respond to the pointer.

A draftan example, not on the site

What it is
no summary yet
Kind
Research
Status
Draft
Reading
not yet

An entry that has no text yet has no reading time, so that cell is cut to null like any other missing value.

Flint
What it is
Compressing reasoning without breaking it
Kind
Research
Status
Earlier work

On a section page the same parts are stacked as a card: the title, the print and the sheet of facts.

11 Plates

A plate is a project's mark. It is one heavy, solid shape on a grid six cells wide, and it is based on how the project works instead of on its name. We construct plates in two ways. Flint and Labloop are outlines drawn around weighted points. Plate, Remora, Savant and Amalgam are bands wrapped around poles on the same grid, following Armin Hofmann's study of connected circles. The descriptions of Savant, Amalgam and Labloop were written by their designer and have not been signed off yet.

Fig. 3Flint, with its construction

2.53.52.50.53Unmarked weights 0.25. Lengths in cells.
A weight is a point with a radius, and a hull is the outline tangent to a group of weights. The figure is drawn from the same numbers as the mark.

Flint

Labloop

Plate

Savant

Remora

Amalgam

What Flint's plate representsread from plates.js

MechanismA model is fine-tuned on its own reasoning traces after they are compressed section by section: the computation is kept word for word, the narration around it is pressed down, and the answer does not change.
AsymmetryTwo kinds of text leave the same trace at the same length. One keeps its full weight to the end; the other is pressed to a sliver, and is still there.
GrammarOne root, two arms of equal reach: a bar that holds its weight, and under it a wedge that runs down to a thread.
Seededthe bar’s weight, the root’s width

These lines are read from the plate's own source file when the marks are generated, so this page cannot drift from the plate itself.

One entry pointplate.js

function plate(name, opts) {
  if (!name) return Logo.svg(opts);
  return Plates.svg(name, opts);
}

A page asks for a plate by name, and a print asks for the same name. Both requests go through this one function. No page depends on the outline of a particular plate, so redrawing a plate means changing one file.

Plates at small sizes

Each plate above is shown large, at 32px and at 16px, in silver on the background. Below 28px we use a coarser drawing, in which thin threads and slots are widened to a whole cell.

12 Prints

We use prints where another site would use photographs. A print is made the way a photogram is: the plate is placed on the sheet and light is let in around it. The result is silver, as grain or through a screen, that is densest at the edge of the plate and fades out before the edge of the sheet. The plate itself is left clear.

1. The plate

2. Out of focusenlarged, rotated

3. Through a screendot, enlarged 6 times

4. Exposed around the plate

We start with the project's plate, enlarged beyond the frame and blurred. This gives the background field. A screen then reduces the field to two tones. The dot screen uses a grid rotated by 30°, which is the only number we kept from the earlier mark.

Inside the outline of the plate, silver and null are swapped. Because the plate was lying in full light, the area inside it ends up as null.

GrainPlate

Line screenSavant

Dot screenFlint

Grain has no grid. The tone depends on how densely the grain is laid.

The line screen is an engraved line at 30°. Its width follows the tone beneath it.

The dot screen is a halftone on the rotated grid.

Where we use prints

We use prints in the feed, on entry cards, and at the top of a README or a paper. We never use them as a background for text, and never in the footer.

What changed

An earlier draft had five screens and a mid-grey tint. We kept three screens and two tones. We removed the mosaic screen because on a dark page it looked like a terminal.

One callprints.js

NullsilverPrints.draw(
  canvas, 'flint', { tone: 'null' })

13 Reading

Reading is what the site is for. Body text is 17px at regular weight, with about 68 characters per line and a line height of 1.62, set in silver directly on the page. The chapter index in the margin of this page is the same component that entries use. Citations are generated from each entry's title and date.

Labloop: a research harness for coding agentsfrom the entry

Coding agents can write and run experiments, but this alone is not enough to conduct a research campaign: someone still needs to decide which experiments to try next, enforce resource limits, and ensure that the results are evaluated consistently. Labloop provides the tooling around the agent to handle these tasks.

Crucially, a good result during the search is not sufficient to support a research claim. Since these scores are used to decide which candidates to pursue, they are optimistic by construction. At the end of the campaign, the selected candidate is therefore evaluated once on a separate final split, and the result is compared against the threshold fixed before the search began.

Failed and invalid experiments remain in the record, together with their configurations and outcomes.

The intention is to preserve what actually happened, rather than only the attempts that worked. Labloop is still experimental. The README on GitHub describes the setup and operation in full.

Rendered Markdowncode, a table, a list

kind: Artifacts
status: Released
date: 2026-06-28
SkillWhat it regenerates
/add-writingOne entry file
/sync-markssrc/lib/marks/
/sync-readmessrc/lib/content/readmes/
  1. Write the entry file. The chapters, the reading estimate and the citation are generated from it.
  2. Regenerate committed files with their scripts instead of editing them by hand.
  3. Read the diff. If a plate changed and its generator did not, report it instead of committing it.

CitationPlease cite this work as

Nullsilver, “Labloop: a research harness for coding agents”, nullsilver.com, Aug 2026.

@misc{nullsilver2026labloop,
  author = {Nullsilver},
  title  = {Labloop: a research harness for coding agents},
  year   = {2026},
  month  = aug,
  url    = {https://nullsilver.com/artifacts/labloop}
}

14 Header and footer

The header has the mark in the margin and a row of pills aligned to the page's columns. The pill for the current page is solid silver. The footer is laid out as the last entry on the page, with a key in the margin and four ruled cells. Both are the live components on this page.

The header's pills, at actual sizenot interactive

The first row shows the header at rest. The second shows it on the Artifacts page with the pointer over About, and the third on the Research page with keyboard focus on About. The pill for the current page is solid silver. When you point at another pill it becomes one step lighter and its arrow appears. The last pill is the main action. It is two columns wide and always shows its arrow, so when you point at it, it turns silver the way a title pill does. On a small phone the four pills share the row, each only slightly wider than its text, so their text is centred.

Mark
20px
in the margin
Header
52px
56 on a phone
Pill
28px
32 on a phone
Margin
104px
a date in a pill
Page edge
20px
12 on a phone
Under the header
5 blurs
1.5 to 32px, no fade

15 Elsewhere

We use the same parts outside the site, without adding anything. A paper uses the light version and keeps its section numbers in the margin. A README opens with a print, followed by a table whose first column plays the role of the margin. An icon is a plate: the lab's own mark for the lab, and a project's plate for that project, drawn solid with no tile behind it.

A paperfirst page

2026

Flint: compressing reasoning without breaking it

Author

Marco De Santis

Abstract

A study on whether reasoning models can learn from compressed versions of their own outputs, reducing the tokens they use without losing the steps needed to solve a problem.

Pl. 01

1

Reasoning models often generate long traces before producing a final answer.

A READMEgithub.com/nullsilver-labs/labloop

Labloop

An experimental research harness for running coding agents through a sequence of experiments.

KindArtifacts
StatusReleased, 07 Aug 2026
SessionsClaude Code

On GitHub the ruled rows become a two-column Markdown table, and the print and the plate are PNG files of the kind that Plate, our generator, already produces.

An icon64, 32, 16

Next to a titlea solid glyph, no tile

Flint

Labloop

Plate