flip-notebook 0.5.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 (64) hide show
  1. flip_notebook-0.5.0/.github/workflows/ci.yml +21 -0
  2. flip_notebook-0.5.0/.github/workflows/publish.yml +37 -0
  3. flip_notebook-0.5.0/.gitignore +20 -0
  4. flip_notebook-0.5.0/AGENTS.md +269 -0
  5. flip_notebook-0.5.0/CHANGELOG.md +138 -0
  6. flip_notebook-0.5.0/CONTRIBUTING.md +31 -0
  7. flip_notebook-0.5.0/LICENSE +21 -0
  8. flip_notebook-0.5.0/PKG-INFO +130 -0
  9. flip_notebook-0.5.0/README.md +115 -0
  10. flip_notebook-0.5.0/RELEASING.md +18 -0
  11. flip_notebook-0.5.0/SPEC.md +578 -0
  12. flip_notebook-0.5.0/docs/internals.md +131 -0
  13. flip_notebook-0.5.0/docs/okf-provenance-profile.md +89 -0
  14. flip_notebook-0.5.0/docs/quickstart.md +236 -0
  15. flip_notebook-0.5.0/docs/wiki-alignment.md +135 -0
  16. flip_notebook-0.5.0/llms.txt +17 -0
  17. flip_notebook-0.5.0/pyproject.toml +66 -0
  18. flip_notebook-0.5.0/src/flip/__init__.py +3 -0
  19. flip_notebook-0.5.0/src/flip/beat.py +742 -0
  20. flip_notebook-0.5.0/src/flip/claims.py +261 -0
  21. flip_notebook-0.5.0/src/flip/cli.py +731 -0
  22. flip_notebook-0.5.0/src/flip/doctor.py +624 -0
  23. flip_notebook-0.5.0/src/flip/export.py +211 -0
  24. flip_notebook-0.5.0/src/flip/ledgers.py +242 -0
  25. flip_notebook-0.5.0/src/flip/manifest.py +170 -0
  26. flip_notebook-0.5.0/src/flip/migrate.py +488 -0
  27. flip_notebook-0.5.0/src/flip/okf.py +279 -0
  28. flip_notebook-0.5.0/src/flip/pages.py +269 -0
  29. flip_notebook-0.5.0/src/flip/profiles/data-investigation.toml +5 -0
  30. flip_notebook-0.5.0/src/flip/profiles/engagement.toml +9 -0
  31. flip_notebook-0.5.0/src/flip/profiles/ledger.toml +5 -0
  32. flip_notebook-0.5.0/src/flip/profiles/research-review.toml +5 -0
  33. flip_notebook-0.5.0/src/flip/profiles/scout.toml +5 -0
  34. flip_notebook-0.5.0/src/flip/profiles.py +132 -0
  35. flip_notebook-0.5.0/src/flip/registry.py +87 -0
  36. flip_notebook-0.5.0/src/flip/rename.py +121 -0
  37. flip_notebook-0.5.0/src/flip/scaffold.py +80 -0
  38. flip_notebook-0.5.0/src/flip/sessions.py +126 -0
  39. flip_notebook-0.5.0/src/flip/skills/notebook-audit/SKILL.md +48 -0
  40. flip_notebook-0.5.0/src/flip/skills/notebook-create/SKILL.md +45 -0
  41. flip_notebook-0.5.0/src/flip/skills/notebook-handoff/SKILL.md +41 -0
  42. flip_notebook-0.5.0/src/flip/skills/notebook-lessons/SKILL.md +44 -0
  43. flip_notebook-0.5.0/src/flip/skills/notebook-log/SKILL.md +45 -0
  44. flip_notebook-0.5.0/src/flip/skills/notebook-source/SKILL.md +56 -0
  45. flip_notebook-0.5.0/src/flip/sources.py +341 -0
  46. flip_notebook-0.5.0/src/flip/util.py +170 -0
  47. flip_notebook-0.5.0/src/flip/views.py +410 -0
  48. flip_notebook-0.5.0/tests/test_beat.py +511 -0
  49. flip_notebook-0.5.0/tests/test_claims.py +389 -0
  50. flip_notebook-0.5.0/tests/test_cli.py +581 -0
  51. flip_notebook-0.5.0/tests/test_doctor.py +740 -0
  52. flip_notebook-0.5.0/tests/test_export.py +363 -0
  53. flip_notebook-0.5.0/tests/test_ledgers.py +308 -0
  54. flip_notebook-0.5.0/tests/test_manifest.py +221 -0
  55. flip_notebook-0.5.0/tests/test_migrate.py +453 -0
  56. flip_notebook-0.5.0/tests/test_okf.py +420 -0
  57. flip_notebook-0.5.0/tests/test_pages.py +194 -0
  58. flip_notebook-0.5.0/tests/test_registry.py +219 -0
  59. flip_notebook-0.5.0/tests/test_rename.py +80 -0
  60. flip_notebook-0.5.0/tests/test_scaffold.py +144 -0
  61. flip_notebook-0.5.0/tests/test_sessions.py +185 -0
  62. flip_notebook-0.5.0/tests/test_sources.py +521 -0
  63. flip_notebook-0.5.0/tests/test_views.py +447 -0
  64. flip_notebook-0.5.0/uv.lock +174 -0
@@ -0,0 +1,21 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [main]
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ matrix:
13
+ python-version: ["3.12", "3.13"]
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: astral-sh/setup-uv@v5
17
+ with:
18
+ python-version: ${{ matrix.python-version }}
19
+ - run: uv sync
20
+ - run: uv run ruff check src tests --output-format=github
21
+ - run: uv run pytest -q
@@ -0,0 +1,37 @@
1
+ # Publishes flip-notebook to PyPI via trusted publishing (OIDC — no stored
2
+ # API tokens).
3
+ #
4
+ # PREREQUISITE (one-time, on pypi.org): register a pending trusted publisher
5
+ # at PyPI → Account settings → Publishing with owner "lavallee", repo
6
+ # "flip", workflow "publish.yml", environment "pypi-flip-notebook". The
7
+ # GitHub environment is created automatically on first workflow run.
8
+ name: Publish to PyPI
9
+
10
+ on:
11
+ release:
12
+ types: [published]
13
+ workflow_dispatch: {}
14
+
15
+ jobs:
16
+ publish:
17
+ runs-on: ubuntu-latest
18
+ environment:
19
+ name: pypi-flip-notebook
20
+ url: https://pypi.org/p/flip-notebook
21
+ permissions:
22
+ id-token: write
23
+ steps:
24
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
25
+ - name: Install uv
26
+ uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6
27
+ with:
28
+ enable-cache: true
29
+ - name: Build
30
+ run: uv build
31
+ - name: Publish to PyPI
32
+ uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # release/v1
33
+ with:
34
+ # Idempotent re-runs: a version already on PyPI is skipped, not an
35
+ # error — needed when a partial publish is completed by
36
+ # re-dispatching after the pending publisher is registered.
37
+ skip-existing: true
@@ -0,0 +1,20 @@
1
+ # session/tool state
2
+ .gstack/
3
+
4
+ # local-only scratch — never commit
5
+ _private/
6
+ *.local.*
7
+
8
+ # generated artifacts
9
+ renders/
10
+ dist/
11
+
12
+ # python
13
+ .venv/
14
+ __pycache__/
15
+ *.egg-info/
16
+ .pytest_cache/
17
+ .ruff_cache/
18
+
19
+ # agent harness state
20
+ .claude/
@@ -0,0 +1,269 @@
1
+ # AGENTS.md — flip for agents
2
+
3
+ flip is a CLI and plain-file format for **reporter's notebooks**: research
4
+ corpora (sources, claims, decisions, questions, sessions) maintained by
5
+ humans and agents together.
6
+
7
+ A notebook is one directory and a conformant OKF v0.1 knowledge bundle: a
8
+ root `index.md` whose frontmatter is the manifest, `notebook.md` as prose
9
+ working memory, and **one markdown page per entity** with YAML frontmatter —
10
+ `references/`, `claims/`, `decisions/`, `questions/`, `sessions/`. Event
11
+ history is append-only JSONL under `log/` and `sources/`. Readable with
12
+ `less`, diffable with `git`, no service required. [SPEC.md](SPEC.md) is the
13
+ format; [docs/internals.md](docs/internals.md) is the code map; this file is
14
+ how you, an agent, should use it.
15
+
16
+ ## When to reach for flip
17
+
18
+ - You are doing research whose sources, reasoning, and claims must survive
19
+ your context window: capture into a notebook, don't summarize into the void.
20
+ - You are asked to "start a notebook," "log this," "capture that source,"
21
+ "verify the claims," or to pick up work someone else left in a directory
22
+ whose `index.md` frontmatter declares a `flip:` version.
23
+ - You produced LLM synthesis that later work will lean on. It is a **lead,
24
+ grade C, not evidence** — a notebook is where it gets promoted or killed.
25
+
26
+ If a directory (or any parent) holds an `index.md` with `flip:` in its
27
+ frontmatter, you are inside a notebook and every `flip` command works from
28
+ there — flip walks up to find the root. (A directory with `notebook.toml` is
29
+ a pre-0.4 notebook: run `flip migrate` first.)
30
+
31
+ ## The five-minute tour
32
+
33
+ Everything below is real output (paths shortened). Read commands take
34
+ `--json`.
35
+
36
+ ```console
37
+ $ flip new nj-schools --kind scout --title "NJ enrollment dip"
38
+ created scout notebook 'nj-schools' at /work/nj-schools
39
+ next: cd /work/nj-schools && flip log "started" — see `flip --help` for the toolkit
40
+
41
+ $ flip log "started scouting the angle"
42
+ logged 2026-07-10T19:59:41Z · agent:claude
43
+
44
+ $ flip add-source ./districts.csv --note "district enrollment table"
45
+ F1 · sources/raw/F1.csv · references/districts.md (grade ?)
46
+ judge it: flip grade F1 --grade A|B|C --independence original|republisher|derivative|self-interested
47
+
48
+ $ flip grade F1 --grade A --independence original --notes "state data, extracted ourselves"
49
+ F1 · grade A · original · fresh
50
+
51
+ $ flip claim add "District enrollment fell 4.2% since 2021" --source F1 --load-bearing
52
+ C1 asserted · sources: F1 · corroboration: 1
53
+
54
+ $ flip claim status C1 verified
55
+ C1 → verified · corroboration: 1
56
+
57
+ $ flip decide --question "Which county first?" --decision "Start with Essex" --why "largest enrollment swing"
58
+ D1 · Start with Essex
59
+
60
+ $ flip pass "2019 funding blog post" --reason "republishes state PR verbatim, no added data"
61
+ passed 2026-07-10T19:59:41Z · republishes state PR verbatim, no added data
62
+
63
+ $ flip question add "Does the fall predate the funding change?"
64
+ Q1 open · Does the fall predate the funding change?
65
+
66
+ $ flip show
67
+ nj-schools · scout · active · 2026-07-10
68
+
69
+ OPEN QUESTIONS
70
+ Q1 · Does the fall predate the funding change?
71
+
72
+ RECENT LOG
73
+ 2026-07-10T19:59:41Z · agent:claude · started scouting the angle
74
+
75
+ $ flip doctor
76
+ ok: no findings
77
+ ```
78
+
79
+ Every entity is a page whose **filename is a human slug and whose id is
80
+ immutable frontmatter**: the capture above created
81
+ `references/districts.md` with `id: F1` and `aliases: [F1]`. Cite ids in
82
+ prose as `[F1]`, `[C1]` — greppable both directions — and resolve them with
83
+ `flip open`:
84
+
85
+ ```console
86
+ $ flip open F1
87
+ /work/nj-schools/references/districts.md
88
+
89
+ $ flip rename F1 district-enrollment-table
90
+ F1: references/districts.md → references/district-enrollment-table.md
91
+ rewrote links in 2 file(s)
92
+ ```
93
+
94
+ `flip rename` is the **only sanctioned rename**: it moves the page (id and
95
+ aliases untouched, so `[F1]` cites keep resolving) and rewrites every
96
+ markdown link and `supports` path notebook-wide. Never `mv` a page yourself.
97
+ An unknown id fails helpfully:
98
+
99
+ ```console
100
+ $ flip open Z9
101
+ no page with id 'Z9' (known ids: C1, D1, F1, Q1)
102
+ ```
103
+
104
+ (Source ids use `P`/`A`/`F`/`T`/`S` prefixes by kind; `C#` claims, `D#`
105
+ decisions, `Q#` questions — prefixes are disjoint, so a bare `[F1]` or `[D2]`
106
+ cite is never ambiguous.) `flip doctor` tracks the profile's minimums: while
107
+ a notebook's status is `active` or `dormant`, missing required files are
108
+ WARNs (they appear with use — the first `flip decide` and `flip pass` create
109
+ a scout's); once status is `done`, `published`, or `archived`, they become
110
+ ERRORs.
111
+
112
+ When verification isn't earned, flip refuses and says what to do:
113
+
114
+ ```console
115
+ $ flip claim status C2 verified
116
+ cannot verify C2: 0 independent original source(s) of 1 required and no
117
+ grade-A source among its sources (sources: none); add independent original
118
+ sources to the claim or upgrade one to grade A via `flip grade`
119
+ ```
120
+
121
+ The rest of the surface: `flip source list` (every source at a glance:
122
+ `F1 · A/original/fresh · districts.csv · references/district-enrollment-table.md`),
123
+ `flip question list` / `flip question answer Q1 --note "..."`,
124
+ `flip session start|end` (working-episode pages under `sessions/`),
125
+ `flip profiles` (available kinds), `flip index` (per-user notebook registry),
126
+ `flip migrate` (v0.3 → v0.4 in place),
127
+ `flip export bag|csl|okf` (BagIt / CSL JSON / policy-filtered public bundle),
128
+ `flip show --claims|--stale`, and `--json` on every read command.
129
+
130
+ ## The contract — lineage rules you MUST honor (SPEC §6)
131
+
132
+ 1. **Capture before cite.** A page may only cite what the notebook has
133
+ custody of: a `references/` page backed by raw bytes under `sources/raw/`
134
+ and a provenance event. Never paste fetched text into the notebook as if
135
+ it were a source — `flip add-source` records bytes, hash, and provenance.
136
+ Dangling citations are legal but counted; `flip doctor` reports them.
137
+ 2. **Judgment is explicit and separate from capture.** Every capture opens at
138
+ grade `?`, which counts toward **nothing** — read the source, then
139
+ `flip grade` it. Capture is custody, not judgment.
140
+ 3. **LLM output is grade C until promoted.** Anything you synthesized — or
141
+ pulled from a retrieval service — enters as a lead in a session page or a
142
+ grade-`C` source. Under `citation_rule: public-terminus` every
143
+ load-bearing chain must end at a public, independently verifiable source.
144
+ 4. **Claims carry status, and verification is gated.** Assert claims with
145
+ `flip claim add --source <id>` the moment the work leans on them.
146
+ `verified` is refused until the profile's corroboration bar is met
147
+ (default: two independent original sources, or one grade-A primary),
148
+ counting judged sources only. Don't argue with the gate — go get
149
+ corroboration.
150
+ 5. **Generation is logged.** Wrap every LLM run or research sweep in
151
+ `flip session start` / `flip session end` — the reasoning chain is
152
+ evidence too.
153
+ 6. **Events append, views regenerate.** `log/*.jsonl`,
154
+ `sources/_provenance.jsonl`, and `derived/_derivations.jsonl` are
155
+ append-only: never edit, rewrite, or delete a line. `index.md` bodies and
156
+ `log.md` are **generated** — flip overwrites them on every mutating
157
+ command, so hand-edits there don't survive; edit pages and ledgers, not
158
+ listings.
159
+ 7. **The round-trip rule: preserve keys you don't own.** Entity pages are
160
+ edited by humans, editors, and other tools. When you edit one — by hand or
161
+ programmatically — change only the keys and prose you mean to change;
162
+ frontmatter keys you don't understand MUST survive, and so must the body.
163
+ flip's own commands obey this; so must you.
164
+ 8. **Attribution everywhere.** Every event and page records its `actor`. flip
165
+ auto-detects known agent harnesses, but be explicit:
166
+ `export FLIP_ACTOR="agent:claude"` (or `agent:<your-name>`). Humans are
167
+ `human:<name>`, tools `tool:<name>`.
168
+
169
+ Also: ids are never reused, even after retraction; never hand-edit anything
170
+ under `sources/raw/` (verbatim bytes, immutable — recapture instead); and
171
+ run `flip doctor` before finishing — fix every ERROR (doctor exits 1), read
172
+ every WARN and either fix it or note in the log why it stands.
173
+
174
+ ## Recipes
175
+
176
+ ### Start a notebook
177
+
178
+ ```bash
179
+ flip profiles # pick a kind: ledger|scout|research-review|engagement|data-investigation
180
+ flip new <slug> --kind scout --title "..."
181
+ cd <slug>
182
+ export FLIP_ACTOR="agent:claude"
183
+ flip log "started: <one-line mission>"
184
+ # fill in notebook.md's section stubs — 'The tip' and 'Hypotheses & falsifiers' first
185
+ flip doctor # expect missing-required WARNs until the profile's files exist through use
186
+ ```
187
+
188
+ Profiles require files that appear through use: on a fresh `scout`, doctor
189
+ WARNs (`missing-required decisions`, `missing-required log/passed.jsonl`)
190
+ until the first `flip decide` and `flip pass`; on a fresh `research-review`,
191
+ until `add-source`, `claim add`, and `session start` have each run once and
192
+ you've created `drafts/` yourself. The WARN lines name exactly what's
193
+ missing — and they harden into ERRORs the moment the manifest status becomes
194
+ `done`, `published`, or `archived` (SPEC §13: completion requirements, not
195
+ creation requirements).
196
+
197
+ ### Capture + grade a source
198
+
199
+ ```bash
200
+ flip add-source https://example.com/report --note "why captured" # runs your configured web fetcher
201
+ flip add-source ./filing.pdf # local file: builtin copy + hash
202
+ flip add-source doi:10.1234/abcd # paper: configured doi fetcher
203
+ # read it, then judge it — grading is a judgment, not a formality:
204
+ flip grade A1 --grade B --independence original --freshness fresh --notes "official docs; original publisher"
205
+ flip source list # audit: any grade "?" line is captured but unjudged
206
+ flip source list --json # same rows for machine consumption
207
+ ```
208
+
209
+ Each capture opens a `references/<slug>.md` page — custody and judgment in
210
+ frontmatter, your capture notes in the body. URL/DOI capture needs a
211
+ `[fetchers]` entry in `$FLIP_HOME/config.toml` (default `~/.flip/config.toml`)
212
+ — see [docs/quickstart.md](docs/quickstart.md). If the fetcher isn't
213
+ configured, flip's error shows the exact stanza to add.
214
+ `republisher`/`derivative` sources don't count toward corroboration — prefer
215
+ the original — and neither does anything still graded `?`.
216
+
217
+ ### Assert and verify a claim
218
+
219
+ ```bash
220
+ flip claim add "<one-sentence assertion>" --source A1 --source F2 --load-bearing
221
+ flip claim status C1 verified # refused until the profile's bar is met
222
+ flip claim status C1 needs-2nd # honest fallback while you hunt corroboration
223
+ flip claim list --status needs-2nd --json
224
+ ```
225
+
226
+ The claim page (`claims/<slug>.md`) carries `sources: [ids]` and a generated
227
+ `# Citations` block linking the reference pages; flip recomputes
228
+ `independent_corroboration` on status changes and doctor flags drift.
229
+
230
+ ### Record a session
231
+
232
+ Before an LLM run or research sweep:
233
+
234
+ ```bash
235
+ flip session start landscape-scan --model claude-fable-5 --tools web-search
236
+ # prints sessions/2026-07-10T2000-landscape-scan.md
237
+ # fill in its Goal / Prompt / Key outputs sections as you work
238
+ flip session end landscape-scan --summary "3 candidate districts; Essex strongest signal"
239
+ ```
240
+
241
+ Promote anything from the session the work will rely on: leads →
242
+ `flip add-source` + `flip grade`, follow-ups → `flip question add`, forks
243
+ resolved → `flip decide`, dead ends → `flip pass`.
244
+
245
+ ### Hand off
246
+
247
+ ```bash
248
+ flip doctor # fix ERRORs first
249
+ flip show # this is what the next reader sees
250
+ # write/refresh HANDOFF.md: state of play, open questions (Q#), claims
251
+ # needing work (C#), next actions — the cold-start view
252
+ flip log "handoff: <where things stand in one line>"
253
+ ```
254
+
255
+ ### Pick up a pre-0.4 notebook
256
+
257
+ ```bash
258
+ flip migrate # from anywhere inside it; finds the notebook.toml root
259
+ # migrated /work/legacy to v0.4 · 1 sources, 1 claims, 1 decisions, 1 questions, 1 sessions
260
+ flip doctor # audit the result; migration preserves ids and history
261
+ ```
262
+
263
+ ## Skills
264
+
265
+ Procedural checklists for these workflows ship in
266
+ [src/flip/skills/](src/flip/skills/) — `notebook-create`, `notebook-source`,
267
+ `notebook-log`, `notebook-audit`, `notebook-handoff`, `notebook-lessons` —
268
+ as plain `SKILL.md` files usable by any agent runtime, and as a
269
+ [spindle](https://github.com/lavallee/spindle) package named `flip`.
@@ -0,0 +1,138 @@
1
+ # Changelog
2
+
3
+ All notable changes to the flip spec and tooling are documented here.
4
+ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/);
5
+ versioning follows [Semantic Versioning](https://semver.org/).
6
+
7
+ ## [0.5.0] — 2026-07-10
8
+
9
+ ### Added
10
+ - **Beats** (SPEC §14): the grouping layer above notebooks. A beat is itself
11
+ an OKF bundle — `flip_beat:` manifest in its root `index.md`, a `beat.md`
12
+ mission page, and one **thread** page per line of attention (`TH#`, kind
13
+ `arc`/`vein`, weighted triage scores). `flip beat new / thread add|update|
14
+ drop / graduate / show / log`. Graduation scaffolds a child notebook under
15
+ `notebooks/`, back-links both ways (`links.beat: <beat>#<thread>`), and
16
+ records coverage; drops record the reason as negative coverage. Beat and
17
+ notebook commands resolve correctly from inside each other.
18
+ - Notebook doctor WARNs `broken-beat-link` when a manifest's `links.beat` no
19
+ longer resolves.
20
+ - Trusted-publishing workflow (`publish.yml`): GitHub releases publish
21
+ `flip-notebook` to PyPI via OIDC.
22
+ - [docs/okf-provenance-profile.md](docs/okf-provenance-profile.md): flip's
23
+ extension vocabulary written up as a draft OKF provenance profile.
24
+
25
+ ### Fixed
26
+ - File captures slug from the stem: `districts.csv` →
27
+ `references/districts.md` (was `districts-csv.md`; found dogfooding).
28
+
29
+ ## [0.4.0] — 2026-07-10
30
+
31
+ **A flip notebook is now natively an
32
+ [OKF v0.1](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md)
33
+ knowledge bundle** — flip becomes an extension profile of OKF (lineage rules
34
+ for LLM-built wikis, SPEC §6) rather than an exporter to it. Breaking
35
+ release; `flip migrate` converts v0.3 notebooks.
36
+
37
+ ### Changed (breaking)
38
+ - **Entities are pages.** Sources, claims, decisions, questions, and sessions
39
+ are one markdown file each with YAML frontmatter — the canonical record —
40
+ in `references/`, `claims/`, `decisions/`, `questions/`, `sessions/`.
41
+ The JSONL entity ledgers (`sources/ledger.jsonl`, `analysis/claims.jsonl`,
42
+ `log/decisions.jsonl`, `log/questions.jsonl`) are gone; event logs
43
+ (`log/log.jsonl`, `log/passed.jsonl`, `_provenance.jsonl`,
44
+ `_derivations.jsonl`) remain append-only JSONL sidecars.
45
+ - **Filenames are human slugs** (`references/lecun-jepa-keynote.md`); the
46
+ immutable compact id lives in frontmatter with `aliases: [<id>]`, so id
47
+ wikilinks resolve in Obsidian-style editors. `flip rename` moves a page and
48
+ rewrites links; `flip open <id>` resolves ids.
49
+ - **The manifest moved into the root `index.md` frontmatter** (OKF's
50
+ sanctioned identity slot); `notebook.toml` is retired. Policy keys are
51
+ flat (`visibility`, `source_trail_public`, …) and edit cleanly as
52
+ Obsidian properties.
53
+ - **`index.md` bodies and `log.md` are generated views**, regenerated on
54
+ every mutating command.
55
+ - **`flip export okf` is now a policy filter** (visibility gate + source-
56
+ trail stripping) over an already-conformant bundle, not a format transform.
57
+ - PyYAML joins click as a core dependency (faithful reading of human/editor-
58
+ authored frontmatter); flip writes a deterministic strict subset.
59
+
60
+ ### Security
61
+ - Stripped exports (`source_trail_public: false`) withhold **derived views of
62
+ withheld data**, not just the data: `log.md` (a rendering of the withheld
63
+ work log), reference titles/descriptions (capture notes, private file
64
+ basenames), and any prior export or bag nested inside the notebook are all
65
+ excluded; the references listing is regenerated from the stripped pages.
66
+ Known residual: a claim's `# Citations` label text is frozen at claim-add
67
+ time and ships as written.
68
+
69
+ ### Added
70
+ - **The flip profile for OKF** (SPEC §6): eight lineage rules — capture
71
+ before cite, explicit judgment, status-carrying claims, logged generation,
72
+ append-only events, key preservation, attribution, render discipline —
73
+ plus the extension frontmatter vocabulary.
74
+ - **Round-trip guarantee**: flip preserves frontmatter keys and bodies it
75
+ doesn't own, so humans (Obsidian) and other agents can edit the same
76
+ files (SPEC §12).
77
+ - `flip open`, `flip rename`, `flip migrate`; doctor checks for OKF
78
+ conformance, id/alias integrity, dangling citations, corroboration drift.
79
+
80
+ ## [0.3.0] — 2026-07-10
81
+
82
+ ### Added
83
+ - **Reference implementation**: the `flip` CLI (`new`, `add-source`, `grade`,
84
+ `log`, `decide`, `pass`, `question`, `claim`, `session`, `show`, `doctor`,
85
+ `index`, `export`, `profiles`, `source list`, `question list`) as a Python
86
+ package (`flip-notebook`, stdlib + click, no network in the core), with a
87
+ full test suite and CI.
88
+ - **OKF export** (`flip export okf`): project a notebook as an
89
+ [Open Knowledge Format v0.1](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md)
90
+ knowledge bundle — sources as `references/` concepts with custody
91
+ frontmatter, claims with `# Citations`, decisions, `log.md`, policy-gated
92
+ source trail, and `--announce` marker blocks for AGENTS.md. Design:
93
+ [docs/wiki-alignment.md](docs/wiki-alignment.md).
94
+ - **Agent-learnability layer**: `AGENTS.md`, `llms.txt`,
95
+ [docs/quickstart.md](docs/quickstart.md), and six procedural skills under
96
+ `src/flip/skills/` (also declared as a spindle package in `pyproject.toml`).
97
+ - BagIt export (`flip export bag`), CSL JSON export (`flip export csl`),
98
+ per-user notebook registry (`flip index`).
99
+
100
+ ### Changed
101
+ - **Breaking (spec §3/§9):** file/dataset source ids now use the `F#` prefix;
102
+ `D#` is reserved for decisions (the two collided in prose cites).
103
+ - **Spec §7.2 hardened:** ungraded (`?`) sources never count toward claim
104
+ corroboration — capture is custody, not judgment.
105
+ - **Spec §12:** profile minimums are completion requirements — missing
106
+ required files WARN while a notebook is `active`/`dormant` and ERROR once
107
+ it is `done`/`published`/`archived`.
108
+
109
+ ### Fixed
110
+ - Ten findings from an adversarial review of the initial implementation,
111
+ including manifest round-trip data loss, TOML escaping that could brick a
112
+ notebook, session-slug suffix collisions, corroboration dedupe, and BagIt
113
+ symlink handling.
114
+
115
+ ## [0.2.0] — 2026-07-09
116
+
117
+ ### Added
118
+ - **Beats** (§13): a grouping layer above notebooks — a standing mission with
119
+ a thread ledger that spawns notebooks as threads get real.
120
+ - **Detached notebooks** (§3): convention for notebooks whose visibility
121
+ exceeds their host repo's (private notebook, public repo).
122
+ - **Pluggable fetchers** (§14): `flip add-source` routes through commands
123
+ registered in `~/.flip/config.toml`; only `builtin:copy` is built in.
124
+ - **Dependency-free registry** (§14): `flip index` writes a plain per-user
125
+ `~/.flip/index.jsonl` by scanning; no services.
126
+
127
+ ### Changed
128
+ - Removed the `agent-beat` profile; that territory belongs to the beat layer.
129
+ - Hardened the no-proprietary-dependencies commitment throughout (§15).
130
+
131
+ ## [0.1.0] — 2026-07-09
132
+
133
+ ### Added
134
+ - Initial spec draft: principles, directory layout, manifest, source custody +
135
+ capture provenance, source-quality model (reliability/credibility split),
136
+ derivations log, claim ledger, work/decision/negative-evidence/session logs,
137
+ IDs, hot/cold views, drafts and renders, profiles, CLI sketch, skills layer,
138
+ git conventions, interop exports.
@@ -0,0 +1,31 @@
1
+ # Contributing to flip
2
+
3
+ flip is at the **spec stage** — the highest-value contributions right now are
4
+ critiques of the format itself: places where the spec would fight real
5
+ reporting or research practice, gaps in the provenance model, profile shapes
6
+ you'd need that don't fit.
7
+
8
+ ## How
9
+
10
+ - **Open an issue** for design discussion — the smaller and more concrete the
11
+ scenario, the better ("here's a capture case the provenance record can't
12
+ express" beats "custody should be more flexible").
13
+ - **PRs against SPEC.md** are welcome for wording, structure, and fixes. For
14
+ substantive design changes, open an issue first; accepted changes land with
15
+ a CHANGELOG entry and, when they alter meaning, a version bump.
16
+ - Spec changes that alter the meaning of existing files on disk (ledger
17
+ fields, status enums, layout) are **breaking** and versioned accordingly —
18
+ notebooks in the wild must never be silently reinterpreted.
19
+
20
+ ## Style
21
+
22
+ - Plain text first; examples over abstractions; every normative rule should
23
+ say what failure it prevents.
24
+ - Keep the core small. New requirements belong in a profile unless every
25
+ notebook needs them.
26
+
27
+ ## Code (upcoming)
28
+
29
+ The `flip` CLI will live in this repo. Once it lands: tests required for
30
+ behavior changes, CI must be green, and the library core stays
31
+ filesystem-only — no network calls, no LLM calls, no required services.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Marc Lavallee
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,130 @@
1
+ Metadata-Version: 2.4
2
+ Name: flip-notebook
3
+ Version: 0.5.0
4
+ Summary: Reporter's notebooks: git-friendly research corpora maintained by humans and agents
5
+ Project-URL: Homepage, https://github.com/lavallee/flip
6
+ Project-URL: Repository, https://github.com/lavallee/flip
7
+ Author: Marc Lavallee
8
+ License: MIT
9
+ License-File: LICENSE
10
+ Keywords: agents,journalism,knowledge,notebook,provenance,research
11
+ Requires-Python: >=3.12
12
+ Requires-Dist: click>=8.1
13
+ Requires-Dist: pyyaml>=6.0
14
+ Description-Content-Type: text/markdown
15
+
16
+ # flip
17
+
18
+ Format and tooling for **reporter's notebooks** — source-controlled research
19
+ corpora created and maintained by any mix of humans and agents.
20
+
21
+ A flip notebook **is an
22
+ [Open Knowledge Format](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md)
23
+ (OKF v0.1) knowledge bundle at rest**: a directory of markdown pages with
24
+ YAML frontmatter, an `index.md` root, and a generated `log.md`. Any OKF
25
+ consumer can browse one; any markdown editor can edit one. What flip adds is
26
+ an **extension profile for lineage** — the discipline the LLM-wiki pattern
27
+ (Karpathy's framing, OKF, LangChain's OpenWiki) deliberately leaves open:
28
+ custody of the sources you rely on (local bytes, hashed at capture),
29
+ explicit source grading, claims gated by a corroboration bar, work and
30
+ LLM-session logs, and a timestamped history. A wiki tells an agent what we
31
+ know; a notebook can prove where it came from.
32
+
33
+ Humans and agents work **in the same files**. Every source, claim, decision,
34
+ question, and session is one page with a human-slug filename and its
35
+ immutable id in frontmatter — open the notebook as an
36
+ [Obsidian](https://obsidian.md) vault and frontmatter is the properties
37
+ panel, `aliases` make `[[A3]]`-style id links resolve, and relative links
38
+ light up the graph view. Re-grading a source from the properties panel is a
39
+ legitimate flip operation; `flip doctor` validates after the fact instead of
40
+ gatekeeping before.
41
+
42
+ **[SPEC.md](SPEC.md)** has the full format: directory layout, the manifest
43
+ (root `index.md` frontmatter), source pages and capture provenance, claims
44
+ and the verification bar, logs and sessions, the flip lineage profile
45
+ (SPEC §6), profiles, the beat layer, the CLI, skills, and the integration
46
+ contract.
47
+
48
+ Design commitments:
49
+
50
+ - **Plain files, no services.** Markdown + YAML frontmatter for entities,
51
+ append-only JSONL for events. Readable with `less`, diffable with `git`,
52
+ browsable by any OKF consumer or markdown tool. Standards (BagIt, CSL,
53
+ RO-Crate, Web Annotation) are generated exports, never the canonical
54
+ format — except OKF, which the notebook natively is.
55
+ - **No proprietary dependencies.** Capture tools, retrieval services, and
56
+ render targets are all pluggable; a notebook is intelligible from its
57
+ local files alone.
58
+ - **Custody first.** Local archival copies with hashes at capture; processing
59
+ is logged and re-runnable; LLM output is a lead, not evidence, until
60
+ promoted through `references/` and graded.
61
+ - **Graceful co-editing.** One entity per file, metadata in frontmatter,
62
+ prose in the body; tools preserve frontmatter keys they don't own, so
63
+ human edits and agent edits round-trip through each other.
64
+
65
+ ## Install
66
+
67
+ ```bash
68
+ uv tool install flip-notebook # or: pipx install flip-notebook
69
+ ```
70
+
71
+ From source: `git clone https://github.com/lavallee/flip && cd flip && uv sync`,
72
+ then `uv run flip --help`. Python 3.12+; the core is stdlib + click + PyYAML.
73
+
74
+ ## Quickstart
75
+
76
+ ```bash
77
+ flip new nj-schools --kind scout --title "NJ enrollment dip"
78
+ cd nj-schools
79
+ flip add-source ./districts.csv --note "district enrollment table"
80
+ # F1 · sources/raw/F1.csv · references/districts.md (grade ?)
81
+ flip grade F1 --grade A --independence original # judge it after reading
82
+ flip claim add "Enrollment fell 4.2% since 2021" --source F1 --load-bearing
83
+ # C1 asserted · sources: F1 · corroboration: 1
84
+ flip claim status C1 verified # gated: refused until the corroboration bar is met
85
+ flip decide --question "Which county first?" --decision "Start with Essex" --why "largest swing"
86
+ flip pass "2019 funding blog post" --reason "republishes state PR verbatim"
87
+ flip show # the hot view: open questions, claims needing work, recent log
88
+ flip doctor # lint: OKF conformance, profile minimums, verification bar
89
+ ```
90
+
91
+ Filenames are human slugs (`references/districts.md`); the immutable id
92
+ (`F1`) lives in frontmatter. `flip open F1` resolves an id to its page;
93
+ `flip rename F1 district-enrollment-table` renames the file and rewrites
94
+ every link to it. `flip migrate` upgrades a pre-0.4 notebook in place.
95
+
96
+ URL and DOI capture route through fetchers you configure (e.g.
97
+ [SingleFile](https://github.com/gildas-lormeau/single-file-cli) for web
98
+ pages) — see [docs/quickstart.md](docs/quickstart.md) for the walkthrough,
99
+ fetcher config, profiles, and the Obsidian setup.
100
+
101
+ ## For agents
102
+
103
+ Notebooks are built to be maintained by humans and agents together:
104
+
105
+ - **[AGENTS.md](AGENTS.md)** — the five-minute tour, the lineage rules
106
+ agents must honor (capture before cite, grade-C-until-promoted, the
107
+ verification bar, the round-trip rule, `flip doctor`, `FLIP_ACTOR`), and
108
+ task recipes.
109
+ - **[llms.txt](llms.txt)** — doc map for LLM consumption.
110
+ - **[src/flip/skills/](src/flip/skills/)** — procedural skills
111
+ (`notebook-create`, `notebook-source`, `notebook-log`, `notebook-audit`,
112
+ `notebook-handoff`, `notebook-lessons`) as plain `SKILL.md` files usable by
113
+ any agent runtime. The skills also ship as a
114
+ [spindle](https://github.com/lavallee/spindle) package named `flip`.
115
+
116
+ Status: spec draft v0.5 — notebooks are native OKF v0.1 bundles. The CLI
117
+ covers the full surface (`new`, `add-source`, `grade`, `log`, `decide`,
118
+ `pass`, `question`, `claim`, `session`, `show`, `open`, `rename`, `doctor`,
119
+ `index`, `migrate`, `export bag|csl|okf`), plus **beats** — the standing
120
+ layer above notebooks (`flip beat new / thread add / graduate / show`): a
121
+ mission with weighted-triage threads that graduate into notebooks and keep
122
+ cross-notebook coverage memory. `flip migrate` converts v0.3 notebooks in
123
+ place. See [docs/wiki-alignment.md](docs/wiki-alignment.md) for how flip
124
+ relates to OKF and OpenWiki, and
125
+ [docs/okf-provenance-profile.md](docs/okf-provenance-profile.md) for flip's
126
+ vocabulary as a draft OKF provenance profile. Next: an Obsidian plugin
127
+ surfacing doctor findings inline.
128
+
129
+ Contributions welcome — see [CONTRIBUTING.md](CONTRIBUTING.md). Changes are
130
+ tracked in [CHANGELOG.md](CHANGELOG.md). [MIT licensed](LICENSE).