1. readsthis repo's live issues and PRs
  2. becomesactivity + recency → mass; references bind items
  3. writes--w--field-attention
  4. you seeactive work reads heavy; referenced items move together; the cycle fills like a vessel

No canvas is drawn here — the field is invisible; these variables are its only output. Without it you would build: a priority field, a linked-issues query, and a sprint board.

field-ui · invisible fields · backlog

Work has weight.

This one is the repo measuring itself: the 57 most recent work items from field-ui's own repository — the issues and pull requests that built the engine rendering this page. A tracker flattens them into identical rows; here each item is a body, and its mass is a blend of activity (discussion) and freshness (how recently it was touched). Heavier items read darker, heavier, more anchored.

Work also binds: when an item references another, hovering it threads back to what it builds on — across lanes. The board has two: In flight and Shipped, and the shipping cycle has visible capacity — everything closed or merged in the 14 days before the snapshot accretes into the bar that heads the Shipped lane. Switch the weighting and watch each lane re-settle; toggle the field off and it collapses to a plain tracker. And the cards drag — pick one up and triage the board by hand. It's a local sandbox: the arrangement saves in your browser, and GitHub is never written.

Field
Weight by

size = activity, comment-leaning — the items people argue about carry the mass · color = kind — teal pull requests, blue issues

drag to triage — local only, GitHub unchanged

Draggable work item. Press Space or Enter to lift the card, then arrow keys to move it: up and down within the lane, left and right across lanes. Press Space or Enter again to drop, or Escape to cancel. Rearranging is a local triage sandbox — GitHub is not modified.

In flight 3

  1. #294 PR feat: scrollV CSS property, quality governor, evidence accretion reveal 6 comments · zachshallbetter · within the hour
  2. #257 issue Contour/vector typography: text → glyph outlines → bound SVG/Canvas representation 0 comments · zachshallbetter · 33h ago
  3. #228 issue Phase 5: migrate legacy core/field.ts element write-back behind platform registries 0 comments · zachshallbetter · 2d ago

Shipped 54

this cycle: 54/20 shipped the 14 days before the snapshot ran 2.7× the stated capacity
  1. #293 PR merged feat: FieldHandle diagnostics, packaging checks, DataConsole perf panel, observable surface docs 2 comments · zachshallbetter · 4h ago
  2. #292 PR merged feat(site): atom card close button + fix all 132 particle link targets 2 comments · zachshallbetter · 5h ago
  3. #279 PR merged feat(elements): Custom Elements Manifest for the field-ui web components 3 comments · zachshallbetter · 18h ago
  4. #291 PR merged feat(home): atom inspect — dwell-to-focus a particle, click to open (no auto-tooltip) 2 comments · zachshallbetter · 5h ago
  5. #290 PR merged perf(site): cache the project atoms in IndexedDB (localStorage fallback) 2 comments · zachshallbetter · 5h ago
  6. #288 PR merged feat(site): evidence — a colour lens (a second visual channel from the engine) 2 comments · zachshallbetter · 5h ago
  7. #289 PR merged feat: particles carry data — the home field is seeded with the 132 project atoms 2 comments · zachshallbetter · 5h ago
  8. #287 PR merged feat(site): Evidence Field — controls + legend so the uniqueness is clear 2 comments · zachshallbetter · 6h ago
  9. #286 PR merged docs(site): CDN hero, @fundamental-engine/vanilla as default door, demote kit 2 comments · zachshallbetter · 6h ago
  10. #282 PR merged feat(site): home 'Gallery' chapter — a live bench of what the field can do 2 comments · zachshallbetter · 6h ago
  11. #284 PR merged feat(site): /evidence — the Evidence Field (field-ui, no particles, real OpenAlex data) 2 comments · zachshallbetter · 6h ago
  12. #285 PR merged docs: coherence pass for @fundamental-engine/core, kit, and CI provenance release 2 comments · zachshallbetter · 6h ago
  13. #281 PR merged docs+release: expand adapter READMEs, add provenance workflow (0.2.2) 2 comments · zachshallbetter · 19h ago
  14. #280 PR merged feat(site): hero → @fundamental-engine/elements + @fundamental-engine/kit on the install grid 2 comments · zachshallbetter · 19h ago
  15. #278 PR merged Scope core as @fundamental-engine/core, publish 0.2.1, add @fundamental-engine/kit umbrella 2 comments · zachshallbetter · 19h ago
  16. #277 PR merged fix(site): install + version-posture coherence; resolve web-platform citations 2 comments · zachshallbetter · 19h ago
  17. #276 PR merged docs: honesty + accuracy pass (perf measured, paper review wording, contract delimiter) 2 comments · zachshallbetter · 20h ago
  18. #275 PR merged refactor(site): centralize the Field Manual chrome into shared components 2 comments · zachshallbetter · 20h ago
  19. #274 PR merged feat(site): foundation fields + Body Interaction Model below the home substrate 2 comments · zachshallbetter · 23h ago
  20. #273 PR merged fix(site): remove the broken StartHereLede container from the home 2 comments · zachshallbetter · 24h ago
  21. #272 PR merged feat(site): eli5 — Body interaction model section (interactive sink/accretion) 2 comments · zachshallbetter · 24h ago
  22. #271 PR merged feat(site): eli5 ch.II — Natural Field names + per-field visual grammar 2 comments · zachshallbetter · 24h ago
  23. #269 PR merged feat(site): recipes hub + per-recipe pages with live previews (Phase 1) 2 comments · zachshallbetter · 24h ago
  24. #268 PR merged refactor(recipes): rename tiers to a complexity ladder (applied/systems/operational) 2 comments · zachshallbetter · 27h ago
  25. #267 PR merged docs: rebuild forces-engine.md against current main 2 comments · zachshallbetter · 27h ago
  26. #266 PR merged feat: Field Surfaces — render the field over & under content (setOverlay API) 2 comments · zachshallbetter · 28h ago
  27. #265 PR merged feat(site): eli5 four forces play OVER + UNDER the content (immersive) 2 comments · zachshallbetter · 28h ago
  28. #262 PR merged fix: catalog field:relocated + correct stale 34→35 force count 2 comments · zachshallbetter · 28h ago
  29. #261 PR merged docs/site: align terminology with the Field Agent Consumption Model 2 comments · zachshallbetter · 28h ago
  30. #258 PR merged feat(site): refactor /eli5 into a story that builds (Substrate-style) 2 comments · zachshallbetter · 28h ago
  31. #283 PR merged fix(site): hero → @fundamental-engine/kit, dynamic footer version, document the kit 1 comments · zachshallbetter · 7h ago
  32. #254 PR merged docs/site: api/options shows required host; drop dead study metric keys 2 comments · zachshallbetter · 30h ago
  33. #252 PR merged fix: risk supplied-only (#226) + memory classification guard (#227) 2 comments · zachshallbetter · 30h ago
  34. #245 PR merged docs(writings): add "field-ui, explained simply" — the plain-language tour 2 comments · zachshallbetter · 30h ago
  35. #251 PR merged feat(site): add /eli5 — a playful second homepage (ELI5 narrative) 2 comments · zachshallbetter · 30h ago
  36. #270 PR merged feat(recipes): generated local datafile of the recipe catalog (data/recipes.json) 1 comments · zachshallbetter · 24h ago
  37. #264 PR merged feat(site): make eli5 ch.II four forces interactive on the main field 1 comments · zachshallbetter · 28h ago
  38. #263 PR merged docs: force count 34→35 in Paper 1 (+ site copy); tighten inspect floor 1 comments · zachshallbetter · 28h ago
  39. #222 PR merged fix(platform): compute real relationship resolution (stop hardcoding relResolved = relTotal) 1 comments · zachshallbetter · 30h ago
  40. #223 PR merged fix(core): classify memory as a semantic metric, not a physical natural force 1 comments · zachshallbetter · 30h ago
  41. #239 PR merged fix: unbreak main — @fundamental-engine/core in research papers + HomeHero metric claim 1 comments · zachshallbetter · 30h ago
  42. #220 PR merged fix(platform): never fabricate confidence from relationship presence 1 comments · zachshallbetter · 30h ago
  43. #244 PR merged feat(site): /writings datastore section — mermaid, latex, code; research migrates in 1 comments · zachshallbetter · 30h ago
  44. #229 PR merged feat(site): Wave 2 — /docs/narrative on the data-attribute model + FieldLoopDemo render fix 1 comments · zachshallbetter · 30h ago
  45. #234 PR merged fix(site): diagnostics export reflects active mode; snapshots is a reference table 1 comments · zachshallbetter · 30h ago
  46. #240 PR merged feat(site): publish the field-ui research paper family at /research 1 comments · zachshallbetter · 30h ago
  47. #241 PR merged feat(site): render research-paper math with KaTeX 1 comments · zachshallbetter · 30h ago
  48. #250 issue closed docs/site: study mappers pass undeclared metrics + RenderLayer particles-vs-dots naming (low) 0 comments · zachshallbetter · 34h ago
  49. #249 issue closed docs/site: api/options FieldOptions table omits host (required) + feedbackSink 0 comments · zachshallbetter · 34h ago
  50. #248 issue closed docs: interaction-and-relationship agent-type union vs FieldAgentKind (precision) 0 comments · zachshallbetter · 34h ago
  51. #247 issue closed docs: authoring-and-recipes has fabricated tokens + incomplete schema (§4/§5/§7/§10) 0 comments · zachshallbetter · 34h ago
  52. #246 issue closed docs: visualization-methods-taxonomy render-mode table is stale (lists nonexistent modes) 0 comments · zachshallbetter · 34h ago
  53. #227 issue closed decision: memory passport family axis (natural vs extended vs new metric value) 0 comments · zachshallbetter · 34h ago
  54. #226 issue closed fix(platform): risk metric defaults to 0 (same anti-pattern as the confidence default) 0 comments · zachshallbetter · 34h ago

How it's built

Every work item is an ordinary <li> with a few data attributes — the GitHub API response, flattened into markup. field-ui runs an invisible field over the list and the type carries the measurement: activity as weight, kind as color, references as hover threads. No canvas, no chart library. Two live channels ride on top: the page's hidden engine writes --d (local particle density) to every data-hot card each frame, and the scoped recipe's attention lane writes an eased --field-attention — CSS turns both into a felt glow and lift, and both go quiet when the field is off. Each card also declares its updatedAt as data-field-at, so the pipeline's recency lane is grounded in the data's own timestamp — --field-recency is freshness(updatedAt, now), decaying against the real clock rather than inferred from interaction. The drag is hand-rolled pointer events — no library, no HTML5 drag-and-drop — and it's a local triage sandbox: the arrangement persists to localStorage, and GitHub is never written.

1 — each work item is a field body

HTML
<li
  id="wi-294"
  data-body="attract"
  data-strength="1.42"
  data-feedback
  data-hot
  data-act="0.91" data-rec="0.99"
  data-field-at="2026-06-09T22:41:00Z"
  data-field-halflife="86400000"
  data-refs="wi-282 wi-269"
  style="--w: 0.94; --cat: #2dd4bf;"
>
  <!-- #number · kind · title · author -->
</li>

<!-- data-rec is the snapshot's freshness —
     freshness(updatedAt, snapshot, 24h), the
     @fundamental-engine/core temporal kernel. data-field-at
     declares the same updatedAt as WORLD TIME, so
     the platform's recency lane is grounded in the
     data: --field-recency = freshness(at, now). -->
  • data-act / data-rec — the normalized signals the lenses re-blend (data-rec is the freshness() kernel over updatedAt, half-life 24h)
  • data-field-at — the declared world timestamp; the platform grounds its recency lane in it (--field-recency)
  • data-refs — the items this one references (the hover threads)
  • data-strength — gravitational mass from the blended weight
  • data-hot — opts into the live density gather: hover and --d climbs toward 1

2 — the cycle bar's two honest channels

CSS
/* the cycle bar is a real sink body that also
   declares itself as its own measurement:
   <div id="wl-cycle" data-body="sink" data-absorb
        data-max="8" data-feedback data-hot
        data-field-visual-for="#wl-cycle"
        data-field-visual-role="measurement">

   channel 1 — data arithmetic: the FILL is
   shipped ÷ capacity from closedAt dates. */
width: 100%;  /* 54/20 this cycle */

/* channel 2 — the live engine: --load (0..1) as
   particles accrete into the sink, blended with
   --live (the engine's local density, --d). */
box-shadow: 0 0
  calc((var(--load, 0) + var(--live) * 0.5) * 22px)
  color-mix(in srgb, var(--accent)
    calc(var(--load, 0) * 40% + var(--live) * 20%),
    transparent);

Two channels, kept honest: the fill is static math over the snapshot's closedAt dates; the glow is the live engine — --load from a real sink body, blended with the local density --d. The bar also names itself as a measurement visual (data-field-visual-for), so its provenance is declared, not implied.

3 — CSS reads the weight and the live channels

CSS
.wl-title {
  font-variation-settings:
    'wght' calc(380 + var(--w) * 360);
}
.wl-item {
  /* --d: the engine's live local density,
     written every frame; it gathers toward 1
     when a data-hot card is hovered/focused.
     --field-attention: the scoped recipe's
     eased attention lane (hover/focus +
     viewport-center proximity + visibility). */
  --live: var(--d, 0);
  box-shadow: 0 0 calc(var(--live) * 16px) -6px
    color-mix(in srgb, var(--cat)
      calc(var(--live) * 55%), transparent);
  background: color-mix(in srgb, var(--text)
    calc(1.5% + var(--w) * 4% + var(--live) * 4%
      + var(--field-attention, 0) * 4%),
    transparent);
}

Switching the lens re-blends --w from data-act and data-rec, then FLIP re-sorts each lane so the reflow is felt, not cut — on the current arrangement, so re-sorting a hand-triaged lane re-orders it; the lens always wins the order. The glow and lift read --d and --field-attention — both written by the running field, both zeroed when it's off.

4 — the drag is pointer events, by hand

TS
// hand-rolled pointer drag — no library, no HTML5 DnD.
card.addEventListener("pointerdown", (e) => {
  if (e.target.closest("a")) return; // links still click
  pend(e); // arms only after 6px of travel
});
function lift(card, e) { // past the threshold
  card.setPointerCapture(e.pointerId);
  placeholderFor(card); // a gap holds the origin slot
  card.classList.add("wl-drag"); // fixed, grabbing,
                                 // touch-action: none
  // pick a card up and the field re-measures it in
  // flight: data-active marks the body engaged, so the
  // attention metric writes a rising --field-attention.
  card.setAttribute("data-active", "");
}
function track(e) { // every pointermove
  card.style.transform = `translate(${e.clientX - x0}px,
    ${e.clientY - y0}px) scale(1.03)`;
  placeSlotIndicator(e); // the slim line between cards
  edgeScroll(e.clientY); // ±60px, proportional speed
}
function drop() { // pointerup — Esc/pointercancel aborts
  insertAtSlot(card); // displaced cards FLIP-settle
  card.removeAttribute("data-active");
  recountLanes(); // counts + cycle bar go "(local)"
  save(); // localStorage only — GitHub is never written
}

Pick a card up and the field re-measures it in flight: data-active marks the dragged body as engaged, so the attention lane's --field-attention rises while you hold it. Drops FLIP-settle the displaced cards, recount both lanes, and re-run the cycle arithmetic — marked (local) when it diverges from the snapshot. Keyboard works too: Space lifts, arrows move, Escape cancels.