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.
- flip_notebook-0.5.0/.github/workflows/ci.yml +21 -0
- flip_notebook-0.5.0/.github/workflows/publish.yml +37 -0
- flip_notebook-0.5.0/.gitignore +20 -0
- flip_notebook-0.5.0/AGENTS.md +269 -0
- flip_notebook-0.5.0/CHANGELOG.md +138 -0
- flip_notebook-0.5.0/CONTRIBUTING.md +31 -0
- flip_notebook-0.5.0/LICENSE +21 -0
- flip_notebook-0.5.0/PKG-INFO +130 -0
- flip_notebook-0.5.0/README.md +115 -0
- flip_notebook-0.5.0/RELEASING.md +18 -0
- flip_notebook-0.5.0/SPEC.md +578 -0
- flip_notebook-0.5.0/docs/internals.md +131 -0
- flip_notebook-0.5.0/docs/okf-provenance-profile.md +89 -0
- flip_notebook-0.5.0/docs/quickstart.md +236 -0
- flip_notebook-0.5.0/docs/wiki-alignment.md +135 -0
- flip_notebook-0.5.0/llms.txt +17 -0
- flip_notebook-0.5.0/pyproject.toml +66 -0
- flip_notebook-0.5.0/src/flip/__init__.py +3 -0
- flip_notebook-0.5.0/src/flip/beat.py +742 -0
- flip_notebook-0.5.0/src/flip/claims.py +261 -0
- flip_notebook-0.5.0/src/flip/cli.py +731 -0
- flip_notebook-0.5.0/src/flip/doctor.py +624 -0
- flip_notebook-0.5.0/src/flip/export.py +211 -0
- flip_notebook-0.5.0/src/flip/ledgers.py +242 -0
- flip_notebook-0.5.0/src/flip/manifest.py +170 -0
- flip_notebook-0.5.0/src/flip/migrate.py +488 -0
- flip_notebook-0.5.0/src/flip/okf.py +279 -0
- flip_notebook-0.5.0/src/flip/pages.py +269 -0
- flip_notebook-0.5.0/src/flip/profiles/data-investigation.toml +5 -0
- flip_notebook-0.5.0/src/flip/profiles/engagement.toml +9 -0
- flip_notebook-0.5.0/src/flip/profiles/ledger.toml +5 -0
- flip_notebook-0.5.0/src/flip/profiles/research-review.toml +5 -0
- flip_notebook-0.5.0/src/flip/profiles/scout.toml +5 -0
- flip_notebook-0.5.0/src/flip/profiles.py +132 -0
- flip_notebook-0.5.0/src/flip/registry.py +87 -0
- flip_notebook-0.5.0/src/flip/rename.py +121 -0
- flip_notebook-0.5.0/src/flip/scaffold.py +80 -0
- flip_notebook-0.5.0/src/flip/sessions.py +126 -0
- flip_notebook-0.5.0/src/flip/skills/notebook-audit/SKILL.md +48 -0
- flip_notebook-0.5.0/src/flip/skills/notebook-create/SKILL.md +45 -0
- flip_notebook-0.5.0/src/flip/skills/notebook-handoff/SKILL.md +41 -0
- flip_notebook-0.5.0/src/flip/skills/notebook-lessons/SKILL.md +44 -0
- flip_notebook-0.5.0/src/flip/skills/notebook-log/SKILL.md +45 -0
- flip_notebook-0.5.0/src/flip/skills/notebook-source/SKILL.md +56 -0
- flip_notebook-0.5.0/src/flip/sources.py +341 -0
- flip_notebook-0.5.0/src/flip/util.py +170 -0
- flip_notebook-0.5.0/src/flip/views.py +410 -0
- flip_notebook-0.5.0/tests/test_beat.py +511 -0
- flip_notebook-0.5.0/tests/test_claims.py +389 -0
- flip_notebook-0.5.0/tests/test_cli.py +581 -0
- flip_notebook-0.5.0/tests/test_doctor.py +740 -0
- flip_notebook-0.5.0/tests/test_export.py +363 -0
- flip_notebook-0.5.0/tests/test_ledgers.py +308 -0
- flip_notebook-0.5.0/tests/test_manifest.py +221 -0
- flip_notebook-0.5.0/tests/test_migrate.py +453 -0
- flip_notebook-0.5.0/tests/test_okf.py +420 -0
- flip_notebook-0.5.0/tests/test_pages.py +194 -0
- flip_notebook-0.5.0/tests/test_registry.py +219 -0
- flip_notebook-0.5.0/tests/test_rename.py +80 -0
- flip_notebook-0.5.0/tests/test_scaffold.py +144 -0
- flip_notebook-0.5.0/tests/test_sessions.py +185 -0
- flip_notebook-0.5.0/tests/test_sources.py +521 -0
- flip_notebook-0.5.0/tests/test_views.py +447 -0
- 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).
|