AtlatestRepositoryfolio
1
;;; HTTP reads use committed index rows while a writer owns its transaction.2
(import (sigil test)3
(sigil fs)4
(sigil path)5
(sigil json)6
(sigil string)7
(sigil sqlite)8
(sigil mcp server)9
(sigil mcp protocol)10
(folio store)11
(folio index)12
(folio tools))14
(define (call-tool server name args)15
(let* ((reply16
(json-decode17
(response->json18
(mcp-server-handle-message server19
(jsonrpc-request id: 1 method: "tools/call"20
params: (dict name: name arguments: args))))))21
(content (dict-ref (dict-ref reply result:) content:)))22
(dict-ref (array-ref content 0) text:)))24
(test-group "separate read index"25
(test "tool reads see committed rows during a writer transaction and refresh after commit"26
(call-with-temp-directory27
(lambda (root)28
(let* ((store (make-folio-store root))29
(notes (store-notes-dir store)))30
(write-file-string (path-join notes "a.md")31
"---\nlast-updated: 2026-01-01\n---\n# A\n[[b]]\n")32
(write-file-string (path-join notes "b.md")33
"---\nlast-updated: 2026-01-02\n---\n# B\n")34
(let* ((writer (make-folio-index store))35
(_ (index-census-tick! writer))36
(reader (make-folio-index store))37
(server (mcp-server name: "read-index-test")))38
(register-folio-tools! server store writer read-index: reader)39
(assert-true (string-contains?40
(call-tool server "folio/note-links" (dict name: "b")) "← a"))41
(with-index-transaction writer42
(lambda ()43
(assert-true (sqlite-run (folio-index-db writer)44
"UPDATE notes_meta SET last_updated = ? WHERE name = ?"45
"2099-12-31" "a"))46
(assert-true (sqlite-run (folio-index-db writer)47
"DELETE FROM note_links WHERE target = ?" "b"))48
(let ((recent? (string-contains?49
(call-tool server "folio/status" (dict))50
"## Recent Notes\n\n b\n a"))51
(backlink? (string-contains?52
(call-tool server "folio/note-links" (dict name: "b")) "← a"))53
(search? (equal? "No notes found."54
(call-tool server "folio/notes" (dict since: "2099-01-01")))))55
(display (format "READ isolation committed-recent=~a committed-backlink=~a committed-search=~a\n"56
recent? backlink? search?))57
(assert-true recent?)58
(assert-true backlink?)59
(assert-true search?))))60
(assert-true (string-contains?61
(call-tool server "folio/status" (dict))62
"## Recent Notes\n\n a\n b"))63
(assert-false (string-contains?64
(call-tool server "folio/note-links" (dict name: "b")) "← a"))65
(assert-true (string-contains?66
(call-tool server "folio/notes" (dict since: "2099-01-01")) " a"))67
(sqlite-close (folio-index-db reader))68
(sqlite-close (folio-index-db writer))))))))