<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Pages on XKV.org</title>
    <link>https://xkv.org/pages/</link>
    <description>Recent content in Pages on XKV.org</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <atom:link href="https://xkv.org/pages/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>About</title>
      <link>https://xkv.org/about/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://xkv.org/about/</guid>
      <description>&lt;p&gt;XKV is a small key-value store that remembers why. Every write records who made it, why, and which earlier change caused it. Any value can then explain itself, one cause at a time, back across keys to where the chain started. It is open source, written in Go, and the first release is out.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-the-project-exists&#34;&gt;Why the Project Exists&lt;/h2&gt;&#xA;&lt;p&gt;Most outages and most support calls begin with a small value that changed. A limit, a price, a timeout, a feature switch. The store holds the new value. The reason sits somewhere else: in a log that rotated away, a chat thread, a ticket, or the head of whoever was on call.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Contact</title>
      <link>https://xkv.org/contact/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://xkv.org/contact/</guid>
      <description>&lt;p&gt;The project would like to hear from:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Teams&lt;/strong&gt; who keep limits, prices, settings or flags in a store and keep getting asked why a value changed.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Engineers&lt;/strong&gt; who tried XKV and hit a bug, a missing feature, or a number that didn&amp;rsquo;t match their own test.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Anyone&lt;/strong&gt; with a question about the store, the demo or the figures on this site.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Write to &lt;strong&gt;&lt;a href=&#34;mailto:info@xkv.org&#34;&gt;info@xkv.org&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Bugs and feature requests are also welcome as issues on &lt;a href=&#34;https://github.com/explainable-kv/xkv/issues&#34;&gt;GitHub&lt;/a&gt;. For a bug, the output of &lt;code&gt;xkv check&lt;/code&gt; on the file and the version from &lt;code&gt;xkv version&lt;/code&gt; help a lot.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Download XKV</title>
      <link>https://xkv.org/download/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://xkv.org/download/</guid>
      <description>&lt;p&gt;The &lt;code&gt;xkv&lt;/code&gt; command reads and writes a store from the shell and serves it over HTTP. Each archive holds the command with the license files and the README. The links always point to the latest release.&lt;/p&gt;&#xA;&lt;div style=&#34;overflow-x:auto&#34;&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;System&lt;/th&gt;&#xA;          &lt;th&gt;Download&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Linux, x86-64&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://github.com/explainable-kv/xkv/releases/latest/download/xkv_linux_amd64.tar.gz&#34;&gt;xkv_linux_amd64.tar.gz&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Linux, ARM64&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://github.com/explainable-kv/xkv/releases/latest/download/xkv_linux_arm64.tar.gz&#34;&gt;xkv_linux_arm64.tar.gz&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;macOS, Apple silicon&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://github.com/explainable-kv/xkv/releases/latest/download/xkv_darwin_arm64.tar.gz&#34;&gt;xkv_darwin_arm64.tar.gz&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;macOS, Intel&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://github.com/explainable-kv/xkv/releases/latest/download/xkv_darwin_amd64.tar.gz&#34;&gt;xkv_darwin_amd64.tar.gz&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;Windows, x86-64&lt;/td&gt;&#xA;          &lt;td&gt;&lt;a href=&#34;https://github.com/explainable-kv/xkv/releases/latest/download/xkv_windows_amd64.zip&#34;&gt;xkv_windows_amd64.zip&lt;/a&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/explainable-kv/xkv/releases/latest/download/SHA256SUMS&#34;&gt;SHA256SUMS&lt;/a&gt; lists the checksums. Every release and its notes are on the &lt;a href=&#34;https://github.com/explainable-kv/xkv/releases&#34;&gt;releases page&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;The binaries are pure Go with no outside libraries; the Linux ones are static. The macOS binaries aren&amp;rsquo;t signed by Apple, so macOS may ask you to allow them the first time, or you can run &lt;code&gt;xattr -d com.apple.quarantine xkv&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Live Demo</title>
      <link>https://xkv.org/demo/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://xkv.org/demo/</guid>
      <description>&lt;p&gt;The demo runs XKV in your browser. It&amp;rsquo;s the Go package itself, compiled to WebAssembly, with the store&amp;rsquo;s file kept in memory. Nothing needs installing, and nothing you type leaves the page.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://xkv.org/demo/app/&#34;&gt;Open the live demo&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-you-can-do&#34;&gt;What You Can Do&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Load a story.&lt;/strong&gt; Three short histories are ready to load: a credit limit that dropped, a timeout raised during an incident, and a cache setting an AI agent changed before an engineer put it back. Each is a handful of real writes made through the store, with their causes.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Click a value.&lt;/strong&gt; The store answers why, and the tree unfolds one level at a time: the value, the change that caused it, the change that caused that, and so on, across keys. Each step shows who made it, the reason they gave, the value before, and any outside reference such as a ticket or a tool call id.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Write your own change.&lt;/strong&gt; Pick a key, a value and a reason, tick the keys whose current value caused your change, and write it. It joins the chain at once. Leave the reason out and the store refuses, with the same error the Go package and the &lt;code&gt;xkv&lt;/code&gt; command give.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;See the history.&lt;/strong&gt; The History tab lists every revision of a key, newest first, with what caused each one.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://xkv.org/images/xkv-demo.png&#34; alt=&#34;The live demo showing why a credit limit is 50. The limit&amp;rsquo;s revision points at the risk score that caused it, which points at the chargeback that raised the score.&#34;&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Quick Start</title>
      <link>https://xkv.org/quick-start/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://xkv.org/quick-start/</guid>
      <description>&lt;p&gt;Ten minutes from nothing to a value that explains itself. Use the &lt;code&gt;xkv&lt;/code&gt; command first to see the idea, then the Go package to build it into a program.&lt;/p&gt;&#xA;&lt;h2 id=&#34;1-get-the-command&#34;&gt;1. Get the Command&lt;/h2&gt;&#xA;&lt;p&gt;Download the archive for your system from the &lt;a href=&#34;https://xkv.org/download/&#34;&gt;download page&lt;/a&gt;, unpack it, and put &lt;code&gt;xkv&lt;/code&gt; on your PATH. Check it runs:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;xkv version&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;2-write-a-chain&#34;&gt;2. Write a Chain&lt;/h2&gt;&#xA;&lt;p&gt;Three services each write one value. Each names what it acted on with &lt;code&gt;--cause&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Reference</title>
      <link>https://xkv.org/reference/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://xkv.org/reference/</guid>
      <description>&lt;p&gt;Everything XKV offers, on one page: the Go package, the &lt;code&gt;xkv&lt;/code&gt; command, the HTTP mode, and the file. The &lt;a href=&#34;https://github.com/explainable-kv/xkv#readme&#34;&gt;README&lt;/a&gt; is the full manual, and the Go documentation is on &lt;a href=&#34;https://pkg.go.dev/github.com/explainable-kv/xkv&#34;&gt;pkg.go.dev&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;revisions&#34;&gt;Revisions&lt;/h2&gt;&#xA;&lt;p&gt;Every write is a revision. A revision has:&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Field&lt;/th&gt;&#xA;          &lt;th&gt;Meaning&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Rev&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;store-wide revision number; only goes up&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Tx&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;transaction id; revisions written together share it&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Key&lt;/code&gt;, &lt;code&gt;Value&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;the key and its new value&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Deleted&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;true when the revision deletes the key&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Actor&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;who made it&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Reason&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;why; required unless the store is relaxed&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Ref&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;an outside reference: a ticket, a request id, a tool call id&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Causes&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;up to 8 earlier revisions, as key and revision number&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Time&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;when it was written&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;the-go-package&#34;&gt;The Go Package&lt;/h2&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;Call&lt;/th&gt;&#xA;          &lt;th&gt;Does&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Open(path, opts)&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;opens or creates a store file; one writer per file&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;OpenMemory(opts)&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;a store in memory, for tests and the browser&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Put(ctx, key, value, opts...)&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;writes one value&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Delete(ctx, key, opts...)&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;deletes a key; the delete is a revision too&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Update(ctx, fn, opts...)&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;writes several keys in one transaction&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Get(ctx, key)&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;the current revision&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;GetAt(ctx, key, rev)&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;the key as the store stood at revision &lt;code&gt;rev&lt;/code&gt;, or &lt;code&gt;ErrCompacted&lt;/code&gt; if compaction removed that state&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Revision(ctx, rev)&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;one revision by number&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;History(ctx, key, limit)&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;a key&amp;rsquo;s revisions, newest first&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Why(ctx, key, depth)&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;the tree of causes behind the current value&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;WhyRev(ctx, rev, depth)&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;the same for one revision&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Keys(ctx, prefix)&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;keys that have a value&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Compact(ctx, opts)&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;drops old revisions, keeping every one a kept value points at. On Windows it fails with nothing changed while another process has the file open&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;code&gt;Check(path)&lt;/code&gt;&lt;/td&gt;&#xA;          &lt;td&gt;reads every record and cause of a file&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;Write options: &lt;code&gt;Reason(s)&lt;/code&gt;, &lt;code&gt;Actor(s)&lt;/code&gt;, &lt;code&gt;Ref(s)&lt;/code&gt;, &lt;code&gt;Cause(key, rev)&lt;/code&gt; and &lt;code&gt;CauseLatest(key)&lt;/code&gt;. &lt;code&gt;WithActor(ctx, name)&lt;/code&gt; sets the actor for every write made with that context.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
