openlogbook 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. openlogbook-0.1.0/.github/CODEOWNERS +3 -0
  2. openlogbook-0.1.0/.github/ISSUE_TEMPLATE/adapter.md +12 -0
  3. openlogbook-0.1.0/.github/ISSUE_TEMPLATE/rfc.md +12 -0
  4. openlogbook-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +10 -0
  5. openlogbook-0.1.0/.github/dependabot.yml +8 -0
  6. openlogbook-0.1.0/.github/workflows/ci.yml +35 -0
  7. openlogbook-0.1.0/.github/workflows/release.yml +16 -0
  8. openlogbook-0.1.0/.gitignore +18 -0
  9. openlogbook-0.1.0/.pre-commit-config.yaml +10 -0
  10. openlogbook-0.1.0/.python-version +1 -0
  11. openlogbook-0.1.0/ARCHITECTURE.md +31 -0
  12. openlogbook-0.1.0/CHANGELOG.md +6 -0
  13. openlogbook-0.1.0/CLAUDE.md +12 -0
  14. openlogbook-0.1.0/CODE_OF_CONDUCT.md +3 -0
  15. openlogbook-0.1.0/CONTRIBUTING.md +13 -0
  16. openlogbook-0.1.0/GOVERNANCE.md +7 -0
  17. openlogbook-0.1.0/LICENSE +7 -0
  18. openlogbook-0.1.0/LORE.md +69 -0
  19. openlogbook-0.1.0/PKG-INFO +78 -0
  20. openlogbook-0.1.0/README.md +58 -0
  21. openlogbook-0.1.0/ROADMAP.md +15 -0
  22. openlogbook-0.1.0/SECURITY.md +7 -0
  23. openlogbook-0.1.0/SPEC.md +76 -0
  24. openlogbook-0.1.0/VISION.md +39 -0
  25. openlogbook-0.1.0/adapters/README.md +9 -0
  26. openlogbook-0.1.0/adapters/template/README.md +3 -0
  27. openlogbook-0.1.0/adapters/template/adapter.py +33 -0
  28. openlogbook-0.1.0/adapters/template/fixture/input.json +2 -0
  29. openlogbook-0.1.0/conformance/README.md +11 -0
  30. openlogbook-0.1.0/conformance/expected.json +5 -0
  31. openlogbook-0.1.0/conformance/make_sample.py +178 -0
  32. openlogbook-0.1.0/conformance/sample-logbook/logbook/2026/03.jsonl +16 -0
  33. openlogbook-0.1.0/conformance/sample-logbook/logbook.json +8 -0
  34. openlogbook-0.1.0/conformance/sample-logbook/notes/2026/2026-03-07.md +1 -0
  35. openlogbook-0.1.0/docs/adr/0001-files-are-the-truth.md +9 -0
  36. openlogbook-0.1.0/docs/adr/0002-canonical-json-and-hashing.md +5 -0
  37. openlogbook-0.1.0/docs/adr/0003-one-log.md +9 -0
  38. openlogbook-0.1.0/docs/adr/0004-notes-live-in-the-logbook.md +9 -0
  39. openlogbook-0.1.0/docs/adr/0005-one-evening-message.md +9 -0
  40. openlogbook-0.1.0/docs/adr/0006-chain-mandatory.md +9 -0
  41. openlogbook-0.1.0/docs/adr/0007-sqlite-default-index.md +7 -0
  42. openlogbook-0.1.0/docs/adr/0008-first-adapters.md +9 -0
  43. openlogbook-0.1.0/docs/adr/0009-the-circle-is-core.md +9 -0
  44. openlogbook-0.1.0/docs/adr/0010-identity-of-the-captain.md +7 -0
  45. openlogbook-0.1.0/docs/adr/README.md +3 -0
  46. openlogbook-0.1.0/docs/how-it-works.svg +17 -0
  47. openlogbook-0.1.0/logbook/__init__.py +4 -0
  48. openlogbook-0.1.0/logbook/chain.py +52 -0
  49. openlogbook-0.1.0/logbook/cli.py +130 -0
  50. openlogbook-0.1.0/logbook/store.py +166 -0
  51. openlogbook-0.1.0/pyproject.toml +51 -0
  52. openlogbook-0.1.0/rfcs/README.md +3 -0
  53. openlogbook-0.1.0/schema/observation.schema.json +22 -0
  54. openlogbook-0.1.0/tests/run.py +24 -0
  55. openlogbook-0.1.0/tests/test_chain.py +147 -0
  56. openlogbook-0.1.0/tests/test_properties.py +59 -0
  57. openlogbook-0.1.0/uv.lock +706 -0
@@ -0,0 +1,3 @@
1
+ * @bighydro
2
+ SPEC.md @bighydro
3
+ schema/ @bighydro
@@ -0,0 +1,12 @@
1
+ ---
2
+ name: New adapter
3
+ about: Propose an adapter for a source
4
+ labels: adapter
5
+ ---
6
+ **Source** (app/service, export format, how to get the export):
7
+
8
+ **Kinds and payload schemas it would produce:**
9
+
10
+ **Tier:**
11
+
12
+ **Synthetic fixture attached?** (never real data)
@@ -0,0 +1,12 @@
1
+ ---
2
+ name: RFC (payload profile or spec change)
3
+ about: Propose a payload profile or a change to SPEC.md
4
+ labels: rfc
5
+ ---
6
+ **Summary**
7
+
8
+ **Schema** (JSON Schema, draft 2020-12)
9
+
10
+ **One synthetic example line**
11
+
12
+ **Backwards compatibility**
@@ -0,0 +1,10 @@
1
+ ## What
2
+
3
+ ## Why
4
+
5
+ ## Checklist
6
+ - [ ] Tests added or updated; `uv run pytest` green
7
+ - [ ] No real personal data in fixtures (synthetic only)
8
+ - [ ] No write/update/delete path into the log except `Logbook.append`
9
+ - [ ] If SPEC.md changed: version bumped, `conformance/` regenerated, CHANGELOG entry
10
+ - [ ] Signed-off (`git commit -s`, DCO)
@@ -0,0 +1,8 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: github-actions
4
+ directory: /
5
+ schedule: { interval: monthly }
6
+ - package-ecosystem: uv
7
+ directory: /
8
+ schedule: { interval: monthly }
@@ -0,0 +1,35 @@
1
+ name: ci
2
+ on:
3
+ push: { branches: [main] }
4
+ pull_request:
5
+ schedule:
6
+ - cron: "17 4 * * 1" # weekly scorecard
7
+ permissions: { contents: read }
8
+ jobs:
9
+ test:
10
+ strategy:
11
+ fail-fast: false
12
+ matrix:
13
+ os: [ubuntu-latest, macos-latest, windows-latest]
14
+ python: ["3.12", "3.13"]
15
+ runs-on: ${{ matrix.os }}
16
+ steps:
17
+ - uses: actions/checkout@v7
18
+ - uses: astral-sh/setup-uv@v7
19
+ - run: uv python install ${{ matrix.python }}
20
+ - run: uv sync --group dev
21
+ - run: uv run ruff check . && uv run ruff format --check .
22
+ - run: uv run mypy logbook
23
+ - run: uv run pytest --cov=logbook --cov-report=xml
24
+ - name: conformance
25
+ run: uv run logbook verify --root conformance/sample-logbook --expect conformance/expected.json
26
+ - uses: codecov/codecov-action@v7
27
+ if: matrix.os == 'ubuntu-latest' && matrix.python == '3.12'
28
+ scorecard:
29
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
30
+ runs-on: ubuntu-latest
31
+ permissions: { security-events: write, id-token: write }
32
+ steps:
33
+ - uses: actions/checkout@v7
34
+ - uses: ossf/scorecard-action@v2
35
+ with: { results_file: results.sarif, results_format: sarif, publish_results: true }
@@ -0,0 +1,16 @@
1
+ name: release
2
+ on:
3
+ push: { tags: ["v*"] }
4
+ permissions: { contents: write, id-token: write, attestations: write } # id-token: PyPI trusted publishing + Sigstore; attestations: provenance
5
+ jobs:
6
+ build:
7
+ runs-on: ubuntu-latest
8
+ steps:
9
+ - uses: actions/checkout@v7
10
+ - uses: astral-sh/setup-uv@v7
11
+ - run: uv build
12
+ - uses: actions/attest-build-provenance@v4 # SLSA provenance for every wheel
13
+ with: { subject-path: dist/* }
14
+ - uses: pypa/gh-action-pypi-publish@release/v1 # OIDC; configure "trusted publisher" once on PyPI
15
+ - uses: softprops/action-gh-release@v3
16
+ with: { files: dist/*, generate_release_notes: true }
@@ -0,0 +1,18 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ dist/
5
+ .pytest_cache/
6
+ .mypy_cache/
7
+ .ruff_cache/
8
+ .coverage
9
+ coverage.xml
10
+ .env
11
+ data/
12
+ .DS_Store
13
+
14
+ # never commit a personal record into the code repo
15
+ /logbook.json
16
+ /logbook/[0-9][0-9][0-9][0-9]/
17
+ /notes/
18
+ /inbox/
@@ -0,0 +1,10 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.6.9
4
+ hooks: [{ id: ruff, args: [--fix] }, { id: ruff-format }]
5
+ - repo: https://github.com/pre-commit/pre-commit-hooks
6
+ rev: v5.0.0
7
+ hooks: [{ id: end-of-file-fixer }, { id: trailing-whitespace }, { id: check-json }, { id: check-yaml }, { id: detect-private-key }]
8
+ - repo: https://github.com/gitleaks/gitleaks
9
+ rev: v8.21.2
10
+ hooks: [{ id: gitleaks }]
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,31 @@
1
+ # Architecture — five layers
2
+
3
+ ```
4
+ 5 Agents any agent with MCP: add, ask, confirm, verify. the UI.
5
+ 4 Surfaces day page · timeline · person · books · shared pages
6
+ 3 Engines logbook → days, trips, people, places. versioned. recomputable.
7
+ 2 Adapters one per source. export in → observations out. pure.
8
+ 1 Logbook the folder, the chain, the CLI. the standard.
9
+ ```
10
+
11
+ The dependency arrow points down only. An adapter never knows an engine exists. A surface reads derived rows and notes, never the raw log. Agents are operators, not authors: they may run adapters and draft, they may never write a note, a confirmation or a visibility decision — that stays with the human, enforced in layer 1.
12
+
13
+ | Layer | Contract | Repo |
14
+ |---|---|---|
15
+ | 1 | the format (SPEC.md); `logbook add/show/verify/export` | this repo |
16
+ | 2 | `run(input_path, since) -> iterator[Observation]`; fixture-tested; no network by default | `logbook-adapter-<source>` |
17
+ | 3 | `pass(logbook, date_range) -> derived rows` carrying `engine_version`; idempotent; stable derived IDs | `logbook-engine` |
18
+ | 4 | reads derived rows + notes; writes only notes and confirmations (as tier-2 lines) | `logbook-web`, `logbook-books` |
19
+ | 5 | MCP server exposing `logbook.add`, `logbook.query`, `logbook.ask`, `logbook.confirm`, `logbook.verify` | `logbook-mcp` |
20
+
21
+ ## Derived is disposable
22
+
23
+ Days, trips, people and places are computed from the log and can be thrown away. Their IDs are derived from (owner, kind, rounded start, place) so a recompute yields the same ID and human notes stay attached. Human input — notes, confirmations, visibility choices — is written to the log as tier-2 lines, so it survives any recompute and any export.
24
+
25
+ ## The circle (layer 4/5, protocol to be defined)
26
+
27
+ A shared page is a signed bundle: the day's derived rows the owner chose to share, their notes marked shareable, photo references, and the owner's signature. Transport is undecided (peer-to-peer over a relay vs. a small server); the bundle format will be defined before any transport is built, so that the first two implementations can exchange pages by any means, including a USB stick.
28
+
29
+ ## Reference stack
30
+
31
+ Python 3.12, no required dependencies for layer 1. Engines may use SQLite as an index; PostGIS is a plugin, never a requirement. Web layer: server-rendered HTML. Everything runs on one machine that is always on, or on a laptop that sometimes is.
@@ -0,0 +1,6 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+ - Format v0.1: folder layout, envelope, hash chain, tiers, conformance rule.
5
+ - CLI: init, add (text or JSONL), show, verify, export.
6
+ - Conformance fixture with expected head.
@@ -0,0 +1,12 @@
1
+ # For agents working in this repository
2
+
3
+ You are one of several coding agents that build this project alongside a human captain. Read SPEC.md and ARCHITECTURE.md first.
4
+
5
+ Hard rules — a change that needs to break one is wrong; stop and say so:
6
+ - Never write to the log except through `Logbook.append`. Never UPDATE or DELETE a line, in code or by hand.
7
+ - Never add real personal data to the repository. Fixtures are synthetic; the sample person lives in Oslo and does not exist.
8
+ - Never add network calls to an adapter's default path.
9
+ - Never change the envelope (SPEC §2–3) without a spec version bump, a regenerated conformance fixture, and an ADR in `docs/adr/`.
10
+ - Test first: write the failing test, run it, implement, run it, commit with `-s`. One issue per task, closed by the commit.
11
+
12
+ Conventions: `uv` for everything (`uv sync --group dev`, `uv run pytest`, `uv run ruff check --fix .`, `uv run mypy logbook`). Conventional commits (`feat:`, `fix:`, `spec:`, `docs:`, `adapter:`). Plain English names inside the code: Logbook, Line, Day, Note — no metaphors.
@@ -0,0 +1,3 @@
1
+ # Code of conduct
2
+
3
+ This project follows the Contributor Covenant, version 2.1 (https://www.contributor-covenant.org/version/2/1/code_of_conduct/). Be kind, be precise, argue about the work. Report problems to the address in the repository profile; the captain handles them privately and promptly.
@@ -0,0 +1,13 @@
1
+ # Contributing
2
+
3
+ The easiest and most useful thing to build is an adapter for the export you already have.
4
+
5
+ 1. Copy `adapters/template/`.
6
+ 2. Put a small, **synthetic** export in `fixture/` — never real data, not even yours.
7
+ 3. Write `run(input_path, since)` yielding observations with a `payload.schema`.
8
+ 4. Run the tests; the expected output file is generated on first run and checked in.
9
+ 5. Open a pull request. Name it `adapter: <source>`.
10
+
11
+ Rules for every contribution: no network calls unless the adapter is explicitly a live adapter; no writes to any source; nothing that updates or deletes a line in the log — if a change seems to need it, the change is wrong.
12
+
13
+ Code is Apache-2.0. Contributions to SPEC.md are CC0.
@@ -0,0 +1,7 @@
1
+ # Governance
2
+
3
+ Captain: bighydro. A ship has one captain and the captain signs the log. The captain merges, releases monthly, and writes the CHANGELOG.
4
+
5
+ The envelope (SPEC §2–3) changes only by major version and ships with a migration tool. Payload profiles change freely through RFCs in `rfcs/`: open a pull request with the schema and one fixture; two weeks of comment; merge.
6
+
7
+ Decisions are made in public issues. When the steward and a contributor disagree, the captain decides and writes down why in the log (the issue). If the ship ever has three officers of the watch, this file gets replaced with something better.
@@ -0,0 +1,7 @@
1
+ Apache License 2.0 — https://www.apache.org/licenses/LICENSE-2.0
2
+
3
+ Copyright 2026 bighydro
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at the URL above. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6
+
7
+ SPEC.md and everything under schema/ and rfcs/ are dedicated to the public domain under CC0 1.0.
@@ -0,0 +1,69 @@
1
+ # Lore — where the logbook comes from
2
+
3
+ A project needs to know its ancestors. Logbook has two lines of descent, human and computational, and they turn out to be the same line.
4
+
5
+ ## I. The human logbook
6
+
7
+ **The knot and the board.** In the 1500s a sailor measured a ship's speed by throwing a flat wooden board — the *log* — over the stern on a line knotted at fixed intervals, and counting how many knots ran out while a small sandglass emptied. Speed at sea is still given in *knots* because of that board. The readings were entered in a book beside the helm: the log-book. Course, speed, wind, weather, position, every few hours, in ink, in order, initialled by the officer of the watch. Within a century "logbook" meant the whole record of a voyage: who came aboard, who died, what was sighted, what was decided. It was never written for an audience. It was written because things happened, and because later someone would need to know what actually occurred.
8
+
9
+ **Truth by construction.** A ship's log is admissible in court. Entries are made at the time, in sequence, in a bound book with numbered pages; an error is struck through with a single line so the original stays legible, and the correction is initialled. Nothing is erased. Nothing is written later and backdated. Three rules — append only, corrections as new entries, never delete — that are four hundred years older than any database and identical to the ones this project enforces.
10
+
11
+ **The voyages we know only because someone kept the book.** Antonio Pigafetta kept the diary of Magellan's circumnavigation (1519–22); only eighteen men came home, and most of what we know of the first voyage around the earth is his book. James Cook's journals fixed the coastlines of the Pacific. Charles Darwin kept a diary aboard *Beagle* for five years (1831–36); *On the Origin of Species* grew out of those notebooks, twenty years later, because he could reread what he had actually seen rather than what he remembered seeing. Robert Falcon Scott's last diary was found beside his body in the Antarctic in 1912; Shackleton's men kept theirs on the ice for two years and every one of them came home. Lighthouse keepers, weather stations, station masters, mine foremen: for three centuries the ordinary world was run by people making dated entries in ruled books, and the climate scientists of our own century now reconstruct the weather of the 1800s from ships' logs, because those pages are the only instruments that were there.
12
+
13
+ **The captain's logbook and the pilot's.** Every pilot alive keeps a logbook. It is a legal document: date, aircraft, route, hours, landings, who was in command. A licence is granted on the strength of it and can be lost over it. It is the one place where a pilot's life in the air is true, and pilots are sentimental about theirs in a way they are about nothing else. The captain's log — the phrase is now a joke from television — was the same thing at sea: the commander's own record, in the first person, of what was decided and why.
14
+
15
+ **The private book.** Beside the official log there was always another book. Marcus Aurelius wrote his *Meditations* for no reader but himself; the Greek title is simply "to himself". Samuel Pepys kept a diary in shorthand for nine years (1660–69) and recorded the plague, the Great Fire, and his own small vanities with equal care; nobody read it for a century and a half. Benjamin Franklin ruled a small book into thirteen virtues and marked each evening's faults with a dot — the first self-tracker. Leonardo's notebooks, Thoreau's journal, the commonplace books in which people for centuries copied what they wanted to keep: none of these were feeds. They were written by one person, for that person, to be reread.
16
+
17
+ **The captain of my soul.** William Ernest Henley wrote *Invictus* in 1875 from a hospital bed, after losing a foot to tuberculosis of the bone:
18
+
19
+ > I am the master of my fate,
20
+ > I am the captain of my soul.
21
+
22
+ The poem is a claim of ownership over one's own voyage. A logbook is the instrument that makes the claim true: you cannot be the captain of a voyage no one recorded.
23
+
24
+ ## II. The computational logbook
25
+
26
+ **Same word, same object.** When engineers needed a name for an ordered, append-only, timestamped record of what a machine had done, they took the sailor's word. Operating systems have written *log files* since the 1960s; Unix `syslog` (Eric Allman, 1980s) gave every program a common place to write a dated line. The metaphor was exact: something happened, write it down, in order, don't go back.
27
+
28
+ **The log as the truth.** Database engineers discovered that the log was not a byproduct of the database — it *was* the database. The write-ahead log (formalised in the ARIES papers, C. Mohan and colleagues, 1992) writes every change to an append-only file *before* touching the tables, so that after a crash the tables can be rebuilt from the log, but the log can never be rebuilt from the tables. Journaling filesystems did the same for disks. Leslie Lamport's *Time, Clocks, and the Ordering of Events* (1978) showed that in a distributed system the only thing that can be agreed on is an order of events — a log. Jay Kreps's essay *The Log* (LinkedIn, 2013), which led to Apache Kafka, says it in one sentence: the log is the source of truth; every table, index, cache and view is a derived, disposable projection of it. This project's first principle — the log is immutable, moments are disposable, notes are sacred — is that sentence applied to a life.
29
+
30
+ **Making the log unforgeable.** Ralph Merkle (1979) showed how to hash a tree of records so that changing any leaf changes the root. Stuart Haber and W. Scott Stornetta (1991) chained timestamped documents by hashing each one together with the previous — a linked hash chain, built so that no one, not even the keeper, could later alter a page without breaking every page after it. Git (2005) made every commit a hash of its content and its parent, so that a repository's history is verifiable by anyone who holds it. Bitcoin (2008) put the same chain in public. Logbook uses the 1991 version: one person's private chain, verifiable by that person, needing no one else's agreement. The ship's log struck a line through errors and initialled the page; the hash chain is the initial.
31
+
32
+ **The dream of a machine that remembers for you.** Vannevar Bush described the *memex* in 1945 — a desk that stores everything a person reads and the trails between them. Ted Nelson's Xanadu, Douglas Engelbart's augmentation, and the hypertext that became the web all descend from it. Steve Mann wore a camera and computer through the 1990s, logging his life continuously. Gordon Bell at Microsoft spent the 2000s on MyLifeBits, scanning and recording everything he did, and wrote *Total Recall* (2009) about it. The Quantified Self movement (Gary Wolf and Kevin Kelly, 2007) turned self-tracking into a practice. Every one of these got the *record* right and left the *recount* and the *circle* unbuilt: a life captured and never read back, held by one person or one company, shared with no one. Logbook is the next step on that trail, with the two missing parts.
33
+
34
+ ## III. Fusing the two sciences
35
+
36
+ The fusion is not a metaphor; the same structure appears on both sides.
37
+
38
+ | Computer science | Human science | In Logbook |
39
+ |---|---|---|
40
+ | The log is the source of truth; views are derived and disposable | Autobiographical memory is reconstructive: we do not replay the past, we rebuild it each time from fragments, and the rebuild drifts (Bartlett, 1932; Loftus) | The record is fixed; the recount is a view that can be regenerated, and every sentence links to its evidence so the drift is visible |
41
+ | Write-ahead: record before you act on it | The *experiencing self* and the *remembering self* disagree; memory keeps the peak and the end and drops the duration (Kahneman) | Observations are written at the time by instruments; the evening note is the remembering self's line, kept separate and marked as such |
42
+ | Idempotent replay; recompute from history when the rules improve | Reminiscence: rereading a diary changes what a memory means without changing what happened | Engines are versioned and re-run over all history; notes are never touched |
43
+ | Hash chain: tamper-evident, verifiable by the holder | Narrative identity: a self is the story a person can tell about the connected events of their life (McAdams) | A verifiable chain is a story that cannot be quietly rewritten, by you or anyone |
44
+ | Access control, capability tokens | Trust is built in dyads, one relationship at a time, by reciprocal disclosure (Altman & Taylor's social penetration theory) | The circle: a page for a page, named person to named person, no broadcast |
45
+ | Garbage collection is forbidden; the log is never pruned | Forgetting is the default: the Ebbinghaus curve (1885) drops most of a day within a week | Never prune. The instrument remembers so that you may forget freely and reread when it matters |
46
+ | Derived metrics: counters, dashboards | Gratitude and expressive writing measurably improve wellbeing (Pennebaker, 1986; Emmons & McCullough, 2003) — and extrinsic rewards crowd out intrinsic motivation (Deci) | Reveal, never reward: the logbook may show you a first or a milestone; it never scores you |
47
+
48
+ The rule of thumb for any new feature: find its twin on the other side of the table. If a computing idea has no human counterpart, it is plumbing and should be invisible. If a human idea has no computing counterpart, it is a note — and notes are sacred.
49
+
50
+ ## IV. The statement against the attention economy
51
+
52
+ Herbert Simon said it in 1971: a wealth of information creates a poverty of attention. The industry that followed — Tim Wu called its practitioners *the attention merchants* — learned to harvest that scarce attention and sell it. Aza Raskin designed infinite scroll in 2006 and has spent years apologising for it. Shoshana Zuboff named the model *surveillance capitalism* (2019): your record, held by someone else, used to predict and steer you. Neil Postman had warned in 1985 that we were amusing ourselves to death; Jaron Lanier gave ten arguments for deleting your accounts; Cal Newport wrote the manual for leaving.
53
+
54
+ Every one of these critics described the disease. Fewer built the alternative, and the alternative cannot be "less feed"; it has to be a different object. A feed is other people's present, ranked by a machine to keep you looking, held by a company, measured in your attention. A logbook is your own past, in order, held by you, measured in nothing. The feed asks *what is happening?* and never lets you finish answering. The logbook asks *what happened?* and lets you close the book.
55
+
56
+ The design decisions follow directly:
57
+
58
+ - **No feed.** There is no page that shows other people's lives. There is a page that shows one day of yours.
59
+ - **No audience.** Sharing is a page handed to a named person who hands one back. There is no post, no follower, no public.
60
+ - **No counts.** Nothing is liked, viewed, or ranked. Nothing near a person has a number.
61
+ - **No engagement loop.** One evening question; ignore it forever and nothing happens.
62
+ - **No harvest.** The files are on your disk. There is no server to sell to, no model trained on you without your key.
63
+ - **Reveal, never reward.** The logbook can tell you it was your hundredth flight hour or your first time in Portugal. It cannot give you a badge for it.
64
+
65
+ Social media promised connection and delivered an audience. A logbook makes the old promise honestly: you, your voyage, the few people you choose to show it to — and a book that will still open in fifty years, because it is only paper made of files.
66
+
67
+ *You are the captain of your ship. This is the log.*
68
+
69
+ — bighydro, captain of this one
@@ -0,0 +1,78 @@
1
+ Metadata-Version: 2.5
2
+ Name: openlogbook
3
+ Version: 0.1.0
4
+ Summary: A diary that writes itself. Your life, in a folder.
5
+ Project-URL: Homepage, https://github.com/bighydro/logbook
6
+ Project-URL: Specification, https://github.com/bighydro/logbook/blob/main/SPEC.md
7
+ Project-URL: Changelog, https://github.com/bighydro/logbook/blob/main/CHANGELOG.md
8
+ Author: bighydro
9
+ License-Expression: Apache-2.0
10
+ License-File: LICENSE
11
+ Keywords: append-only,diary,hash-chain,lifelog,local-first,logbook,personal-data
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: End Users/Desktop
15
+ Classifier: Programming Language :: Python :: 3 :: Only
16
+ Classifier: Topic :: Database
17
+ Classifier: Typing :: Typed
18
+ Requires-Python: >=3.12
19
+ Description-Content-Type: text/markdown
20
+
21
+ # Logbook
22
+
23
+ **A diary that writes itself.**
24
+
25
+ Your life already gets recorded — by your phone, your photos, your calendar, your messages. Logbook writes it all down once, in one folder that only you hold, and reads it back to you as days. You hand a page to someone you care about; they hand one back.
26
+
27
+ It is the opposite of social media: no feed, no followers, no likes, no counts. Reveal, never reward. Nothing leaves without a name.
28
+
29
+ ![How Logbook works](docs/how-it-works.svg)
30
+
31
+ ## Sixty seconds
32
+
33
+ ```bash
34
+ pipx install openlogbook # or: pip install .
35
+ logbook init # creates ~/Logbook and your key
36
+ logbook add "had lunch with a friend by the lake"
37
+ logbook add ~/Downloads/takeout.zip # any export, no flags
38
+ logbook show today
39
+ logbook verify # the chain is intact
40
+ ```
41
+
42
+ That is the whole product. Everything else is a layer somebody plugs in.
43
+
44
+ ## What is in the folder
45
+
46
+ ```
47
+ ~/Logbook/
48
+ logbook/ the record. one file per month. append only. never edit.
49
+ 2026/09.jsonl
50
+ inbox/ drop anything here. it gets read, then moved to done/.
51
+ notes/ what you write. plain Markdown, one file per day.
52
+ logbook.json who this is, your timezone, the chain head.
53
+ ```
54
+
55
+ Nothing here needs the app to make sense. Open the files in any editor twenty years from now.
56
+
57
+ If you also keep a clone of this repository, set `LOGBOOK_HOME` to your record's folder and pass that path to `logbook init`. On a case-insensitive disk (macOS by default) `~/Logbook` and a clone named `~/logbook` are the same folder; `init` refuses a folder that contains `pyproject.toml`, `.git` or `logbook/__init__.py`, and the CLI never picks such a folder as your record.
58
+
59
+ ## Three rules
60
+
61
+ 1. **Append only.** Every line is hash-chained to the one before. A broken chain is an error, never repaired silently.
62
+ 2. **Files first.** No database is required to read, verify or export a logbook. Databases are caches.
63
+ 3. **Nothing leaves.** Personal lines are encrypted with your key. There is no server. Sharing is a page handed to a named person.
64
+
65
+ ## Read next
66
+
67
+ - [VISION.md](VISION.md) — why, and the rules the product refuses to break
68
+ - [LORE.md](LORE.md) — where the logbook comes from: ships, pilots, diaries, and the log in computing
69
+ - [SPEC.md](SPEC.md) — the format, one page; this is the part meant to become a standard
70
+ - [ARCHITECTURE.md](ARCHITECTURE.md) — the five layers and what each may depend on
71
+ - [ROADMAP.md](ROADMAP.md) — what ships when
72
+ - [CONTRIBUTING.md](CONTRIBUTING.md) — the easiest thing to build is an adapter for the export you have
73
+
74
+ ## Status
75
+
76
+ v0.1 — the format, the CLI (init, add, show, verify, export) and the conformance fixture. Engines (days, trips, people) and the circle (sharing) are the next layers; see the roadmap.
77
+
78
+ Apache-2.0 for code. The specification is CC0.
@@ -0,0 +1,58 @@
1
+ # Logbook
2
+
3
+ **A diary that writes itself.**
4
+
5
+ Your life already gets recorded — by your phone, your photos, your calendar, your messages. Logbook writes it all down once, in one folder that only you hold, and reads it back to you as days. You hand a page to someone you care about; they hand one back.
6
+
7
+ It is the opposite of social media: no feed, no followers, no likes, no counts. Reveal, never reward. Nothing leaves without a name.
8
+
9
+ ![How Logbook works](docs/how-it-works.svg)
10
+
11
+ ## Sixty seconds
12
+
13
+ ```bash
14
+ pipx install openlogbook # or: pip install .
15
+ logbook init # creates ~/Logbook and your key
16
+ logbook add "had lunch with a friend by the lake"
17
+ logbook add ~/Downloads/takeout.zip # any export, no flags
18
+ logbook show today
19
+ logbook verify # the chain is intact
20
+ ```
21
+
22
+ That is the whole product. Everything else is a layer somebody plugs in.
23
+
24
+ ## What is in the folder
25
+
26
+ ```
27
+ ~/Logbook/
28
+ logbook/ the record. one file per month. append only. never edit.
29
+ 2026/09.jsonl
30
+ inbox/ drop anything here. it gets read, then moved to done/.
31
+ notes/ what you write. plain Markdown, one file per day.
32
+ logbook.json who this is, your timezone, the chain head.
33
+ ```
34
+
35
+ Nothing here needs the app to make sense. Open the files in any editor twenty years from now.
36
+
37
+ If you also keep a clone of this repository, set `LOGBOOK_HOME` to your record's folder and pass that path to `logbook init`. On a case-insensitive disk (macOS by default) `~/Logbook` and a clone named `~/logbook` are the same folder; `init` refuses a folder that contains `pyproject.toml`, `.git` or `logbook/__init__.py`, and the CLI never picks such a folder as your record.
38
+
39
+ ## Three rules
40
+
41
+ 1. **Append only.** Every line is hash-chained to the one before. A broken chain is an error, never repaired silently.
42
+ 2. **Files first.** No database is required to read, verify or export a logbook. Databases are caches.
43
+ 3. **Nothing leaves.** Personal lines are encrypted with your key. There is no server. Sharing is a page handed to a named person.
44
+
45
+ ## Read next
46
+
47
+ - [VISION.md](VISION.md) — why, and the rules the product refuses to break
48
+ - [LORE.md](LORE.md) — where the logbook comes from: ships, pilots, diaries, and the log in computing
49
+ - [SPEC.md](SPEC.md) — the format, one page; this is the part meant to become a standard
50
+ - [ARCHITECTURE.md](ARCHITECTURE.md) — the five layers and what each may depend on
51
+ - [ROADMAP.md](ROADMAP.md) — what ships when
52
+ - [CONTRIBUTING.md](CONTRIBUTING.md) — the easiest thing to build is an adapter for the export you have
53
+
54
+ ## Status
55
+
56
+ v0.1 — the format, the CLI (init, add, show, verify, export) and the conformance fixture. Engines (days, trips, people) and the circle (sharing) are the next layers; see the roadmap.
57
+
58
+ Apache-2.0 for code. The specification is CC0.
@@ -0,0 +1,15 @@
1
+ # Roadmap
2
+
3
+ Phases, not dates. Each phase ends with something a stranger can use.
4
+
5
+ **0 — the format (now).** SPEC v0.1, JSON Schema, conformance fixture, this CLI. Verify passes on the sample logbook.
6
+
7
+ **1 — three drops.** Adapters for Google Takeout (location, photos, calendar, mail headers, YouTube, Chrome), Apple Health (sleep, steps, workouts) and WhatsApp exports (messages, tier 2); an email adapter follows as its own task. `logbook add <zip>` sniffs which is which. Encryption at rest for tiers 2–3 (spec v0.2).
8
+
9
+ **2 — days.** The reference engine: stays, moves, flights, places, meetings, people, trips. `logbook show <day>` becomes a page. The MCP server ships, so any agent can add, ask and confirm.
10
+
11
+ **3 — the circle.** The shared-page bundle format; exchange between two logbooks by file; then a transport. Per-person pages: last real contact, shared moments, birthdays.
12
+
13
+ **4 — the community.** Adapter template and bounty list (Strava, Garmin, Immich, Dawarich, Telegram, iMessage, bank CSV, Spotify, Letterboxd). Payload-profile RFCs. A second implementation in another language by someone who only read the spec.
14
+
15
+ **5 — v1.0.** The envelope frozen; conformance badge; books and published pages as community layers; data-portability law gives every service a reason to emit the format.
@@ -0,0 +1,7 @@
1
+ # Security
2
+
3
+ This software stores a person's whole life. Treat every bug as if it were serious.
4
+
5
+ Report vulnerabilities privately to the address in the repository profile. You will get a reply within 48 hours. Fixes ship before disclosure.
6
+
7
+ Threat model (v0.1): the logbook lives on a machine the owner controls. The adversary is anyone who obtains the files. Tier 1 is plain; tiers 2 and 3 are encrypted at rest from v0.2 with a key that never leaves the owner's machine. There is no server and no account. Adapters are untrusted code: they run without network by default and can only append.
@@ -0,0 +1,76 @@
1
+ # Logbook format — specification v0.1
2
+
3
+ Status: draft. License: CC0. Anyone may implement this without asking.
4
+
5
+ The key words MUST, MUST NOT, SHOULD and MAY are to be interpreted as described in RFC 2119.
6
+
7
+ ## 1. The folder
8
+
9
+ ```
10
+ <root>/
11
+ logbook.json identity and chain head
12
+ logbook/<YYYY>/<MM>.jsonl the record
13
+ notes/<YYYY>/<YYYY-MM-DD>.md free text, optional
14
+ inbox/ optional; not part of conformance
15
+ ```
16
+
17
+ `logbook.json`:
18
+
19
+ ```json
20
+ {"format": "logbook/0.1", "owner_id": "<uuid>", "created_at": "<RFC3339 UTC>",
21
+ "timezone": "<IANA tz>", "seq": 4181, "head": "<hex sha256>"}
22
+ ```
23
+
24
+ ## 2. The line (the envelope)
25
+
26
+ One observation per line, JSON, UTF-8, newline-terminated, in `logbook/<YYYY>/<MM>.jsonl`, where YYYY and MM are taken from `at` in UTC.
27
+
28
+ | Field | Type | Meaning |
29
+ |---|---|---|
30
+ | `id` | uuid | UUIDv7 (RFC 9562) recommended; identity of this line; outside the hash so it may be assigned at write time |
31
+ | `seq` | integer ≥ 1 | position in the owner's chain; strictly increasing by 1 |
32
+ | `at` | RFC3339 UTC | when the thing happened (not when it was recorded) |
33
+ | `end` | RFC3339 UTC or null | when it stopped, if it had a duration |
34
+ | `tz` | IANA name | the owner's timezone at `at` |
35
+ | `source` | string | who reported it: `manual`, `apple-health`, `google-takeout`, … |
36
+ | `kind` | string | what it is: `location`, `photo`, `event`, `message`, `sleep`, `note`, … |
37
+ | `tier` | 1, 2 or 3 | privacy tier, §4 |
38
+ | `payload` | object | whatever the source said; MUST contain `schema`, e.g. `"location/v1"` |
39
+ | `recorded_at` | RFC3339 UTC | when the line was written |
40
+ | `prev` | hex sha256 | hash of the previous line; 64 zeros for the first |
41
+ | `hash` | hex sha256 | §3 |
42
+
43
+ Unknown fields MUST be preserved by readers and MUST NOT be added by writers at the top level; extensions go inside `payload`.
44
+
45
+ ## 3. The chain
46
+
47
+ ```
48
+ content = canonical_json({at, end, tz, source, kind, tier, payload})
49
+ hash = sha256( prev + "|" + seq + "|" + sha256(content) + "|" + recorded_at )
50
+ ```
51
+
52
+ `canonical_json` is RFC 8785 (JSON Canonicalization Scheme): keys sorted by UTF-16 code units, no whitespace, UTF-8, ES6 number serialisation, no NaN/Infinity. A logbook is **valid** when, taking every line from every file and ordering by `seq` (files partition by the month of `at`, so backfilled history lands in old files; file order is not chain order), every line's `seq` is the previous plus one, every `prev` equals the previous `hash`, every `hash` recomputes, and `logbook.json` `seq`/`head` match the last line.
53
+
54
+ Corrections are new lines. A source that revises an earlier record writes a new line with `payload.supersedes = "<id>"`. Nothing is ever rewritten or removed.
55
+
56
+ ## 4. Tiers
57
+
58
+ | Tier | Typical content | At rest |
59
+ |---|---|---|
60
+ | 1 | location, photo metadata, calendar, public activity | plain |
61
+ | 2 | notes, messages, decisions, confirmations, personal mail | encrypted with the owner's key (v0.2) |
62
+ | 3 | money, health | encrypted with the owner's key (v0.2) |
63
+
64
+ Derived data inherits the highest tier of its evidence. v0.1 conformance requires the field; v0.2 will define the encryption envelope for tiers 2–3 (`payload_enc` replacing `payload`, age/X25519 recipient = the owner's key).
65
+
66
+ ## 5. Payload profiles
67
+
68
+ The envelope is the standard. Payloads are versioned by `payload.schema` and proposed as RFCs in `rfcs/`. Seed profiles: `location/v1`, `photo/v1`, `event/v1`, `message/v1`, `transaction/v1`, `health-sample/v1`, `note/v1`. A logbook with unknown schemas is still valid.
69
+
70
+ ## 6. Conformance
71
+
72
+ An implementation is conformant when `verify` on `conformance/sample-logbook` reports valid and prints the head in `conformance/expected.json`, and when appending one line to a copy of it yields a logbook that still verifies. Level 2 conformance (v0.2) adds encryption. Two independent implementations must agree before v1.0 is frozen.
73
+
74
+ ## 7. What this spec does not say
75
+
76
+ Nothing about servers, databases, user interfaces, engines, agents, or how two logbooks exchange pages. Those are layers. The spec is finished when it is small enough to implement in an afternoon.
@@ -0,0 +1,39 @@
1
+ # Vision
2
+
3
+ ## One sentence
4
+
5
+ A logbook is a folder of plain files that records what happened to you, that only you hold, and that anything can plug into.
6
+
7
+ ## Three ideas, and only three
8
+
9
+ **The record.** Everything that happened to you, written down once, in files you own. Your phone, photos, calendar, messages and every other export you can get your hands on flow into one append-only, hash-chained log. Nothing is ever edited. Nothing is ever pruned. If every app you use disappeared tomorrow, the record stays.
10
+
11
+ **The recount.** The record reads your life back to you without your effort. Every day gets a page. Days become trips, trips become chapters; people, places, meals, decisions and achievements appear on their own. You only confirm, correct, and add a line in your own words. A diary asks you to write; a logbook writes you.
12
+
13
+ **The circle.** You hand a page to a named person, and they hand one back. Two logbooks, one shared moment, each side keeps its own words and photos. No audience, no feed, no counts — you see their side of a dinner because you were at the dinner.
14
+
15
+ ## What it refuses to have
16
+
17
+ The opposite of social media is not a feature; it is a list of things the product will never contain:
18
+
19
+ - no feed, no timeline of other people
20
+ - no followers, likes, reactions, or view counts
21
+ - no ranking, no algorithm choosing what you see
22
+ - no public-by-default; every share names a person
23
+ - no streaks, no scores, no metrics near people
24
+ - no engagement loop; there is one evening question and it can be ignored forever
25
+ - nothing leaves without a named recipient
26
+
27
+ ## Reveal, never reward
28
+
29
+ A logbook may *reveal* — your first time in a country, your hundredth flight hour, the year with the most dinners at home — and may never *reward*. Revealing invites gratitude; rewarding invites compulsion. That single line is the product philosophy, and it is the line social media crossed.
30
+
31
+ Life is an adventure that can only be replayed when it is logged, the way chess is a game because the board remembers every move. The logbook is the board. The adventure is yours.
32
+
33
+ ## Why "logbook"
34
+
35
+ Pilots and sailors keep logbooks: dated, factual, in order, never edited, kept for years because one day someone needs to know what actually happened. Computing borrowed the word — log files, the commit log, the write-ahead log — for an append-only record that is the source of truth from which everything else is derived. That is exactly the structure here. The name is not a metaphor from computing; it is the original object computing took the metaphor from, returned to its purpose: a person keeping a true record of a voyage.
36
+
37
+ ## Where it can go
38
+
39
+ A logbook is signed by a key only you hold. A long, verifiable record that belongs to a key is a stronger claim of identity than any platform can issue — not *who you are*, but *what happened to you*, proven by you. We are modest about this in year one. The first real protocol question is how two logbooks exchange a page. Get that right and the rest follows.
@@ -0,0 +1,9 @@
1
+ # Adapters
2
+
3
+ One adapter per source. `run(input_path, since) -> iterator[dict]` where each dict has the keys `at, end, tz, source, kind, tier, payload` (see SPEC §2) — everything except the chain fields, which the logbook adds on append.
4
+
5
+ Rules: pure by default (no network), never write to the source, never invent `tier` lower than the source deserves, fixture-tested with **synthetic** data only.
6
+
7
+ Planned first (ADR 0008): `google-takeout`, `apple-health`, `whatsapp`, then `email`.
8
+
9
+ Wanted — pick one and open an issue with the adapter template: immich, dawarich, strava, garmin, apple-fitness, eight-sleep, oura, withings, telegram, imessage, signal, gmail, ics-calendar, google-calendar, flighty, flightradar24, notion, obsidian, spotify, apple-music, letterboxd, goodreads, kindle-highlights, youtube-history, chrome-history, twitter-archive, instagram-export, bank-csv (generic, with per-bank mapping files), revolut, paypal, amazon-orders, uber, airbnb, vivino, steam, boat-passage logs.
@@ -0,0 +1,3 @@
1
+ # adapter: example
2
+
3
+ What export it reads, how to get that export from the source (menu path), which `kind`s and `payload.schema`s it produces, and what tier. Fixture in `fixture/` is synthetic.