datanotes 3.4.0 → 3.4.1

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.
@@ -314,7 +314,7 @@ Answer:
314
314
  "op": "create_table",
315
315
  "planned_texts": ["datanotes/metastore.yaml"],
316
316
  "commits": [{ "table": "main.public.film", "version": 0, "operation": "CREATE TABLE" }],
317
- "migration_id": "20261024T063914-create_table-create-table-main-public-film"
317
+ "migration_id": "20261024T081156-create_table-create-table-main-public-film"
318
318
  }
319
319
  ```
320
320
 
@@ -359,7 +359,7 @@ Answer (70 lines)
359
359
  "path": "Films/Charade.md",
360
360
  "set": {
361
361
  "table": "main.public.film",
362
- "id": "01a16ca2-8b15-7b17-9621-47ebd428dcb2",
362
+ "id": "01a16cf7-6b19-78cd-bae8-ca1a8fd27c66",
363
363
  "director": "Stanley Donen",
364
364
  "title": "Charade"
365
365
  },
@@ -369,7 +369,7 @@ Answer (70 lines)
369
369
  "path": "Films/His Girl Friday.md",
370
370
  "set": {
371
371
  "table": "main.public.film",
372
- "id": "01a16ca2-8b15-736e-b2e9-b44812311845",
372
+ "id": "01a16cf7-6b19-7117-90e4-2b59555b974a",
373
373
  "director": "Howard Hawks",
374
374
  "title": "His Girl Friday"
375
375
  },
@@ -379,7 +379,7 @@ Answer (70 lines)
379
379
  "path": "Films/Metropolis.md",
380
380
  "set": {
381
381
  "table": "main.public.film",
382
- "id": "01a16ca2-8b16-7de3-b3c7-f99fea697aef",
382
+ "id": "01a16cf7-6b19-73f5-a95f-7200d392529b",
383
383
  "director": "Fritz Lang",
384
384
  "title": "Metropolis"
385
385
  },
@@ -389,7 +389,7 @@ Answer (70 lines)
389
389
  "path": "Films/Nosferatu.md",
390
390
  "set": {
391
391
  "table": "main.public.film",
392
- "id": "01a16ca2-8b16-7f5e-a304-e715a1815b66",
392
+ "id": "01a16cf7-6b19-74d9-a8c2-353ae0902e8c",
393
393
  "director": "F. W. Murnau",
394
394
  "title": "Nosferatu"
395
395
  },
@@ -399,7 +399,7 @@ Answer (70 lines)
399
399
  "path": "Films/The Gold Rush.md",
400
400
  "set": {
401
401
  "table": "main.public.film",
402
- "id": "01a16ca2-8b16-747f-9e49-aefd3f27fd58",
402
+ "id": "01a16cf7-6b19-7a60-b0ac-0a9dcdc412f1",
403
403
  "director": "Charlie Chaplin",
404
404
  "title": "The Gold Rush"
405
405
  },
@@ -458,7 +458,7 @@ Answer (73 lines)
458
458
  "path": "Films/Charade.md",
459
459
  "set": {
460
460
  "table": "main.public.film",
461
- "id": "01a16ca2-8b18-7e55-9cbc-a983a43ae96c",
461
+ "id": "01a16cf7-6b1e-7993-9c87-2ed68d76eba0",
462
462
  "director": "Stanley Donen",
463
463
  "title": "Charade"
464
464
  },
@@ -468,7 +468,7 @@ Answer (73 lines)
468
468
  "path": "Films/His Girl Friday.md",
469
469
  "set": {
470
470
  "table": "main.public.film",
471
- "id": "01a16ca2-8b18-739c-9058-e32e9f3a61d4",
471
+ "id": "01a16cf7-6b1e-79db-8bd7-c55a21c2d29f",
472
472
  "director": "Howard Hawks",
473
473
  "title": "His Girl Friday"
474
474
  },
@@ -478,7 +478,7 @@ Answer (73 lines)
478
478
  "path": "Films/Metropolis.md",
479
479
  "set": {
480
480
  "table": "main.public.film",
481
- "id": "01a16ca2-8b18-71f0-92e4-4e2492953fa5",
481
+ "id": "01a16cf7-6b1e-7e74-9fb2-5f094a71a39f",
482
482
  "director": "Fritz Lang",
483
483
  "title": "Metropolis"
484
484
  },
@@ -488,7 +488,7 @@ Answer (73 lines)
488
488
  "path": "Films/Nosferatu.md",
489
489
  "set": {
490
490
  "table": "main.public.film",
491
- "id": "01a16ca2-8b18-78be-9435-87eca4fa962e",
491
+ "id": "01a16cf7-6b1e-79e9-b36d-92f76a21ce59",
492
492
  "director": "F. W. Murnau",
493
493
  "title": "Nosferatu"
494
494
  },
@@ -498,7 +498,7 @@ Answer (73 lines)
498
498
  "path": "Films/The Gold Rush.md",
499
499
  "set": {
500
500
  "table": "main.public.film",
501
- "id": "01a16ca2-8b18-76bd-b55f-ba6aadec67b1",
501
+ "id": "01a16cf7-6b1e-7d6d-8c78-3104c4071c47",
502
502
  "director": "Charlie Chaplin",
503
503
  "title": "The Gold Rush"
504
504
  },
@@ -519,7 +519,7 @@ Answer (73 lines)
519
519
  }
520
520
  ],
521
521
  "commits": [{ "table": "main.public.film", "version": 1, "operation": "ADOPT ROWS" }],
522
- "migration_id": "20261024T063914-adopt_rows-adopt-5-notes-into-film"
522
+ "migration_id": "20261024T081156-adopt_rows-adopt-5-notes-into-film"
523
523
  }
524
524
  ```
525
525
 
@@ -536,7 +536,7 @@ Answer:
536
536
  ```markdown
537
537
  ---
538
538
  table: main.public.film
539
- id: 01a16ca2-8b18-7e55-9cbc-a983a43ae96c
539
+ id: 01a16cf7-6b1e-7993-9c87-2ed68d76eba0
540
540
  year: 1963
541
541
  minutes: 113
542
542
  status: watched
@@ -623,7 +623,7 @@ Answer:
623
623
  "files_created": 1,
624
624
  "planned_creates": ["datanotes/main/public/film/Battleship Potemkin.md"],
625
625
  "commits": [{ "table": "main.public.film", "version": 2, "operation": "WRITE" }],
626
- "migration_id": "20261024T063914-insert_row-insert-into-film"
626
+ "migration_id": "20261024T081156-insert_row-insert-into-film"
627
627
  }
628
628
  ```
629
629
 
@@ -655,7 +655,7 @@ Answer:
655
655
  "op": "add_column",
656
656
  "planned_texts": ["datanotes/metastore.yaml"],
657
657
  "commits": [{ "table": "main.public.film", "version": 4, "operation": "ADD COLUMNS" }],
658
- "migration_id": "20261024T063915-add_column-add-column-added_by-to-film"
658
+ "migration_id": "20261024T081158-add_column-add-column-added_by-to-film"
659
659
  }
660
660
  ```
661
661
 
@@ -683,7 +683,7 @@ Answer:
683
683
  "files_created": 1,
684
684
  "planned_creates": ["datanotes/main/public/film/Night of the Living Dead.md"],
685
685
  "commits": [{ "table": "main.public.film", "version": 5, "operation": "WRITE" }],
686
- "migration_id": "20261024T063915-insert_row-insert-into-film"
686
+ "migration_id": "20261024T081158-insert_row-insert-into-film"
687
687
  }
688
688
  ```
689
689
 
@@ -692,7 +692,7 @@ Answer:
692
692
  ```markdown
693
693
  ---
694
694
  table: main.public.film
695
- id: 01a16ca2-915b-736c-a394-c98699327151
695
+ id: 01a16cf7-71f8-7c36-a392-61386c267a0e
696
696
  director: George A. Romero
697
697
  minutes: 96
698
698
  status: to watch
@@ -734,7 +734,7 @@ Answer:
734
734
  ```markdown
735
735
  ---
736
736
  table: main.public.film
737
- id: 01a16ca2-943a-7248-9a53-5c7f7532b5af
737
+ id: 01a16cf7-74bb-7a3e-ad0e-2dac8433ce30
738
738
  year: 1924
739
739
  minutes: 45
740
740
  status: to watch
@@ -762,7 +762,7 @@ Answer:
762
762
  "op": "alter_table",
763
763
  "planned_texts": ["datanotes/metastore.yaml"],
764
764
  "commits": [{ "table": "main.public.film", "version": 7, "operation": "ALTER TABLE" }],
765
- "migration_id": "20261024T063918-alter_table-alter-table-main-public-film"
765
+ "migration_id": "20261024T081200-alter_table-alter-table-main-public-film"
766
766
  }
767
767
  ```
768
768
 
@@ -825,7 +825,7 @@ This is the table as you inferred, corrected and extended it on this page. Its d
825
825
 
826
826
  ```yaml
827
827
  # Metastore (Datanotes): catalogs, schemas, tables, columns, views.
828
- id: 01a16ca2-8b02-76f7-8686-40530eaf4e87
828
+ id: 01a16cf7-6b02-7b71-b2d6-cede5690ed1f
829
829
  config:
830
830
  history: true
831
831
 
@@ -31,7 +31,7 @@ Answer:
31
31
  "files_created": 1,
32
32
  "planned_creates": ["datanotes/main/public/film/Metropolis.md"],
33
33
  "commits": [{ "table": "main.public.film", "version": 1, "operation": "WRITE" }],
34
- "migration_id": "20261024T063903-insert_row-insert-into-film"
34
+ "migration_id": "20261024T081147-insert_row-insert-into-film"
35
35
  }
36
36
  ```
37
37
 
@@ -40,7 +40,7 @@ Answer:
40
40
  ```markdown
41
41
  ---
42
42
  table: main.public.film
43
- id: 01a16ca2-615c-78e9-af82-5d7ee065ac91
43
+ id: 01a16cf7-4642-7759-8b98-011e31e573c9
44
44
  title: Metropolis
45
45
  year: 1927
46
46
  minutes: 153
@@ -103,7 +103,7 @@ Answer:
103
103
  }
104
104
  ],
105
105
  "commits": [{ "table": "main.public.film", "version": 6, "operation": "UPDATE" }],
106
- "migration_id": "20261024T063907-update_row-update-film"
106
+ "migration_id": "20261024T081151-update_row-update-film"
107
107
  }
108
108
  ```
109
109
 
@@ -174,7 +174,7 @@ Answer:
174
174
  }
175
175
  ],
176
176
  "commits": [{ "table": "main.public.film", "version": 8, "operation": "UPDATE" }],
177
- "migration_id": "20261024T063907-update_row-update-film-3",
177
+ "migration_id": "20261024T081151-update_row-update-film-3",
178
178
  "ambiguous_mentions": [
179
179
  {
180
180
  "path": "datanotes/main/public/film/Nosferatu.md",
@@ -193,7 +193,7 @@ Answer:
193
193
  ```markdown
194
194
  ---
195
195
  table: main.public.film
196
- id: 01a16ca2-718e-7219-9638-3d26346a9a88
196
+ id: 01a16cf7-5635-75b3-8e95-68aa1e5d8b03
197
197
  title: Nosferatu
198
198
  year: 1922
199
199
  status: watched
@@ -246,7 +246,7 @@ Answer:
246
246
  }
247
247
  ],
248
248
  "commits": [{ "table": "main.public.film", "version": 9, "operation": "UPDATE" }],
249
- "migration_id": "20261024T063907-update_row-update-film-4"
249
+ "migration_id": "20261024T081151-update_row-update-film-4"
250
250
  }
251
251
  ```
252
252
 
@@ -332,7 +332,7 @@ Answer:
332
332
  }
333
333
  ],
334
334
  "commits": [{ "table": "main.public.film", "version": 10, "operation": "UPDATE" }],
335
- "migration_id": "20261024T063907-update_rows-update-film"
335
+ "migration_id": "20261024T081151-update_rows-update-film"
336
336
  }
337
337
  ```
338
338
 
@@ -370,7 +370,7 @@ Answer:
370
370
  ],
371
371
  "planned_creates": ["datanotes/main/public/film/Battleship Potemkin.md"],
372
372
  "commits": [{ "table": "main.public.film", "version": 11, "operation": "MERGE" }],
373
- "migration_id": "20261024T063907-merge_rows-merge-2-rows-into-film"
373
+ "migration_id": "20261024T081151-merge_rows-merge-2-rows-into-film"
374
374
  }
375
375
  ```
376
376
 
@@ -431,7 +431,7 @@ Answer:
431
431
  }
432
432
  ],
433
433
  "commits": [{ "table": "main.public.film", "version": 12, "operation": "DELETE" }],
434
- "migration_id": "20261024T063907-delete_rows-archive-1-rows-of-film"
434
+ "migration_id": "20261024T081151-delete_rows-archive-1-rows-of-film"
435
435
  }
436
436
  ```
437
437
 
@@ -568,6 +568,6 @@ Answer (51 lines)
568
568
  { "table": "main.public.film", "version": 22, "operation": "MOVE ROWS" },
569
569
  { "table": "main.public.watchlist", "version": 1, "operation": "MOVE ROWS" }
570
570
  ],
571
- "migration_id": "20261024T063907-move_rows-move-4-rows-from-film-to-watch"
571
+ "migration_id": "20261024T081151-move_rows-move-4-rows-from-film-to-watch"
572
572
  }
573
573
  ```
@@ -87,7 +87,7 @@ Answer (62 lines)
87
87
  {
88
88
  "start": 81,
89
89
  "end": 86,
90
- "context": "-9707-5a03c150e424\nname: Cary Grant\n---\n\n"
90
+ "context": "-8b5b-1f2bd9e696e3\nname: Cary Grant\n---\n\n"
91
91
  }
92
92
  ]
93
93
  },
@@ -48,6 +48,20 @@ A pattern of `read` or `write` takes one of these forms:
48
48
 
49
49
  Some routes stay the owner’s, whatever a named token’s permissions. A named token can’t create or delete tokens and webhooks, list tokens, rotate them or read the engine’s status. A token may list webhooks and read its own entry with `tokens/me/`. With `tokens/update/`, it may change its own `description` and `autolink`, never its permissions.
50
50
 
51
+ ## A write into another table needs write too
52
+
53
+ A row write can change rows of tables it doesn’t name. The engine checks those rows against `write` too. These writes change other tables:
54
+
55
+ * **`delete_rows` with `on_referenced: "set_null"`**: it clears the links to the deleted rows in the rows that link to them.
56
+ * **Inverse links**: a link to a row with an [inverse column](https://datanotes.dev/guides/database-objects/relations/) adds the link back on that row.
57
+ * **`align_relations`**: it writes the missing links on the other side.
58
+
59
+ When one of those rows belongs to a table outside the token’s `write`, the engine refuses the whole write with 403. Nothing is written, and a dry run gives the same answer. The refusal names the table, such as `token legacy may not write personal.health.weight: this write changes rows of it`. When the token may not read that table, the refusal doesn’t name it, so a token never learns a table name that its listings hide. In a batch, the whole batch is refused with 403 and nothing stays written.
60
+
61
+ To allow the write, add that table to the token’s `write` with `tokens/update/`. The engine also checks its `read`: a token must read every table it writes.
62
+
63
+ The owner token and a token with `"write": ["*"]` write every table, so these checks never refuse them. Schema changes with `ddl`, and undo and restore with `maintain`, aren’t row writes and keep their own rules.
64
+
51
65
  ## Limit what a token can read
52
66
 
53
67
  By default, a named token reads every table. Give it `read` patterns, and it reads only the tables they match. Use them for an agent that works on one part of your notes, so it never sees the rest.
@@ -84,7 +98,7 @@ The engine follows these rules:
84
98
  * **`ddl` and `maintain` need every table.** A token with either one can’t have a limited `read`. Cloning a table, adding a constraint, undo and restore read rows of any table. The engine refuses the combination with 400.
85
99
  * **A view needs its tables too.** To read a view, a token must read the view’s name and every table the view reads. That includes nested views, joins, unions and the links its filters follow. `list_tables` lists a view only when the engine can tell its tables from the view’s query alone. It hides a view over a union, even when every table of the union is readable.
86
100
  * **Free notes stay hidden.** Only a token that reads every table reads a note outside tables, or any other file of the vault. A token with a limited `read` never reads free notes.
87
- * **A link stays visible as text.** A readable row may link to a row the token can’t read. The link text, such as `[[Pasta]]`, stays in the answer. `expand` doesn’t expand it, so the linked note’s properties stay hidden. `file_backlink_count` stays a plain count.
101
+ * **A link stays visible as text.** A readable row may link to a row the token can’t read. The link text, such as `[[Pasta]]`, stays in the answer. `expand` doesn’t expand it, so the linked note’s properties stay hidden.
88
102
 
89
103
  ### What the engine filters and what it refuses
90
104
 
@@ -107,6 +121,7 @@ A set you did not list is filtered to what the token may read, with no error:
107
121
  * **Wildcards**: a pattern in `tables`, or every table when you leave `table` out
108
122
  * **Search and the graph**: `search`, `search_notes`, `semantic_search`, and the neighbours and paths of the graph
109
123
  * **History and changes**: `list_changes`, `list_migrations`, `describe_history` and the change feed’s stream
124
+ * **Counts**: `file_backlink_count` counts only the links from readable rows, in `columns`, `where` and `order_by`. The files, passages and pending notes of `describe_semantic_index` count only readable notes.
110
125
 
111
126
  The engine filters before it applies `limit`, so a search still returns up to `limit` results. A token sees its own tool calls on the change feed, never another token’s. `list_webhooks` shows only the webhooks whose tables the token may all read.
112
127
 
@@ -146,9 +161,7 @@ Read patterns limit tables, not columns or rows. These gaps remain:
146
161
 
147
162
  * **No write-only tokens.** A token always reads what it writes.
148
163
  * **No column or row limits.** A token reads every column and every row of a readable table.
149
- * **Writes into other tables.** A write can change rows of other tables: `on_referenced: "set_null"`, inverse links and `align_relations`. The engine doesn’t check those changes against `write` yet. The answer still hides the rows the token can’t read.
150
- * **Counts.** `describe_semantic_index` and `file_backlink_count` count every note, readable or not. They may tell how many notes exist.
151
- * **Tool calls.** Any token may record a tool call with `tool-calls/record/`, in the name of any agent.
164
+ * **Tool calls.** A token reports what its agents say about themselves, such as the harness and the tool. The engine doesn’t check it. A token can’t report in another token’s session, as [A session belongs to one token](https://datanotes.dev/guides/security/who-did-what/#a-session-belongs-to-one-token) explains.
152
165
  * **Guessed names.** As [Names are hidden, not secret](#names-are-hidden-not-secret) explains, a refusal confirms that a table exists.
153
166
 
154
167
  ## Turn automatic links off for a sync program
@@ -33,6 +33,14 @@ Tool calls appear on the change feed as events with `kind: "tool_call"`, sent on
33
33
 
34
34
  A large result costs less to report when the program cuts it first. The engine answers `takes_summary: true` when it accepts a cut call. Then send the value cut at 1,000 characters, and the result’s `summary` next to it. The event is the same as for the whole call. `datanotes mcp` does this after its first report.
35
35
 
36
+ ### A session belongs to one token
37
+
38
+ The first token that reports a session owns it. Both routes count as a report. After that, only that token and the owner can report the session. Another named token gets a 403 error, and the engine stores nothing. So no token can rename another agent’s model or add tool calls to its session.
39
+
40
+ Give each agent session its own id, such as a new UUID. The engine compares the first 16 characters of the id, so make them unique. When one program serves agents with several tokens, give each token its own sessions.
41
+
42
+ The engine keeps the owners of the last 2,000 sessions in memory, and forgets them when it restarts.
43
+
36
44
  ## Read who did what
37
45
 
38
46
  Three operations read the record:
@@ -3,7 +3,7 @@
3
3
  > The datanotes command and its options.
4
4
 
5
5
  ```text
6
- datanotes 3.4.0: Markdown notes as database tables, for you and your agents.
6
+ datanotes 3.4.1: Markdown notes as database tables, for you and your agents.
7
7
 
8
8
 
9
9
  Usage:
@@ -4,6 +4,21 @@
4
4
 
5
5
  This page lists each version of Datanotes, newest first. Datanotes follows [semantic versioning](https://semver.org): a major version can break what you rely on, and its notes list those changes first. The package is on [npm](https://www.npmjs.com/package/datanotes), and each version has a [GitHub release](https://github.com/davidefornelli/datanotes/releases).
6
6
 
7
+ ## 3.4.1
8
+
9
+ Datanotes 3.4.1 closes three gaps in token permissions. It only adds to 3.4: no operation, argument or setting goes away. One fix can refuse a write that 3.4.0 allowed, so check your tokens before you update.
10
+
11
+ ### Fixes
12
+
13
+ * **Writes into other tables need `write`**: a row write can change rows of tables it doesn’t name, through `on_referenced: "set_null"`, inverse links or `align_relations`. A named token now needs `write` on those tables too. Otherwise the engine refuses the whole write with 403, and nothing is written. The refusal names the table, unless the token may not read it. [A write into another table needs write too](https://datanotes.dev/guides/security/tokens/#a-write-into-another-table-needs-write-too) explains it.
14
+ * **A session belongs to one token**: the first token that sends a session id to `sessions/identify/` or `tool-calls/record/` owns it. Another named token gets 403 for that session, and nothing is stored. The owner may use any session. [A session belongs to one token](https://datanotes.dev/guides/security/who-did-what/#a-session-belongs-to-one-token) explains it.
15
+ * **Counts follow `read`**: for a token with limited `read`, `file_backlink_count` counts only links from notes it may read. `describe_semantic_index` counts only those notes in `files`, `passages` and `pending`.
16
+
17
+ ### Before you update
18
+
19
+ * **Token `write`**: an integration that relies on those side effects gets 403 after the update. Add the other table to the token’s `write`, and to its `read` when `read` is limited.
20
+ * **Session ids**: give each token its own session ids. `datanotes mcp` already does: it makes a random id for each session.
21
+
7
22
  ## 3.4.0
8
23
 
9
24
  Datanotes 3.4.0 brings three additions:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "datanotes",
3
- "version": "3.4.0",
3
+ "version": "3.4.1",
4
4
  "mcpName": "io.github.davidefornelli/datanotes",
5
5
  "description": "The engine of your second brain: Markdown notes as database tables, for you and your agents.",
6
6
  "keywords": [