Local DataPoint nodes (owned by this device, no server) had no persistent log — snapshots were written to the node’s meta.snapshot field but the full time-series was never recorded. The graph screen had no data to show for a local DataPoint.
FileOperations had no append-log contract; ClientNodeManager.postSnapshot() only called fileOperations.update(node) for local nodes (overwrites the node) and never wrote to a time-series log. GraphScreen only fetched data via NodeHttp (server SSE/REST), so local DataPoints always produced an empty graph.
appendDataPointLog(id, epochMs, value) and readDataPointLog(id): Sequence<Pair<Long,String>> to the FileOperations interface with no-op defaults (WASM / legacy impls unaffected).<epochMs>\t<value>\n) in FileBasedOperations (JVM/desktop), AndroidFileOperations, and IosFileOperations.ClientNodeManager.postSnapshot() now calls appendDataPointLog after writing the snapshot for local nodes; edited() now also calls fileOperations.update() for local nodes.LocalSwarmHost.createNode() handles KrillApp.DataPoint explicitly to produce a properly named DataPointMetaData.GraphScreen reads local DataPoints from the log (skipping the HTTP path) and converts the #RRGGBB color log format back to int-string for rendering.DataPointView.EditDataPoint shows ON/OFF buttons for local DIGITAL DataPoints.manual-data.json flow enabled (comingSoon: false) with 7 steps: intro → name project → createNode(Project) → name DataPoint → createNode(DataPoint) → openEditor → chainTo(what-next).DataPointLogTest (7 tests) covers round-trip append/read for DOUBLE, COLOR, and DIGITAL types plus blank-line skipping, partial-line skipping, absent-file empty-sequence, and auto-mkdir — injecting logDir as a constructor parameter so the test never touches ~/.krill.FlowRegistryTest.manualData_isLiveInPhase5 guards that manual-data stays enabled.~/.krill/data/dplogs on the CI runner.file.readLines().asSequence() rather than sequence { file.forEachLine { yield(...) } } — forEachLine is non-inline and yield (a suspend function) cannot be called from its lambda; readLines() avoids the restriction entirely.