The forest graph

The right sidebar shows a small 3D forest instead of the d3 graph. Each published note is a plant, and each link is a root between two plants. The expand button opens the same forest full screen, with search and a note panel.

The design lives outside the vault, in docs/forest/ at the repo root. docs/forest/README.md is the map: what was built, the file list, and where the site differs from the original spec.

The forest shows only published notes

The GardenForest emitter builds public/static/garden.json from the content that Quartz has already filtered. A note that does not publish never reaches it.

  • A link to a note that exists but does not publish is dropped. Its name never appears in the forest.
  • A link to a note that exists nowhere becomes an unwritten seed (a ghost). Its title is the link text, which the published page already shows.
  • Names match after Unicode normalisation and without case, as in Obsidian.

So the forest adds no new exposure. The publish rules in publishing.md decide what the forest shows.

Growth is the stage

The plant type comes from the growth key: seedling, budding, potted, evergreen. See conventions.md for the ladder. A note without growth gets a stage from its links and word count, and the forest labels it “inferred”. The exporter never writes an inferred stage.

The layout state is a lockfile

.garden-state.json at the repo root holds where every plant stands. Vercel reads it and never writes it.

  1. Before a push, run npm run garden. It builds the site and writes the state.
  2. Commit .garden-state.json with the push.
  3. Never edit or delete it by hand. A missing state replants the whole forest.

The garden-publish-check skill does steps 1 and 2. A build that finds the committed state out of date prints a warning, and it never fails.

Within a month, plants that are already placed do not move. New notes grow around them. At the first run in a new month, the forest moves part of the way toward the current links.

Before you change it

ChangeRead first
Anything about the datadocs/forest/garden-json-spec.md, then quartz/garden/extract.ts
A layout rule or constantdocs/forest/README.md (the golden hash rule), then quartz/garden/layout.ts
The look or the controlsdocs/forest/garden-explorer.html (the prototype), then quartz/components/scripts/forest/

Run npm test after any change under quartz/garden/. A change to a layout rule changes every position. Update the golden hash in layout.test.ts on purpose, and replant the state in the same commit with npm run garden:replant.