Commitcc5800aeRecorded2 Aug 2026Repositoryfolio

Bump to 0.2.7 on the sigil 0.18 toolchain, add a changelog

Message

Patch, not minor: the pre-1.0 convention reserves a minor bump for genuinely-breaking API changes. A new tool is additive, and stable ids are a fix to behaviour callers already had to work around. Substance is carried by the changelog and the tag message.

sigil ^0.18, sigil-run ^0.18.0, sigil-http ^0.18.0, sigil-sxml ^0.15.0, plus the patch bumps sigil deps update found. Runtime core resolves to 0.18.1. sigil-test stays at ^0.17 with a comment explaining why, so the next reader does not "fix" the pin and hit the install abort.

First changelog for this repo; format follows sigil-http, the only sibling with one. It has a Known issues section recording that multi-line inbox captures are STILL buried, because a user reading a release note needs to know what is not fixed at least as much as what is.

README documents the bulk tools -- none of them were listed, not even the pre-existing task-complete-batch, task-sweep and inbox-sweep -- and carries the same one-line-capture warning.

Changed
 CHANGELOG.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 README.md    | 37 +++++++++++++++++++++++++++++++++++++
 package.sgl  | 16 +++++++++++-----
 sigil.lock   | 61 ++++++++++++++++++++++++++++---------------------------------
 4 files changed, 145 insertions(+), 38 deletions(-)
Diff
CHANGELOG.mdadded
@@ -0,0 +1,69 @@
+1
# Changelog
+2
+3
All notable changes to **folio** are documented in this file.
+4
+5
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
+6
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+7
+8
## [0.2.7] - 2026-08-02
+9
+10
### Fixed
+11
+12
- **Moving a task no longer renumbers it.** Ids are preserved in every
+13
direction — inbox → project, project → inbox, project → project, and
+14
`folio/inbox-triage`. An id you hold before a move is still valid after it,
+15
so `task-move` → `task-update <same-id>` chains correctly and a triage plan
+16
built from an inbox dump keeps working once the items are routed.
+17
+18
This was never a design constraint. Ids are globally unique random hex with
+19
no per-project id space, so nothing required a new one on move.
+20
`project-add-task!` simply called `generate-task-id` unconditionally and
+21
ignored any id handed to it, while `move-task-in-store!` stripped the id out
+22
on the way in. The asymmetry gave it away as an oversight: project → inbox
+23
passed metadata through untouched, and only inbox → project destroyed the id.
+24
+25
- **A task can no longer end up carrying two `id` entries.** Moving a task from
+26
a project back to the inbox prepended a fresh id without removing the
+27
existing one, leaving both on the line; lookups silently resolved the first.
+28
+29
### Added
+30
+31
- **`folio/task-move-batch`** — move many tasks in one call, either
+32
`{ids: [...], project: "x"}` for a shared target or
+33
`{moves: [{id, project}, ...]}` to fan a single call out across many
+34
projects. An entry with no `project` moves that task to the inbox.
+35
+36
Returns a result line per id so partial failures are visible rather than
+37
swallowed, and the header counts successes rather than attempts. Because ids
+38
are now stable, the reported id is the one the task landed under.
+39
+40
Triaging 227 inbox items on 2026-08-02 cost 226 individual round-trips, which
+41
is a large part of why that inbox went untriaged for four months.
+42
+43
### Changed
+44
+45
- Toolchain moved to sigil 0.18 (`sigil ^0.18`, `sigil-run ^0.18.0`,
+46
`sigil-http ^0.18.0`, `sigil-sxml ^0.15.0`), with runtime core resolving to
+47
0.18.1. `sigil-test` / `sigil-test-runner` remain pinned at `^0.17` (0.17.16):
+48
bumping them aborts the install because sigil-http, sigil-tls, sigil-crypto
+49
and sigil-web-styles each declare a dev-dependency on `sigil-test ^0.17` and
+50
the resolver unifies across the graph. That affects the test harness only,
+51
not the shipped runtime, and clears once those four repos move their dev-dep.
+52
+53
### Known issues
+54
+55
- **A capture containing newlines is still stored in a shape folio cannot read
+56
back.** `folio/inbox-add` accepts multi-line text, but the `{id: ...}`
+57
metadata is appended to the END of the text, so on a multi-line capture it
+58
lands on the item's last line. The parser sees only the first line, which has
+59
no id, and `backfill-ids!` then mints a fresh id onto it — the real item and
+60
its metadata become unreachable and a phantom one-line duplicate appears in
+61
its place. Six items were hidden this way between April and August 2026.
+62
+63
This is not fixed in 0.2.7. A block-parsing fix was written and withdrawn: it
+64
cured the burial but introduced worse defects, because it inferred where an
+65
item ends and then let destructive operations act on that inference. The
+66
redesign makes an item's extent syntactic rather than inferred.
+67
+68
Until it lands, **capture multi-line content as a note and reference it from
+69
a single-line inbox item**, rather than putting the body in the item itself.
README.mdmodified
@@ -145,6 +145,35 @@ folio/
145
| `folio/task-update` | Update task metadata (priority, due, tags, waiting) |
146
| `folio/task-move` | Move a task between projects or to inbox |
147
+148
A task's id is stable: moving it between the inbox and a project, or between
+149
projects, preserves the id it already had.
+150
+151
### Bulk operations
+152
+153
Triaging a full inbox one call at a time is slow enough that nobody does it
+154
routinely, which is how an inbox goes months without being triaged.
+155
+156
| Tool | Description |
+157
|------|-------------|
+158
| `folio/task-move-batch` | Move many tasks at once, with a result line per id |
+159
| `folio/task-complete-batch` | Mark many tasks done by id list |
+160
| `folio/task-sweep` | Remove completed tasks from projects |
+161
| `folio/inbox-sweep` | Remove completed items from the inbox |
+162
+163
`folio/task-move-batch` takes either one shared target or per-id targets, so a
+164
single call can fan out across many projects:
+165
+166
```json
+167
{"ids": ["t-a3f2", "t-b1c4"], "project": "bureau-v2"}
+168
+169
{"moves": [{"id": "t-a3f2", "project": "bureau-v2"},
+170
{"id": "t-b1c4", "project": "sigil-gc"},
+171
{"id": "t-c5d6"}]}
+172
```
+173
+174
An entry with no `project` moves that task to the inbox. Every id gets its own
+175
result line, so a partial failure is visible rather than swallowed.
+176
177
### Inbox
178
179
| Tool | Description |
@@ -153,6 +182,14 @@ folio/
182
| `folio/inbox-add` | Add an item to the inbox |
183
| `folio/inbox-triage` | Move an inbox item to a project |
184
+185
> **Keep inbox captures to a single line.** An item whose text contains
+186
> newlines is currently written in a shape folio cannot read back: the
+187
> `{id: ...}` metadata lands on the item's last line, the parser sees only the
+188
> first, and the item becomes invisible to every tool while a phantom
+189
> one-line duplicate takes its place. For anything longer, create a note and
+190
> reference it from a one-line inbox item. See the Known issues section of
+191
> CHANGELOG.md.
+192
193
### Projects
194
195
| Tool | Description |
package.sglmodified
@@ -6,8 +6,8 @@
6
7
(package
8
name: "folio"
9
version: "0.2.6"
10
sigil: "^0.17"
+9
version: "0.2.7"
+10
sigil: "^0.18"
11
description: "Markdown-native knowledge and project management via MCP"
12
url: "https://codeberg.org/sigil/folio"
13
license: "BSD-3-Clause"
@@ -34,17 +34,23 @@
34
bundle?: #t))
35
36
dependencies: (list
37
(from-git url: "codeberg:sigil/sigil" package: "sigil-run" version: "^0.17.0")
+37
(from-git url: "codeberg:sigil/sigil" package: "sigil-run" version: "^0.18.0")
38
(from-git url: "codeberg:sigil/sigil-json" version: "^0.16.0")
39
(from-git url: "codeberg:sigil/sigil-log" version: "^0.16.0")
40
(from-git url: "codeberg:sigil/sigil-mcp" version: "^0.16.0")
41
(from-git url: "codeberg:sigil/sigil-http" version: "^0.16.0")
+41
(from-git url: "codeberg:sigil/sigil-http" version: "^0.18.0")
42
(from-git url: "codeberg:sigil/sigil-sqlite" version: "^0.16.0")
43
(from-git url: "codeberg:sigil/sigil-yaml" version: "^0.9.1")
44
(from-git url: "codeberg:sigil/sigil-sxml" version: "^0.14.0")
+44
(from-git url: "codeberg:sigil/sigil-sxml" version: "^0.15.0")
45
(from-git url: "codeberg:sigil/sigil-markdown" version: "^0.9.1")
46
(from-git url: "codeberg:sigil/sigil-web-styles" version: "^0.2.0"))
47
+48
;; sigil-test is deliberately held at ^0.17 while the runtime is on ^0.18.
+49
;; Bumping it to ^0.18 ABORTS `sigil deps install` with a version conflict:
+50
;; sigil-http, sigil-tls, sigil-crypto and sigil-web-styles each declare a
+51
;; dev-dependency on sigil-test ^0.17, and the resolver unifies across the
+52
;; whole graph. Test harness only -- the shipped runtime is unaffected.
+53
;; Raise this once those four repos move their dev-dep. See t-9484.
54
dev-dependencies: (list
55
(from-git url: "codeberg:sigil/sigil" package: "sigil-test" version: "^0.17")
56
(from-git url: "codeberg:sigil/sigil" package: "sigil-test-runner" version: "^0.17"))
sigil.lockmodified
@@ -2,22 +2,22 @@
2
(lock
3
(package name: "sigil-stdlib"
4
url: "codeberg:sigil/sigil"
5
ref: "^0.17"
6
sha: "8e694ed5cde7d6a9f1c935ee21ab8a3a9bb92f4f"
+5
ref: "^0.18"
+6
sha: "4a5d7262191ecbbd8e2124284b3ef988c1b58aad"
7
package-selector: "sigil-stdlib"
8
version: "0.17.16")
+8
version: "0.18.1")
9
(package name: "sigil-run"
10
url: "codeberg:sigil/sigil"
11
ref: "^0.17.0"
12
sha: "8e694ed5cde7d6a9f1c935ee21ab8a3a9bb92f4f"
+11
ref: "^0.18.0"
+12
sha: "4a5d7262191ecbbd8e2124284b3ef988c1b58aad"
13
package-selector: "sigil-run"
14
version: "0.17.16")
+14
version: "0.18.1")
15
(package name: "sigil-lib"
16
url: "codeberg:sigil/sigil"
17
ref: "^0.17"
18
sha: "8e694ed5cde7d6a9f1c935ee21ab8a3a9bb92f4f"
+18
sha: "4a5d7262191ecbbd8e2124284b3ef988c1b58aad"
19
package-selector: "sigil-lib"
20
version: "0.17.16")
+20
version: "0.18.1")
21
(package name: "sigil-json"
22
url: "codeberg:sigil/sigil-json"
23
ref: "^0.16.0"
@@ -31,13 +31,13 @@
31
(package name: "sigil-mcp"
32
url: "codeberg:sigil/sigil-mcp"
33
ref: "^0.16.0"
34
sha: "1a0175939d7841686cad8793ed5faa1d10602351"
35
version: "0.16.4")
+34
sha: "4809a63545d6540ddb7abf437a63d1c9f49fbed9"
+35
version: "0.16.5")
36
(package name: "sigil-http"
37
url: "codeberg:sigil/sigil-http"
38
ref: "^0.16.0"
39
sha: "c24a14cabdb5ceed6273d7a6c1004baee07d69a0"
40
version: "0.16.7")
+38
ref: "^0.18.0"
+39
sha: "1ad4063a9540ca91fbb15fc7d32936e232eb621c"
+40
version: "0.18.2")
41
(package name: "sigil-sqlite"
42
url: "codeberg:sigil/sigil-sqlite"
43
ref: "^0.16.0"
@@ -46,18 +46,18 @@
46
(package name: "sigil-yaml"
47
url: "codeberg:sigil/sigil-yaml"
48
ref: "^0.9.1"
49
sha: "38e96aa33d83e7881dc9860995883fdd6ee05593"
50
version: "0.9.1")
+49
sha: "3f8955b867950cc8a9da717b8918b802c57d021f"
+50
version: "0.9.2")
51
(package name: "sigil-sxml"
52
url: "codeberg:sigil/sigil-sxml"
53
ref: "^0.14.0"
54
sha: "a33eb522bfd485dcc490c8db5ea599d7215027ff"
55
version: "0.14.0")
+53
ref: "^0.15.0"
+54
sha: "5a4f043247600f58bdabae19de55664d759a30c9"
+55
version: "0.15.0")
56
(package name: "sigil-markdown"
57
url: "codeberg:sigil/sigil-markdown"
58
ref: "^0.9.1"
59
sha: "20e0de7bae49cda15e4b147f87968b0442caa75c"
60
version: "0.9.1")
+59
sha: "181ef01a3b711eae2c5ffffa76938a9dff18fab8"
+60
version: "0.9.5")
61
(package name: "sigil-web-styles"
62
url: "codeberg:sigil/sigil-web-styles"
63
ref: "^0.2.0"
@@ -66,15 +66,15 @@
66
(package name: "sigil-test"
67
url: "codeberg:sigil/sigil"
68
ref: "^0.17"
69
sha: "8e694ed5cde7d6a9f1c935ee21ab8a3a9bb92f4f"
+69
sha: "070f133a3524142b4febfd7c287385186b616252"
70
package-selector: "sigil-test"
71
version: "0.17.16")
+71
version: "0.17.20")
72
(package name: "sigil-test-runner"
73
url: "codeberg:sigil/sigil"
74
ref: "^0.17"
75
sha: "8e694ed5cde7d6a9f1c935ee21ab8a3a9bb92f4f"
+75
sha: "070f133a3524142b4febfd7c287385186b616252"
76
package-selector: "sigil-test-runner"
77
version: "0.17.16")
+77
version: "0.17.20")
78
(package name: "sigil-nrepl"
79
url: "codeberg:sigil/sigil-nrepl"
80
ref: "^0.16"
@@ -88,13 +88,8 @@
88
(package name: "sigil-tls"
89
url: "codeberg:sigil/sigil-tls"
90
ref: "^0.16.0"
91
sha: "30e8c2a84345dc4d484f5c085daa5bd16fc60fe1"
92
version: "0.16.3")
93
(package name: "sigil-peg"
94
url: "codeberg:sigil/sigil-peg"
95
ref: "^0.9.0"
96
sha: "2a0adbd32b13fb835cf021a8e279341161a77436"
97
version: "0.9.1")
+91
sha: "baf05e45ed4090406c2990debadabfcd8253d834"
+92
version: "0.16.4")
93
(package name: "sigil-css"
94
url: "codeberg:sigil/sigil-css"
95
ref: "^0.9.1"
@@ -123,8 +118,8 @@
118
(package name: "sigil-crypto"
119
url: "codeberg:sigil/sigil-crypto"
120
ref: "^0.16"
126
sha: "a391c4ed73891ac5dc8a6da98b80a340c03f801f"
127
version: "0.16.3")
+121
sha: "964eec2fad375834e2b49da454209fabc059ca30"
+122
version: "0.16.4")
123
(package name: "sigil-hooks"
124
url: "codeberg:sigil/sigil-hooks"
125
ref: "^0.16.0"