Anonymous - 8 hours ago

Originally posted by: athanclark

Design

The browser's interval tree is rebuilt in memory, but the server's (oc_duration_nodes, via server/avl.mjs) and the native store's (native-store/src/intervals.rs) are persisted as exact rationals. PostgreSQL computes windows and summaries over them in SQL, through forks and saved views. Neither format has an "infinity" or a clock, so "now" cannot be stored in them.

Stored as a placeholder. An ongoing duration stays a row of the tree, as a zero-length band at its start. Its definition carries "end": {"ongoing": true}. Storage, forks, history, lookup by ID and listing therefore need no schema change.

Resolved at query time. Each window query also reads the timeline's ongoing durations, through a partial index on the definition and with a per-timeline cap. It resolves each against "now", as last = max(start, now), then:

  • swaps the resolved band in for its placeholder in the window's longest-first ranking;
  • adjusts the counts;
  • adds the band to the collapsed summaries when it is shorter than the threshold.

"Now" is the server's clock for server queries and the page's clock in the browser. It is mapped through the Gregorian preset: stored = Unix seconds × scale + origin.

Stages

  1. The core model and the browser: validation (Gregorian timelines only), resolution, the in-memory index, drawing, the duration dialog, .ochx. The server refuses ongoing ends until stage 2.
  2. The server: storage, window and summary queries, saved views, the API and OpenAPI.
  3. The native store and och-convert.