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
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.
03 Logo
The logo is a lowercase n. It is a block of silver with one rounded shoulder and a thin slit cut upward from its base. It applies rule 1 to a letter, and it is drawn on the same grid as the plates of our projects, so the lab's mark and the project marks form one set.
Fig. 1Construction, in cells
Beforea star cut from a tile
Nowplate zero, section
The earlier star already followed rule 1, because it was cut out of a tile. We replaced it with a glyph because a glyph does not need a tile, stays legible at 16px, and is constructed the same way as the project plates.
Numberscells
- Em
- 6
- Corner
- 0.25
- Stem
- 2.5
- Shoulder, and its round
- 2.5
- Slit
- 0.5
- Slit, below 48px
- 1
Sizes32, 20, 16
The mark is 20px in the header, next to 14px labels. On a silver background it is cut out in null. We never make it the largest element on a screen, with one exception: the print at the top of this page.
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
The pagenull with 5% silver
Silverthe light
Table 1Roles: the colours a component may use
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
0123456789
& ? ! ( ) / ° ×
IBM Plex MonoSIL OFL 1.1
0123456789
c0011 0.735
2026-08-07T09:12Z06 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
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 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
Shape999px, 12px, 1px
A pill: a single line that names something, 28px high
- 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
Table 3Durations: point at a row to play it
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
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
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
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
Population 14, newest first
Log 7 lines, newest first, Rome time
- c0013 improve from c0011 on gpu 1
- c0011 improve search fitness 0.735
- c0012 improve from c0009 on gpu 0
- c0010 crossover search fitness 0.72
- c0009 improve search fitness 0.74 (new best)
- c0006 improve invalid: evaluator rejected output
- 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
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.
An experimental research harness for running coding agents through a sequence of experiments, evaluating their results, and keeping a record of what happened.
- 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.
- 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
Flint
Labloop
Plate
Savant
Remora
Amalgam
What Flint's plate representsread from plates.js
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 - Write the entry file. The chapters, the reading estimate and the citation are generated from it.
- Regenerate committed files with their scripts instead of editing them by hand.
- 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.
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