trajectories 0.0.0 → 0.1.2

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 (205) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/LICENSE +201 -0
  3. package/README.md +288 -2
  4. package/dist/cli.js +30210 -0
  5. package/dist/convert.d.ts +31 -0
  6. package/dist/convert.js +431 -0
  7. package/dist/deepagents_checkpoint.py +362 -0
  8. package/dist/index.d.ts +7 -0
  9. package/dist/index.js +8402 -0
  10. package/dist/log-baseline.d.ts +26 -0
  11. package/dist/log-baseline.js +104 -0
  12. package/dist/log-content.d.ts +16 -0
  13. package/dist/log-content.js +80 -0
  14. package/dist/log-io.d.ts +10 -0
  15. package/dist/log-io.js +121 -0
  16. package/dist/log-read.d.ts +24 -0
  17. package/dist/log-read.js +117 -0
  18. package/dist/log-reconcile.d.ts +5 -0
  19. package/dist/log-reconcile.js +38 -0
  20. package/dist/log-records.d.ts +35 -0
  21. package/dist/log-records.js +85 -0
  22. package/dist/log-recovery.d.ts +18 -0
  23. package/dist/log-recovery.js +123 -0
  24. package/dist/log-stage.d.ts +14 -0
  25. package/dist/log-stage.js +138 -0
  26. package/dist/log-state.d.ts +89 -0
  27. package/dist/log-state.js +92 -0
  28. package/dist/log-switch.d.ts +3 -0
  29. package/dist/log-switch.js +98 -0
  30. package/dist/log-types.d.ts +129 -0
  31. package/dist/log-types.js +8 -0
  32. package/dist/log.d.ts +8 -0
  33. package/dist/log.js +62 -0
  34. package/dist/migrate.d.ts +29 -0
  35. package/dist/migrate.js +173 -0
  36. package/dist/normalization-runtime.d.ts +1 -0
  37. package/dist/normalization-runtime.js +3150 -0
  38. package/dist/portable.d.ts +9 -0
  39. package/dist/portable.js +26 -0
  40. package/dist/readers/canonical.d.ts +13 -0
  41. package/dist/readers/canonical.js +54 -0
  42. package/dist/readers/cline.d.ts +10 -0
  43. package/dist/readers/cline.js +107 -0
  44. package/dist/readers/cursor.d.ts +20 -0
  45. package/dist/readers/cursor.js +374 -0
  46. package/dist/readers/deepagents.d.ts +41 -0
  47. package/dist/readers/deepagents.js +163 -0
  48. package/dist/readers/fx.d.ts +11 -0
  49. package/dist/readers/fx.js +573 -0
  50. package/dist/readers/github-copilot.d.ts +8 -0
  51. package/dist/readers/github-copilot.js +216 -0
  52. package/dist/readers/grok-build.d.ts +12 -0
  53. package/dist/readers/grok-build.js +391 -0
  54. package/dist/readers/guards.d.ts +4 -0
  55. package/dist/readers/guards.js +121 -0
  56. package/dist/readers/pi-compaction.d.ts +7 -0
  57. package/dist/readers/pi-compaction.js +112 -0
  58. package/dist/readers/pi-context.d.ts +13 -0
  59. package/dist/readers/pi-context.js +64 -0
  60. package/dist/store.d.ts +25 -0
  61. package/dist/store.js +218 -0
  62. package/dist/types.d.ts +91 -0
  63. package/dist/types.js +1 -0
  64. package/dist/writers/claude-code.d.ts +5 -0
  65. package/dist/writers/claude-code.js +51 -0
  66. package/dist/writers/cline.d.ts +3 -0
  67. package/dist/writers/cline.js +77 -0
  68. package/dist/writers/codex.d.ts +3 -0
  69. package/dist/writers/codex.js +32 -0
  70. package/dist/writers/cursor.d.ts +3 -0
  71. package/dist/writers/cursor.js +197 -0
  72. package/dist/writers/deepagents.d.ts +3 -0
  73. package/dist/writers/deepagents.js +116 -0
  74. package/dist/writers/entropy.d.ts +5 -0
  75. package/dist/writers/entropy.js +33 -0
  76. package/dist/writers/fx.d.ts +3 -0
  77. package/dist/writers/fx.js +135 -0
  78. package/dist/writers/github-copilot.d.ts +3 -0
  79. package/dist/writers/github-copilot.js +71 -0
  80. package/dist/writers/grok-build.d.ts +3 -0
  81. package/dist/writers/grok-build.js +43 -0
  82. package/dist/writers/helpers.d.ts +17 -0
  83. package/dist/writers/helpers.js +75 -0
  84. package/dist/writers/omp.d.ts +3 -0
  85. package/dist/writers/omp.js +7 -0
  86. package/dist/writers/opencode.d.ts +3 -0
  87. package/dist/writers/opencode.js +65 -0
  88. package/dist/writers/pi.d.ts +3 -0
  89. package/dist/writers/pi.js +45 -0
  90. package/docs/cline-native-format.md +43 -0
  91. package/docs/copilot-native-format.md +78 -0
  92. package/docs/cursor-native-format.md +103 -0
  93. package/docs/deepagents-native-format.md +98 -0
  94. package/docs/evidence-api.md +170 -0
  95. package/docs/fx-native-format.md +87 -0
  96. package/docs/harness-parity-bootstrap.md +78 -0
  97. package/docs/harness-support-parity.md +107 -0
  98. package/docs/inspirations.md +103 -0
  99. package/docs/ledger-migration.md +141 -0
  100. package/docs/pi-compaction-context.md +75 -0
  101. package/docs/pi-provider-context.md +76 -0
  102. package/docs/research/2026-10-06-huihua-and-oar.md +176 -0
  103. package/docs/research/ledger/README.md +96 -0
  104. package/docs/research/ledger/confer/2026-09-13-round-10/README.md +61 -0
  105. package/docs/research/ledger/confer/2026-09-13-round-2/cass.md +72 -0
  106. package/docs/research/ledger/confer/2026-09-13-round-3/README.md +70 -0
  107. package/docs/research/ledger/confer/2026-09-13-round-5/README.md +61 -0
  108. package/docs/research/ledger/confer/2026-09-13-round-6/README.md +68 -0
  109. package/docs/research/ledger/confer/2026-09-13-round-7/README.md +64 -0
  110. package/docs/research/ledger/confer/2026-09-13-round-9/README.md +59 -0
  111. package/docs/research/ledger/confer/2026-09-14-wake/wake.md +146 -0
  112. package/docs/research/ledger/docs/inspirations.md +320 -0
  113. package/docs/research/ledger/docs/pr2-pr6-integration.md +53 -0
  114. package/docs/research/ledger/docs/research/2026-09-07-confer-inspirations.md +163 -0
  115. package/docs/research/ledger/docs/research/2026-09-07-letta-continuous-service.md +104 -0
  116. package/docs/research/ledger/docs/research/2026-09-08-claude-history-retrieval.md +117 -0
  117. package/docs/research/ledger/docs/research/2026-09-09-agentsview-native-discovery.md +87 -0
  118. package/docs/research/ledger/docs/research/2026-09-09-daemon-observation.md +231 -0
  119. package/docs/research/ledger/docs/research/2026-09-09-discovery-pagination.md +114 -0
  120. package/docs/research/ledger/docs/research/2026-09-09-harness-transcript-contract.md +145 -0
  121. package/docs/research/ledger/docs/research/2026-09-09-native-history-discovery.md +180 -0
  122. package/docs/research/ledger/docs/research/2026-09-09-native-history-implementation.md +137 -0
  123. package/docs/research/ledger/docs/research/2026-09-09-other-inspirations.md +279 -0
  124. package/docs/research/ledger/docs/research/2026-09-09-trajectory-and-letta-code.md +128 -0
  125. package/docs/research/ledger/docs/research/2026-09-13-diagnostics-coverage.md +116 -0
  126. package/docs/research/ledger/docs/research/2026-09-13-fts-rebuild.md +83 -0
  127. package/docs/research/ledger/docs/research/2026-09-13-read-path-split.md +74 -0
  128. package/docs/research/ledger/docs/research/2026-09-13-runtime-rollout.md +102 -0
  129. package/docs/research/ledger/docs/research/2026-09-13-scan-outcomes.md +80 -0
  130. package/docs/research/ledger/docs/research/2026-09-13-search-quality.md +105 -0
  131. package/docs/research/ledger/docs/research/2026-09-13-source-coverage.md +64 -0
  132. package/docs/research/ledger/docs/research/2026-09-13-sync-wall-budget.md +82 -0
  133. package/docs/research/ledger/docs/research/2026-09-13-typed-read-gate.md +81 -0
  134. package/docs/research/ledger/docs/research/2026-09-13-writer-lease.md +84 -0
  135. package/docs/research/ledger/docs/research/2026-09-16-c1-copy-fallback.md +227 -0
  136. package/docs/research/ledger/docs/research/2026-09-16-c10-kimi.md +414 -0
  137. package/docs/research/ledger/docs/research/2026-09-16-c2-derive-counter.md +216 -0
  138. package/docs/research/ledger/docs/research/2026-09-16-c3-echo-filter.md +305 -0
  139. package/docs/research/ledger/docs/research/2026-09-16-c4-title-index.md +349 -0
  140. package/docs/research/ledger/docs/research/2026-09-16-c5-trigram.md +268 -0
  141. package/docs/research/ledger/docs/research/2026-09-16-c6-recency-prior.md +438 -0
  142. package/docs/research/ledger/docs/research/2026-09-16-c7-tombstones.md +467 -0
  143. package/docs/research/ledger/docs/research/2026-09-16-c8-remote-truth.md +390 -0
  144. package/docs/research/ledger/docs/research/2026-09-16-c9-grok.md +380 -0
  145. package/docs/research/ledger/docs/research/2026-09-16-wake-port-program.md +38 -0
  146. package/docs/research/ledger/docs/research/2026-09-17-cursor-blobstore.md +157 -0
  147. package/docs/research/ledger/manifest.json +540 -0
  148. package/legacy/NOTICE.md +50 -0
  149. package/legacy/bin/ledger-core.ts +7 -0
  150. package/legacy/bin/ledger.ts +7 -0
  151. package/legacy/bin/traj-bridge.ts +7 -0
  152. package/legacy/scripts/import-claude-history.ts +130 -0
  153. package/legacy/scripts/native-history-smoke.ts +52 -0
  154. package/legacy/scripts/observe-daemon.ts +570 -0
  155. package/legacy/scripts/retitle-sessions.md +19 -0
  156. package/legacy/scripts/verify-runtime-rollout.ts +151 -0
  157. package/legacy/src/canonical.ts +108 -0
  158. package/legacy/src/cli.ts +1293 -0
  159. package/legacy/src/db.ts +2254 -0
  160. package/legacy/src/diagnostics.ts +87 -0
  161. package/legacy/src/discovery.ts +56 -0
  162. package/legacy/src/embeddings.ts +382 -0
  163. package/legacy/src/filter.ts +602 -0
  164. package/legacy/src/gemini_embeddings.ts +103 -0
  165. package/legacy/src/identity.ts +9 -0
  166. package/legacy/src/index.ts +10 -0
  167. package/legacy/src/ingest.ts +791 -0
  168. package/legacy/src/managed.ts +178 -0
  169. package/legacy/src/native/common.ts +68 -0
  170. package/legacy/src/native/cursor.ts +647 -0
  171. package/legacy/src/native/grok.ts +540 -0
  172. package/legacy/src/native/kimi.ts +706 -0
  173. package/legacy/src/native/opencode.ts +470 -0
  174. package/legacy/src/native/sqlite-ro.ts +281 -0
  175. package/legacy/src/native.ts +97 -0
  176. package/legacy/src/normalizer.ts +457 -0
  177. package/legacy/src/parentage.ts +562 -0
  178. package/legacy/src/pressure.ts +162 -0
  179. package/legacy/src/private-storage.ts +74 -0
  180. package/legacy/src/reader.ts +1255 -0
  181. package/legacy/src/scanner.ts +591 -0
  182. package/legacy/src/schema-gate.ts +263 -0
  183. package/legacy/src/schema.ts +829 -0
  184. package/legacy/src/semantic-top-k.ts +71 -0
  185. package/legacy/src/session-hash.ts +49 -0
  186. package/legacy/src/store-status.ts +218 -0
  187. package/legacy/src/sync-preparation.ts +45 -0
  188. package/legacy/src/sync-truth.ts +843 -0
  189. package/legacy/src/sync.ts +1233 -0
  190. package/legacy/src/types.ts +436 -0
  191. package/legacy/src/vocab.txt +30522 -0
  192. package/legacy/src/watch.ts +673 -0
  193. package/legacy/src/writer-lease.ts +310 -0
  194. package/ops/README.md +150 -0
  195. package/ops/install-cli.sh +63 -0
  196. package/ops/install-native.sh +35 -0
  197. package/ops/install-release.sh +49 -0
  198. package/ops/linux/install-systemd-user.sh +103 -0
  199. package/ops/macos/install-launchd.sh +72 -0
  200. package/ops/sync-settings.sh +37 -0
  201. package/package.json +21 -5
  202. package/skills/trajectories/SKILL.md +138 -0
  203. package/skills/trajectories/scripts/trajectories_recent.sh +26 -0
  204. package/skills/trajectories/scripts/trajectories_search.sh +26 -0
  205. package/index.js +0 -1
@@ -0,0 +1,96 @@
1
+ # Ledger research archive
2
+
3
+ This directory preserves the Markdown prior-art and implementation research from
4
+ [archeism/ledger at `43081aef54c23b4bd017b6c0e11fc42a9a1cb381`](https://github.com/archeism/ledger/tree/43081aef54c23b4bd017b6c0e11fc42a9a1cb381).
5
+ It is historical evidence. Runtime commands, implementation plans, test counts and
6
+ open items describe Ledger at that frozen commit; they are not current Trajectories
7
+ instructions or fresh verification.
8
+
9
+ Only Markdown was copied. No experiments, transcripts, databases, archives or other
10
+ runtime artifacts are included. The archive retains the complete frozen `docs/research`
11
+ directory, Ledger's inspiration and PR2/PR6 integration records, the Wake deep dive,
12
+ and the Confer pages directly cited by the retained research. Relative links inside
13
+ the copied set stay local. Relative links to excluded files are rewritten to immutable
14
+ GitHub blobs at the source commit. Existing upstream URLs are unchanged.
15
+
16
+ Seven source links under `docs/research` incorrectly used `../confer`, which resolves
17
+ to nonexistent `docs/confer` paths. This archive repairs only those destinations to
18
+ the included root `confer` files. Each repair is declared below and in its manifest
19
+ entry; the source text and original digest remain recorded separately.
20
+
21
+ `manifest.json` is the machine-readable inventory. Every row below records the original
22
+ path and digest, ported path and digest, and the only allowed transformation.
23
+
24
+ - Source files: 43
25
+ - Source bytes: 511973
26
+ - Ported bytes: 516313
27
+ - Rewritten relative links: 49
28
+ - Declared broken-link repairs: 7
29
+ - Archive budget: 516313 / 2,097,152 bytes
30
+
31
+ ## Declared link repairs
32
+
33
+ | Source document | Old destination | New destination | Resolved frozen source |
34
+ | --- | --- | --- | --- |
35
+ | `docs/research/2026-09-13-read-path-split.md` | `../confer/2026-09-13-round-5/README.md` | `../../confer/2026-09-13-round-5/README.md` | `confer/2026-09-13-round-5/README.md` |
36
+ | `docs/research/2026-09-13-scan-outcomes.md` | `../confer/2026-09-13-round-7/README.md` | `../../confer/2026-09-13-round-7/README.md` | `confer/2026-09-13-round-7/README.md` |
37
+ | `docs/research/2026-09-13-search-quality.md` | `../confer/2026-09-13-round-2/cass.md` | `../../confer/2026-09-13-round-2/cass.md` | `confer/2026-09-13-round-2/cass.md` |
38
+ | `docs/research/2026-09-13-source-coverage.md` | `../confer/2026-09-13-round-9/README.md` | `../../confer/2026-09-13-round-9/README.md` | `confer/2026-09-13-round-9/README.md` |
39
+ | `docs/research/2026-09-13-sync-wall-budget.md` | `../confer/2026-09-13-round-10/README.md` | `../../confer/2026-09-13-round-10/README.md` | `confer/2026-09-13-round-10/README.md` |
40
+ | `docs/research/2026-09-13-typed-read-gate.md` | `../confer/2026-09-13-round-6/README.md` | `../../confer/2026-09-13-round-6/README.md` | `confer/2026-09-13-round-6/README.md` |
41
+ | `docs/research/2026-09-13-writer-lease.md` | `../confer/2026-09-13-round-3/README.md` | `../../confer/2026-09-13-round-3/README.md` | `confer/2026-09-13-round-3/README.md` |
42
+
43
+ ## Inventory
44
+
45
+ | Original | Ported | Original SHA-256 | Ported SHA-256 | Change rule |
46
+ | --- | --- | --- | --- | --- |
47
+ | `confer/2026-09-13-round-10/README.md` | `packages/trajectories/docs/research/ledger/confer/2026-09-13-round-10/README.md` | `44254e61ceffd3faa52947031b2222527e207ecd60d87743848b9fc7fbfa3e8a` | `a154c0f70a2a6b961e89dfdef8ed54eab622b5e2930bc845567f03f65e88a046` | relative-markdown-links-rewritten-only (6) |
48
+ | `confer/2026-09-13-round-2/cass.md` | `packages/trajectories/docs/research/ledger/confer/2026-09-13-round-2/cass.md` | `21c76e69f89abc8e9f774ab8e96be08dc170636a75c1b79bc694b6cbc606ea39` | `21c76e69f89abc8e9f774ab8e96be08dc170636a75c1b79bc694b6cbc606ea39` | verbatim |
49
+ | `confer/2026-09-13-round-3/README.md` | `packages/trajectories/docs/research/ledger/confer/2026-09-13-round-3/README.md` | `10afd29c8e45520c2ccd9c84ba99f10803bc0c357c62153150167bdd8112b7e2` | `53f61e79675ca390ae1e8a8f1bdfa8a66db2dccc9ecc7f4b458346cb2827d285` | relative-markdown-links-rewritten-only (6) |
50
+ | `confer/2026-09-13-round-5/README.md` | `packages/trajectories/docs/research/ledger/confer/2026-09-13-round-5/README.md` | `51fb9c9c3f6aa3a7551e31db81af97af254c36c1e0cef47d3cf3aa252f3f871c` | `b214e96243682b3a78a3119a3704fd9f2e9cfa5e20c568f67adda842d1bb450c` | relative-markdown-links-rewritten-only (6) |
51
+ | `confer/2026-09-13-round-6/README.md` | `packages/trajectories/docs/research/ledger/confer/2026-09-13-round-6/README.md` | `2050496aaf68f48884407a6dcb646f19e9fb223695b425bf40c1e6025c59bf19` | `fc9770f596f41298b4d60b9438a668bf4d2ae738963ea7f298f482bdea82a329` | relative-markdown-links-rewritten-only (6) |
52
+ | `confer/2026-09-13-round-7/README.md` | `packages/trajectories/docs/research/ledger/confer/2026-09-13-round-7/README.md` | `27ea87e1db60d4bd1cc8f3b219d66419119490901199c78a0d8e5e8b5740c1e7` | `a7871a8beca5907dd80f25dac952130a76bea6fcceeed5d28f04516a542043ad` | relative-markdown-links-rewritten-only (6) |
53
+ | `confer/2026-09-13-round-9/README.md` | `packages/trajectories/docs/research/ledger/confer/2026-09-13-round-9/README.md` | `f695bfb3a2d9010d771c719d6ef7f1fb9c4fe64f395295e4b8cfd7b2749dd1a7` | `73b79a4774ade7986f5c63d425976c2a8e1d1e9db3934631471f374b1c98e3b9` | relative-markdown-links-rewritten-only (6) |
54
+ | `confer/2026-09-14-wake/wake.md` | `packages/trajectories/docs/research/ledger/confer/2026-09-14-wake/wake.md` | `7369f061e4dbe831f43cd59fc293f318e3c7a02c095ed7ad0de6dbc6d7432cfe` | `7369f061e4dbe831f43cd59fc293f318e3c7a02c095ed7ad0de6dbc6d7432cfe` | verbatim |
55
+ | `docs/inspirations.md` | `packages/trajectories/docs/research/ledger/docs/inspirations.md` | `0555efdcfc8db9e9c35be6c6ec3b692de903fd03d1af14988cde71ba03ff63b4` | `df3da0ff9844814bd12c24e8bd937a5e1de43a6407f9623666b9c44e8e15ce2e` | relative-markdown-links-rewritten-only (1) |
56
+ | `docs/pr2-pr6-integration.md` | `packages/trajectories/docs/research/ledger/docs/pr2-pr6-integration.md` | `27ae83cbcf8c2faa73c66ce3e7db91b211f65f3336c186455e0c3b6f3ff80ad2` | `27ae83cbcf8c2faa73c66ce3e7db91b211f65f3336c186455e0c3b6f3ff80ad2` | verbatim |
57
+ | `docs/research/2026-09-07-confer-inspirations.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-07-confer-inspirations.md` | `9c4e1cff49f87f82aca9631f3614477868838d963ff3d74b577c00416430a208` | `9c4e1cff49f87f82aca9631f3614477868838d963ff3d74b577c00416430a208` | verbatim |
58
+ | `docs/research/2026-09-07-letta-continuous-service.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-07-letta-continuous-service.md` | `a636b41a93d7b72896e4d37a8a49a5d69b378ff762a7b51386283da59bfcaf0f` | `a636b41a93d7b72896e4d37a8a49a5d69b378ff762a7b51386283da59bfcaf0f` | verbatim |
59
+ | `docs/research/2026-09-08-claude-history-retrieval.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-08-claude-history-retrieval.md` | `ebb54cf725d48e645c53db2762f9cb024c0f272563678be29787fc74441e2aad` | `ebb54cf725d48e645c53db2762f9cb024c0f272563678be29787fc74441e2aad` | verbatim |
60
+ | `docs/research/2026-09-09-agentsview-native-discovery.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-09-agentsview-native-discovery.md` | `f355278d4eaac8efb7426b4c5e803128c25b1d1e5d194d32aff70d8cb848c138` | `f355278d4eaac8efb7426b4c5e803128c25b1d1e5d194d32aff70d8cb848c138` | verbatim |
61
+ | `docs/research/2026-09-09-daemon-observation.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-09-daemon-observation.md` | `8f5375194be8cfcb815ccbffad3d8100840d3e4c80f98f939351094505382c9b` | `8f5375194be8cfcb815ccbffad3d8100840d3e4c80f98f939351094505382c9b` | verbatim |
62
+ | `docs/research/2026-09-09-discovery-pagination.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-09-discovery-pagination.md` | `c2bb6df588ae69eb23a2b59c01b7571197a4ad94bb222cf6c7dfba45e05ce8cf` | `96b6605794e557c6e0a038abb8b18f31704d52fdfdc77404cf81cd6e38353fdc` | relative-markdown-links-rewritten-only (1) |
63
+ | `docs/research/2026-09-09-harness-transcript-contract.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-09-harness-transcript-contract.md` | `5fdf934f351a6eca66eb0ecd9022ae431eba4117db402cfad4955bb6466b299a` | `0c05ce1a60bd6f28d443086a3ff132f27be5f19b09e5b2768614a040dd2201c3` | relative-markdown-links-rewritten-only (1) |
64
+ | `docs/research/2026-09-09-native-history-discovery.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-09-native-history-discovery.md` | `efdbf356e4c2ed111067c7426f977c693b7c77123567a83f3c77400e3f2debd4` | `ad6493f6bc48d02dc177e35e65a40c557fd19db2b0d1e25235964113c222540d` | relative-markdown-links-rewritten-only (1) |
65
+ | `docs/research/2026-09-09-native-history-implementation.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-09-native-history-implementation.md` | `c22b2fd509d098f10865c57f5c30a57cfbbaab4fb6e078fa253275229058cc64` | `c22b2fd509d098f10865c57f5c30a57cfbbaab4fb6e078fa253275229058cc64` | verbatim |
66
+ | `docs/research/2026-09-09-other-inspirations.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-09-other-inspirations.md` | `4819acf55cd230a53e0728d7e4e34367f3d90f6d573cae5482f6d1d9cd62d5a1` | `4819acf55cd230a53e0728d7e4e34367f3d90f6d573cae5482f6d1d9cd62d5a1` | verbatim |
67
+ | `docs/research/2026-09-09-trajectory-and-letta-code.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-09-trajectory-and-letta-code.md` | `02208cabe339c5ef942fa33d6557db7b1b691562a22d6b365a481e6c353f21ee` | `1e0ea3e3ccfe072a0e8430515c28af739afa6b2da0a5fe32b03b55d0467bfe3d` | relative-markdown-links-rewritten-only (1) |
68
+ | `docs/research/2026-09-13-diagnostics-coverage.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-13-diagnostics-coverage.md` | `115a6143214b34c4672a64b25aef3b29621cf88fa50bc2f38313fecbb760ab30` | `115a6143214b34c4672a64b25aef3b29621cf88fa50bc2f38313fecbb760ab30` | verbatim |
69
+ | `docs/research/2026-09-13-fts-rebuild.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-13-fts-rebuild.md` | `329893715deaaa9928aa935a5ada161e186f445b90f26b014603548fba422861` | `329893715deaaa9928aa935a5ada161e186f445b90f26b014603548fba422861` | verbatim |
70
+ | `docs/research/2026-09-13-read-path-split.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-13-read-path-split.md` | `8f5442beb04b340b2efd13403d9def649310b6aa785c07b53f8e39001e89388b` | `1c5617e8d46d66743a004e9be75f6ac3b8f92e108e294878dd8573b0d5012f16` | relative-markdown-links-rewritten-only (1) |
71
+ | `docs/research/2026-09-13-runtime-rollout.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-13-runtime-rollout.md` | `62c64f0996dba7ef3d6f952d59ec51b7695d5937876ae6652481c0ba65ba218a` | `f58ac18e567b01ffde421606cd1e1da645dcb9cfee05a7009157a696240428c4` | relative-markdown-links-rewritten-only (1) |
72
+ | `docs/research/2026-09-13-scan-outcomes.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-13-scan-outcomes.md` | `56809f100094083b79b8f8b5aac874e309a2c638ba71c9792f2c3944480641d2` | `44ab19c1168db5755e0fd50bb3c8a753045cc14865915abcc12e715136be499c` | relative-markdown-links-rewritten-only (1) |
73
+ | `docs/research/2026-09-13-search-quality.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-13-search-quality.md` | `fb279b7c17b7ff1efa91c7b2372d6c8311bcc82268c1f710a854952f214290cd` | `3d766f9d1bd664dab572889217949d1937b393ada810e3e2e62ece61a44fbac6` | relative-markdown-links-rewritten-only (1) |
74
+ | `docs/research/2026-09-13-source-coverage.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-13-source-coverage.md` | `1110deac61390c7cb71cb42c1f9576c0e93ee01aae430ea13108e4c7b661c984` | `37b73217da5cd48fb0191a82e6ae612658b473a93123b401a8776aac97c2a3d6` | relative-markdown-links-rewritten-only (1) |
75
+ | `docs/research/2026-09-13-sync-wall-budget.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-13-sync-wall-budget.md` | `1ad94f66f4dea3419b3833ad251995966e30d0adc3068c2aa25769ccabda4a23` | `ff814019d32c1ad580b21811541d76a29e6bfe602f2e39e2e248de05f69463a1` | relative-markdown-links-rewritten-only (1) |
76
+ | `docs/research/2026-09-13-typed-read-gate.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-13-typed-read-gate.md` | `b8986e031ed75bf406f78fa9bd08a3fdb22f3ade64542fe9f5613fa4aac71d2b` | `1836755adcd4cdb5dc9b36385a3f3b1a2d652fc83a73a82b838330a7d6c77058` | relative-markdown-links-rewritten-only (1) |
77
+ | `docs/research/2026-09-13-writer-lease.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-13-writer-lease.md` | `faf243cc3806c4092a28754694eae4fed353a0858493e0c52dfaabbd2712fe9b` | `baa8ea384bbeb8f174b0bc110d6b5e8535321bfcb596d4a46a9ac2555c187ab1` | relative-markdown-links-rewritten-only (1) |
78
+ | `docs/research/2026-09-16-c1-copy-fallback.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-16-c1-copy-fallback.md` | `0511562c37aae9ee2a2c084c4cb57307ade18c6582eeea88c984da4b4f17a4b0` | `0511562c37aae9ee2a2c084c4cb57307ade18c6582eeea88c984da4b4f17a4b0` | verbatim |
79
+ | `docs/research/2026-09-16-c10-kimi.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-16-c10-kimi.md` | `5e36bb0db62a75ce0262cf1df5668dd176d1ae920b0ab9693f565ba0b4062ab5` | `5e36bb0db62a75ce0262cf1df5668dd176d1ae920b0ab9693f565ba0b4062ab5` | verbatim |
80
+ | `docs/research/2026-09-16-c2-derive-counter.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-16-c2-derive-counter.md` | `c81fc27fa5c801fcb32306a160d1e8461764f771a2e2581a44df177e1681d821` | `c81fc27fa5c801fcb32306a160d1e8461764f771a2e2581a44df177e1681d821` | verbatim |
81
+ | `docs/research/2026-09-16-c3-echo-filter.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-16-c3-echo-filter.md` | `0c58ee7286cb7504ed338859a11ae7d7c556c24fec8d76ca45181a0e4a8162f4` | `0c58ee7286cb7504ed338859a11ae7d7c556c24fec8d76ca45181a0e4a8162f4` | verbatim |
82
+ | `docs/research/2026-09-16-c4-title-index.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-16-c4-title-index.md` | `dfeb51cc018da0316d313559e3ef8d96bf88ca8f68acc6c4d8f8c57dfaf938ee` | `dfeb51cc018da0316d313559e3ef8d96bf88ca8f68acc6c4d8f8c57dfaf938ee` | verbatim |
83
+ | `docs/research/2026-09-16-c5-trigram.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-16-c5-trigram.md` | `65099e8a3f50ace49e4eab5d09815c5d7aa04f3fa0c0dfbdb746de242b275f94` | `65099e8a3f50ace49e4eab5d09815c5d7aa04f3fa0c0dfbdb746de242b275f94` | verbatim |
84
+ | `docs/research/2026-09-16-c6-recency-prior.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-16-c6-recency-prior.md` | `0c224e6b1f9ec4b44a2d4f149558bc28500908c16ad4a86b8d4179a112da7e7d` | `0c224e6b1f9ec4b44a2d4f149558bc28500908c16ad4a86b8d4179a112da7e7d` | verbatim |
85
+ | `docs/research/2026-09-16-c7-tombstones.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-16-c7-tombstones.md` | `e89f48676ce31efd53910f385592409ee5e0e963db98b7739871301d62c859e5` | `e89f48676ce31efd53910f385592409ee5e0e963db98b7739871301d62c859e5` | verbatim |
86
+ | `docs/research/2026-09-16-c8-remote-truth.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-16-c8-remote-truth.md` | `b938739cfc75535950a361c57a31a65e3afda8799305385721143ca69ebb7bc4` | `b938739cfc75535950a361c57a31a65e3afda8799305385721143ca69ebb7bc4` | verbatim |
87
+ | `docs/research/2026-09-16-c9-grok.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-16-c9-grok.md` | `eea295814219519ce73018c5d2adbf6744f53ba6d1e9424372fc1063259203c3` | `eea295814219519ce73018c5d2adbf6744f53ba6d1e9424372fc1063259203c3` | verbatim |
88
+ | `docs/research/2026-09-16-wake-port-program.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-16-wake-port-program.md` | `4f51e32d4a505093a1df5c8793aa1288c172e1d79a2d9635ac37d44bda604700` | `4f51e32d4a505093a1df5c8793aa1288c172e1d79a2d9635ac37d44bda604700` | verbatim |
89
+ | `docs/research/2026-09-17-cursor-blobstore.md` | `packages/trajectories/docs/research/ledger/docs/research/2026-09-17-cursor-blobstore.md` | `8ce6ea4dab7b138af4237d35f9b0fdbf0dd1798c8bfb0219378d4fd052375f55` | `8ce6ea4dab7b138af4237d35f9b0fdbf0dd1798c8bfb0219378d4fd052375f55` | verbatim |
90
+
91
+ ## Excluded material
92
+
93
+ Large experiment outputs, native histories, databases, transcript bodies and archives
94
+ remain in Ledger's own retained history or external evidence stores. Source files,
95
+ runbooks, case studies, decisions, lab protocols and non-cited Confer reports outside
96
+ this bounded packet are linked to immutable Ledger blobs when referenced.
@@ -0,0 +1,61 @@
1
+ # Confer round 10 — 2026-09-13
2
+
3
+ Deadline/watchdog round. Pins: all six unchanged (trajectory `21ae92d`
4
+ 10th, obelisk `45eaac8b` 9th, agentsview `532fd652` 6th, cass `6d445f6`
5
+ 5th, vercel/ai `6c6c2210`, letta-code `1ec6a43f` 3rd). Baseline: main
6
+ `cb3d414`.
7
+
8
+ | Repo | File |
9
+ | --- | --- |
10
+ | letta-ai/trajectory | [trajectory.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-10/trajectory.md) |
11
+ | letta-ai/letta-code | [letta-code.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-10/letta-code.md) |
12
+ | tommy0103/obelisk | [obelisk.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-10/obelisk.md) |
13
+ | dicklesworthstone/cass | [cass.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-10/cass.md) |
14
+ | kenn-io/agentsview | [agentsview.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-10/agentsview.md) |
15
+ | vercel/ai harness | [vercel-ai-harness.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-10/vercel-ai-harness.md) |
16
+
17
+ ## Cycle-10 decision: enforce the sync wall budget across worker waits (#35)
18
+
19
+ Scout defect map on main: `workDeadline` is consulted only at the two
20
+ admission gates (`sync.ts:713/723`); the worker wave `Promise.all`
21
+ (`:777`) has no timeout; `spawnJsonChild` (`:389-428`) fires
22
+ SIGTERM→SIGKILL on its timer but **never settles the awaited promise** —
23
+ a hung child stdout drain hangs the parent forever; `handleSync` has no
24
+ signal handlers, so launchd's SIGTERM kills the parent and orphans the
25
+ children. That is exactly the observed 75-minute zero-CPU hold.
26
+
27
+ Design (sources in brackets):
28
+
29
+ 1. **Settle the spawn promise**: on timeout, the kill sequence
30
+ (SIGTERM → grace → SIGKILL, already present) must end with the
31
+ promise settling to a typed timeout result (pid, budget, phase);
32
+ the stdout drain races the kill so it cannot outlive it. Workers
33
+ that are slow-but-alive within their own budget are untouched.
34
+ [cass PAGE_SLEEP vs PARK pair is the pinned distinction]
35
+ 2. **One absolute deadline, recomputed** (`workDeadline`, already
36
+ computed): clamp `min(remaining wall, per-worker budget)` into every
37
+ wave wait; the last wait can never overshoot. On wall expiry: typed
38
+ outcome, kill remaining children (group semantics — the children are
39
+ ours), proceed to summary. [harness deadline-clamp rule; letta-code
40
+ outer group kill + cooperative inner wall]
41
+ 3. **Truthful reporting**: `SyncSummary.outcome` gains
42
+ `wall_budget_exceeded` with completed-so-far counts and the elapsed —
43
+ a bounded pass is a result, not a hang. [cass compact typed abort
44
+ line; agentsView named ReasonFinalizationTimeout]
45
+ 4. **Lease invariant preserved**: the abort path runs the existing
46
+ `finally` (lease release) — the deadline signal must live outside
47
+ the cleanup path so an abort cannot inherit the wedge.
48
+ [letta-code: keep the deadline out of the abort path]
49
+ 5. Tests mirror cass's fault pair: a never-replying worker (PARK) →
50
+ pass aborts at the wall with the typed outcome, no orphan children,
51
+ lease released, summary truthful; a slow-but-progressing worker
52
+ (PAGE_SLEEP) within budget → completes normally; normal passes
53
+ byte-identical summaries (regression).
54
+
55
+ ## Deferred
56
+
57
+ - Progress-watermark stall detection inside workers (obelisk's
58
+ insight: watch a watermark, not just the clock) — the worker budget
59
+ already bounds each child; a watermark matters only for multi-minute
60
+ per-worker budgets.
61
+ - Watcher drain deadlines (watch has its own paths; separate surface).
@@ -0,0 +1,72 @@
1
+ # coding_agent_session_search (Cass) — round 2 (widening mechanics, robot envelope, FTS5 probe, qrels gate)
2
+
3
+ ## Outcome
4
+
5
+ Four implementation-grade extracts for Ledger's cycle-2 search-quality work, all re-read at the refreshed pin. (1) Sparse-query widening is a **bounded rerun of the same search with a different query string**: five cheap gates, strictly-more acceptance, per-hit tagging, and explicit reporting. (2) The robot envelope splits into honesty fields Ledger can compute from one FTS5 table + optional embeddings, versus Tantivy/searcher-cache shard machinery to omit verbatim. (3) The FTS5 probe is a one-line special command whose *placement* matters: never on the search path, always before a destructive operation, dry-run-first repair. (4) The quality gate is a checked-in qrels fixture scored by a pure core, wired into CI **by filename**, and offline because semantic acquisition is pinned to a deterministic local embedder.
6
+
7
+ ## Pin (delta)
8
+
9
+ - Round-2 pin `dicklesworthstone/coding_agent_session_search@c7cd1ad3ff7ee5d4323b9c840dcfcda683881e36` (`cass@c7cd1ad`); round-1 `07aa43e2` is an ancestor, **11 commits** between, none touching this round's subject files. `src/lib.rs` gained +20 lines net, all in mirror/prune/clipboard regions, so envelope anchors shift **+20** (`SearchCursorManifestInput` 33835→33855; `"cursor_manifest"` inserts 34716→34736) — content identical. `ci.yml`, `src/search/query.rs`, `src/indexer/mod.rs`, `src/search_quality_eval.rs`, `src/search/storage_integrity.rs` **unchanged**. Every round-1 substantive claim survives; only the `lib.rs` anchors move.
10
+ - Clone: `/tmp/ledger-confer/round-2/cass` (round-1 shallow clone, `git fetch --depth 300`, `git checkout origin/main`). Read-only, never copied into the Ledger tree.
11
+
12
+ ## 1. Sparse/zero-result widening — exact mechanics
13
+
14
+ - **Gate** (all cheap; no second query until every predicate passes) `cass@c7cd1ad:src/search/query.rs#L6754-L6772`: *sparse* = `returned_hits < min(sparse_threshold, limit)` when `limit > 0` else `< sparse_threshold`, and **`offset != 0` never widens** `#L3943-L3958`; *no explicit syntax* — no `*` in the query, `fs_cass_has_boolean_operators` false (AND/OR/NOT case-insensitive, `&&`, `||`, any quoted phrase; asserted `#L19307-L19315`), `query.trim()` non-empty; *index ceiling* — `index_doc_count <= CASS_AUTOMATIC_WILDCARD_FALLBACK_MAX_DOCS` (default `10_000`, `0` disables the feature) `#L792`, `#L811-L826`; *long-token guard* — only when `returned_hits == 0`, skip if any term exceeds `AUTOMATIC_WILDCARD_FALLBACK_MAX_TOKEN_CHARS = 16` `#L738`, `#L3962-L3974`. Threshold origin: CLI passes `3`, capped to the visible limit unless aggregation over-fetched (`src/lib.rs#L30429`, `#L30457`, `fn sparse_threshold_for_visible_limit` `#L27009-L27018`); the TUI passes `0`, i.e. interactive search never widens `src/ui/app.rs#L15625`.
15
+ - **Shape / acceptance / tagging**: `query.split_whitespace().map(|t| format!("*{}*", t.trim_matches('*'))).join(" ")` `#L6820-L6826`, re-parsed by the same engine (`let mut fallback_hits = self.search(&wildcard_query, …)?` `#L6831-L6832` — a widened-query parse error propagates, it is not swallowed). Adopt **iff `fallback_hits.len() > hits.len()`** (strictly larger), else the original page is returned untouched `#L6842`. Every adopted hit gets `match_type = MatchType::ImplicitWildcard` `#L6843-L6845`, whose `quality_factor()` is **0.6** `#L1455` — the tag feeds ranking/trust math, not just reporting. Suggestions are generated only on a true zero `#L6803-L6807`, `#L6848-L6852`.
16
+ - **Reporting**: `SearchResult.wildcard_fallback: bool` `#L1846-L1850` → robot `_meta.wildcard_fallback` (`src/lib.rs#L34715`) and the JSONL `_meta` **header line** (`#L34867`); `_meta.query_plan` flips `QueryPhase::Lexical.realized` true (`src/query_cost_planner.rs#L117-L119`) with reason "lexical phase realized with wildcard fallback" (`#L289-L291`); explanation card `search.wildcard_fallback` (`src/explainability.rs#L152-L171`) with `fail_open: true`, `realized_tier: "lexical"`, `operator_action: "quote terms or use explicit wildcards to control breadth"`, `rollback_trigger: "unexpected broad matches in the first result page"`. The refusal path is `tracing::debug!` only `#L6773-L6780` — **not** agent-readable, which Ledger should fix.
17
+ - **Ledger naming (proposal, in Ledger's idiom).** Ledger has no boolean/wildcard syntax surface (`buildFtsExpression` phrase-wraps multi-word input, `db.ts#L1522-L1535`) and no meta line, so widen into a `type`-discriminated header — the idiom Ledger already uses for `build`/`watch`/`emit-pi` (`docs/api-surface.md#L299-L306`):
18
+
19
+ ```json
20
+ {"type":"search_meta","query":"…","limit":20,"count":3,"total_hits":3,
21
+ "count_precision":"exact","count_reason":"fewer hits than the requested limit; the scan was exhausted",
22
+ "elapsed_ms":4,"search_mode":"lexical","requested_search_mode":"lexical","fallback_reason":null,
23
+ "widened":{"applied":true,"reason":"sparse_result","widened_query":"artifacts* OR hosting* OR subdomain*",
24
+ "original_hits":0,"widened_hits":3,"threshold":3,"corpus_records":4120},
25
+ "index_freshness":{"…":null},"storage_integrity":{"storage_state":"ok"}}
26
+ ```
27
+ - Naming rules borrowed: `count_precision` + `count_reason`; a **typed** `fallback_reason` (never prose); `widened` as a nested object so both the applied and the refused path are machine-checkable (`applied:false` + `skip_reason`); per-hit `SearchHit.match_type?: "lexical" | "implicit_wildcard"` so a consumer branches without joining back to the meta line.
28
+
29
+ ## 2. Robot envelope — field semantics, and what Ledger must not copy
30
+
31
+ - Top level `src/lib.rs#L34637-L34649`: `query, limit, offset, count, total_matches, hits, max_tokens, request_id, cursor, hits_clamped, budget`, plus conditional `sessions_filter{requested,matched}`, `sessions_filter_warning`, `suggestions`, `aggregations`, `explanation`, `_meta`, `_warning`, `_timeout`. `_meta` (only with `--robot-meta`) `#L34704-L34743` + conditionals `#L34739-L34792`: `elapsed_ms, search_mode, requested_search_mode, mode_defaulted, fallback_tier, fallback_reason, semantic_refinement, refinement_level, semantic_fallback_reason, lexical_degrade_reason, wildcard_fallback, cache_stats{…}, timing{search_ms,rerank_ms,other_ms}, tokens_estimated, max_tokens, request_id, next_cursor, hits_clamped, query_plan, cursor_manifest, explanation_cards` + `state`, `index_freshness`, `search_completeness`, `storage_integrity`, `timeout_ms`/`timed_out`/`partial_results`, `ann_stats`, `ann_unavailable_reason`.
32
+ - `cursor_manifest` `#L33878-L33986`, per-field semantics and Ledger verdict:
33
+
34
+ | Field | Semantics (OBSERVED) | Ledger |
35
+ | --- | --- | --- |
36
+ | `count_precision`, `count_reason` | `exact` iff the engine COUNT collector ran (`result.total_count.is_some()`, `src/lib.rs#L30953`), requiring `index_doc_count <= DEFAULT_EXACT_TOTAL_COUNT_MAX_DOCS = 50_000` (`src/search/query.rs#L790-L805`); else `lower_bound` = `offset + displayed + has_more` `#L30963-L30968` | **keep** — `exact` iff `hits.length < limit`; today Ledger's `totalHits` is always `hits.length` (`db.ts#L1635-L1640`, `#L1430-L1434`, `#L1514-L1518`) = an unlabeled lower bound |
37
+ | `continuation_safe`, `continuation_reason` | `= next_cursor_present && !timed_out && !index_rebuilding` `#L33884`, else a first-match-wins ladder: window exhausted / no cursor emitted / timeout partial / rebuilding / clamped `#L33885-L33897` | **defer** — Ledger has no offset/cursor (`executeFtsQuery` emits `LIMIT ?` only, `db.ts#L1537-L1546`; no paging flag in `docs/api-surface.md#L34-L67`), so the field would be constant |
38
+ | `field_mask`, `token_budget`, `budget`, `hits_clamped`, `realized_limit`, `search_page_count` | `--fields` projection; token/time budget shedding | omit — no `--fields`/`--max-tokens`; Ledger's only truncation is a 240-char snippet `cli.ts#L581` |
39
+ | `cache_generation{reader_generation,reloads,reload_ms_total,policy,ghost_entries,admission_rejects}` | Tantivy searcher-cache lifecycle | **omit verbatim** — engine/shard machinery, no `bun:sqlite` analogue |
40
+ | `index_generation{lexical_shard_generation,freshness,stale,partial,partial_reason,rebuilding,pending_sessions}` | shard id is shard-specific; `partial`/`partial_reason` are round-1's durable-signal win (checkpoint present but not completed; scan watermark ahead of indexed watermark) | **keep the subset** squashed to `{stale, partial, partial_reason, pending_sessions}`, derived from `ingest_cursors.status`/`updated_at` + `ingest_queue.attempt_count`/`next_attempt_at` (`schema.ts#L80-L118`) — no new table |
41
+ | `semantic_fallback{requested,realized,fallback_tier,fallback_reason,semantic_refinement}` | typed reasons (`semantic_absent`, `semantic_backfilling`, …) so agents branch without prose | **keep — highest value here**: `querySemantic` silently returns `{hits: []}` when no compatible vectors exist or `embed()` yields nothing (`db.ts#L1299-L1304`, `#L1319-L1321`), and `queryHybrid` cannot tell the caller half its input was empty (`db.ts#L1450-L1458`) |
42
+ | `search_completeness` | quarantine exclusions ⇒ *known* conversations absent: `{quarantine_status: ok\|degraded, quarantined_conversations, complete, can_search}` (`src/search/quarantine_status.rs#L196-L228`) | **keep the shape, change the cause** — Ledger's analog is failed/deferred normalization (PR17 `ingest_diagnostics`), i.e. `{complete, missing_sessions, reason}` |
43
+ | `storage_integrity` | `StorageState` (with `Unchecked` so openability is never reported as `ok`, `src/search/storage_integrity.rs#L83-L89`), per-check `{name, elapsed_ms, timed_out, skipped_reason, read_only}` `#L116-L136`, `default_risk` (`FtsMetadataFailed` ⇒ Low) `#L166-L178` | **keep for `status`, optionally in `search_meta`** — see §3 |
44
+
45
+ ## 3. FTS5 integrity — probe, cadence, safe-next-action ladder
46
+
47
+ - **Probe** `src/indexer/mod.rs#L19781-L19803`: `sqlite_master` existence check, then `INSERT INTO fts_messages(fts_messages) VALUES('integrity-check')`. Doc comment `#L19774-L19780`: "`PRAGMA quick_check` validates SQLite's b-trees, but it does not understand the payload stored inside `%_data`, so it can report `ok` for the exact corrupt-segment shape seen in GH #374. The special command is read-only despite its INSERT syntax." Classification `#L19797-L19803`: a `retryable_franken_error` (transient contention) becomes a **hard error**, never a corruption verdict; anything else → `Some("FTS5 segment integrity-check failed: {err}")`.
48
+ - **Cadence**: only in the read-only **full-rebuild preflight**, before any writable open (the writable open itself repairs schema objects) `#L15602-L15615` → `full_rebuild_existing_archive_integrity_preflight` `#L19884-L19957`; size-gated at 2 GiB (`DEFAULT_INDEX_INTEGRITY_PREFLIGHT_MAX_BYTES`, env-overridable, `0` = always `#L19700-L19720`), over the cap every engine-backed query is skipped with a warning routing to `cass doctor check --json` `#L19810-L19821`. Never startup, never per-query. Pinned by a test that seeds one segment, overwrites its `fts_messages_data.block`, and asserts the preflight names the probe `#L49845-L49890`.
49
+ - **Doctor ladder** (on demand only): `doctor_database_quick_check` runs `PRAGMA quick_check(1)` `src/lib.rs#L37376-L37385`, then `doctor_database_integrity_probe` runs `PRAGMA integrity_check(20)` **only if quick_check is `ok`** `#L37419-L37432`; diagnostics are bounded to 20 rows + "N additional diagnostic row(s) omitted" `#L37342-L37371`; `failed_pragma_name()` names the failed probe `#L37467-L37474`.
50
+ - **Safe-next-action ladder**: (1) *refuse the destructive operation* — `needs_rebuild = true` + a `"database","fail"` check carrying pragma name and row counts `src/lib.rs#L88856-L88872`, and the indexer returns `canonical_archive_unhealthy_for_index_error` instead of replacing the archive `src/indexer/mod.rs#L15604-L15615`; (2) *classify derived vs canonical* — a queryable FTS shadow whose docsize count fails is only `"fts_table","warn"` with remedy ``cass doctor --rebuild-canonical-fts --yes`` `src/lib.rs#L88845-L88852`, and `FtsMetadataFailed` carries `SourceOfTruthRisk::Low` because canonical rows survive `storage_integrity.rs#L166-L178`; (3) *dry-run first* — without `--yes` the repair refuses with exit code 4, kind `refused-unsafe`, hinting the inspect-then-apply sequence `src/doctor_recover.rs#L621-L636`, and an unopenable shadow is reported only because the dry run must not lock `#L653-L678`; (4) *escalate, don't improvise* — if both structured opens fail, preserve db+`-wal`+`-shm`+sidecars and route to recovery commands `#L690-L703`; (5) *never claim health without a probe* — `Unchecked` exists for "db_open succeeded, nothing structural ran" `storage_integrity.rs#L83-L89`.
51
+ - **Ledger-dialect verification** (my own throwaway `bun:sqlite` 1.3.14 scripts in `/tmp`, now deleted — not Cass behaviour): `INSERT INTO records_fts(records_fts) VALUES('integrity-check')` and the rank-1 variant both return cleanly on a healthy table, as does `('merge', N)`/`('automerge', 4)` which Ledger already issues (`db.ts#L108`, `sync.ts#L420`). Cass's `*term*` shape is **not translatable**: `MATCH '*artifacts*'` → `unknown special query: artifacts*`; the FTS5 equivalent is an OR-join of prefixes (`artifacts* OR hosting* OR subdomain*`, which widened a 1-hit phrase query to 2 hits). Blind byte-corruption over pages 3..120 of a 3000-row fixture did **not** reproduce a "quick_check ok / integrity-check ERR" divergence on stock SQLite, and FTS shadow tables are write-protected ("table f_data may not be modified") — so a Ledger regression test for the corrupt-`%_data` case needs a crafted DB file. The probe's justification is the decode/checksum it performs (and rank 1 also verifies index-vs-content), which is exactly what Ledger's own in-place FTS rewrite in the v3→v4 migration needs after the fact (`UPDATE records_fts SET record_id = …, session_id = …`, `schema.ts#L223-L229`).
52
+
53
+ ## 4. Search-quality gate — qrels fixture, metrics, drift diff, CI wiring
54
+
55
+ - **Fixture**: `{_comment, qrels:[{id, query, mode?, expected_refs[], k, note?}]}` (`src/search_quality_eval.rs#L62-L77`; 5 checked-in judgments in `tests/fixtures/search_quality/qrels.json`) plus a corpus manifest `{_comment, docs:[{stem, keywords[], age_days, extra_text}]}` seeded as **real harness sessions** (`tests/fixtures/search_quality/corpus.json`; `struct CorpusDoc` `tests/e2e_search_quality_gate.rs#L99-L105`, `fn load_corpus` `#L123`, `fn seed_corpus_doc` `#L153`, reduction `fn run_qrel` `#L239-L296`). Queries are distinctive single tokens, multi-ref recall is two entries in `expected_refs`, one doc is aged 400 days to exercise the live trust tier, one carries a planted email `#L63`.
56
+ - **Metrics** (pure, deterministic): `QueryRun{qrel, observed, realized_mode, fallback_tier, latency_ms}` → `evaluate()` gives `recall@k = |expected ∩ observed[..k]| / |expected|`, `precision@k = |expected ∩ observed[..k]| / min(k, |observed|)`, `mrr = 1/rank(first expected)`; `passed` requires recall = precision = 1.0 (±1e-9) **and** no unexpected top-k ref **and** a non-empty judgment (`#L112-L150`, `#L268-L369`). Aggregates `query_count, passed_count, failed_count, mean_recall_at_k, mean_precision_at_k, mean_mrr, mean_latency_ms, trust_tier_distribution, realized_mode_counts` `#L152-L171`; report `{schema_version: 1, label?, queries[], aggregate}` `#L175-L187`.
57
+ - **Drift diff**: `diff_reports(baseline, current)` joins by qrel id → `QueryDiff{recall_delta, precision_delta, mrr_delta, newly_missing_refs, regressed}` and `RegressionDiff{mean_*_delta, per_query, dropped_query_ids, added_query_ids, regressed_query_ids, has_regression}`; `regressed` = any metric dropped beyond 1e-9 **or** a previously-found ref vanished `#L431-L517`. OBSERVED: no CLI call site (`grep -rn diff_reports` matches only its module + the gate's import) — drift is a library API; the shipped gate asserts absolute conformance.
58
+ - **Privacy**: refs pass `sanitize_doc_ref` (alnum + `.`/`-`/`_`, ≤128 chars) and a non-canonical ref becomes a `__invalid_doc_ref__` sentinel that still reduces precision rather than transforming private text `#L56`, `#L228-L250`; the gate asserts the planted email never reaches either artifact `tests/e2e_search_quality_gate.rs#L470-L478`.
59
+ - **CI wiring without network**: the gate is `tests/e2e_search_quality_gate.rs`, discovered by glob in the `test-rust` job — `mapfile -t tests < <(git ls-files 'tests/e2e_*.rs' | sed …)` then `E2E_LOG=1 cargo test --features "qr encryption backtrace" --test <each>` (`.github/workflows/ci.yml#L363-L371`, `#L411-L425`): **the filename is the wiring** (no `#[ignore]`, no allowlist, no workflow edit). Offline-ness is env-enforced in the child: `CASS_SEMANTIC_EMBEDDER=hash` (deterministic local embedder, so `--hybrid` needs no model download), tempdir `HOME`/`XDG_*`/cwd, `CODING_AGENT_SEARCH_NO_UPDATE_PROMPT=1`, `NO_COLOR=1` `#L186-L200`; hangs become diagnostics via the bounded runner `spawn_with_timeout_or_diag` (120 s index / 60 s search `#L55-L57`); artifacts honour `CASS_SEARCH_QUALITY_ARTIFACT_DIR` else tempdir `#L446-L451`.
60
+
61
+ ## Ledger integration points (main `2b08be4`)
62
+
63
+ - **Widening** — `db.ts#L1108-L1131` (`queryLexical`): the `catch`-only fallback is invisible and fires on syntax errors, not sparsity; `buildFtsExpression` `#L1522-L1535` phrase-wraps every multi-word query, so `"artifacts hosting subdomain"` demands adjacency. Port the gate (offset/limit-aware threshold, no-op on explicit syntax, corpus ceiling, long-token guard, strictly-more acceptance) with an FTS5-legal widened expression (`term* OR term*`), a `widened` field on `QueryResult` (`types.ts#L190-L195`), `match_type` on widened hits, and a `{"type":"search_meta",…}` line emitted before the hit stream `cli.ts#L574-L592`. Propagate through `queryHybrid` (`db.ts#L1438-L1520`), which today discards the lexical result's identity when re-ranking into `scoredMap`.
64
+ - **Envelope** — `cli.ts#L574-L592` assembles bare hit objects and `docs/api-surface.md#L299-L306` documents that stream, so the meta line must be `type`-discriminated and additive. Derive `count_precision` in `executeFtsQuery` (`db.ts#L1537-L1640`) from `hits.length < limit`; `index_freshness`/`search_completeness` from `ingest_cursors` + `ingest_queue` + PR17 `ingest_diagnostics` (no new table); `semantic_fallback` from `querySemantic`'s silent empty returns (`db.ts#L1299-L1304`, `#L1319-L1321`). Omit `cache_generation`, `lexical_shard_generation`, `field_mask`, `token_budget`, `budget`, `hits_clamped`, and defer `continuation_*` until Ledger has paging.
65
+ - **FTS probe** — home is the existing maintenance child (`sync.ts#L411-L431`: `('merge', N)`, `PRAGMA optimize`, `PRAGMA wal_checkpoint(PASSIVE)`, reply fields `fts_changes`/`optimize_actions`/`wal_*`; `db.ts#L104-L110` sets `('automerge', 4)`), reporting `fts_integrity: "ok"|"failed"`; surface it in `ledger status` as a `storage_integrity` field with a `read_only: true` check record, and refuse a full FTS rebuild rather than rebuilding a shadow that failed its probe. Never on the search path; rank-1 check is the post-migration verification for `schema.ts#L223-L229`.
66
+ - **Qrels gate** — Ledger's runner is `bun test` (`packages/core/package.json`), tests in `packages/core/tests/*.test.ts`; a fixture-driven `search-quality.test.ts` (qrels JSON + a seeded store) needs no new harness, and Ledger's equivalent of `CASS_SEMANTIC_EMBEDDER=hash` is the lexical-only default plus the `applyEmbeddingProvider` overrides in `cli.ts#L528`.
67
+
68
+ ## Boundaries
69
+
70
+ - **No code reused.** Cass carries a nonstandard license rider; this is pattern/vocabulary extraction only — no Cass source copied, translated, or vendored, only JSON field names, state vocabularies, and probe/cadence decisions cited as precedent.
71
+ - No Cass build, test, or binary was run; all Cass claims are static reads of `cass@c7cd1ad` (`/tmp/ledger-confer/round-2/cass`). §3's FTS5 experiments are `bun:sqlite` results on throwaway `/tmp` databases (deleted), labelled as Ledger-dialect, not Cass behaviour. Ledger was inspected read-only at `2b08be4`.
72
+ - Out of scope (as round 1): federated/remote search, fleet surfaces, TUI, semantic model acquisition, encryption/pages assets — plus, this round, cursor pagination, which Ledger cannot use until it has offset/cursor search at all.
@@ -0,0 +1,70 @@
1
+ # Confer round 3 — 2026-09-13
2
+
3
+ Delta round: pins mostly frozen (obelisk `45eaac8b` ×3 rounds, trajectory
4
+ `21ae92d` ×3, vercel/ai `6c6c2210` ×2, agentsview `532fd652` ×2; letta-code
5
+ +1 telemetry commit, cass +2 test-only commits). Value this round is the
6
+ cycle-3 focus: participating-writer ownership. Baseline: main `b20664a`.
7
+
8
+ | Repo | Pin | File |
9
+ | --- | --- | --- |
10
+ | letta-ai/trajectory | `21ae92d` (8 open PRs census-corrected) | [trajectory.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-3/trajectory.md) |
11
+ | letta-ai/letta-code | `6a12dcb0` | [letta-code.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-3/letta-code.md) |
12
+ | tommy0103/obelisk | `45eaac8b` | [obelisk.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-3/obelisk.md) |
13
+ | dicklesworthstone/cass | `3ac128bf` | [cass.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-3/cass.md) |
14
+ | kenn-io/agentsview | `532fd652` | [agentsview.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-3/agentsview.md) |
15
+ | vercel/ai harness | `6c6c2210` | [vercel-ai-harness.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-3/vercel-ai-harness.md) |
16
+
17
+ ## Cycle-3 decision: hard writer lease between CLI verbs and the daemon
18
+
19
+ Verified on main (WritePathScout3): the shipping daemon is a 15-minute
20
+ oneshot `sync` (launchd `StartInterval` 900 / systemd timer 15min) — not an
21
+ always-on watch; `new TrajectoryDb()` writes DDL in its constructor, so the
22
+ lease must attach BEFORE any `new TrajectoryDb()` (mutating entry points:
23
+ `cli.ts` handleBuild, `sync.ts` runSync:541 + worker children :242,
24
+ `watch.ts` startWatching:223); today's only arbitration is
25
+ `busy_timeout=15000` — 15s of silent blocking.
26
+
27
+ Design (sources in brackets):
28
+
29
+ 1. **Sibling lock DB** `<dbPath>-write.lock`: bare SQLite connection,
30
+ `busy_timeout=0`, `BEGIN IMMEDIATE`, attempt budget `ceil(waitMs/25)+1`,
31
+ busy-only retry, non-busy rethrow; connection close = release; process
32
+ death releases via fd teardown — no TTL, no reaper, no pid-liveness
33
+ checks (which letta-code.md shows are zombie-broken on darwin anyway).
34
+ 2. **Metadata-bearing lease, two-phase acquire**: the holder label commits
35
+ in its own transaction FIRST, then the lease is taken with a held
36
+ `BEGIN IMMEDIATE` and kept uncommitted for the lease lifetime — a
37
+ contender arriving in the commit-to-hold gap simply sees busy, and the
38
+ committed label lets any refusal name the holder. Release deletes the
39
+ label self-conditionally (own pid) so it can never erase a successor's.
40
+ [cass]
41
+ 3. **Typed, actionable refusals**: robot error code + human text naming the
42
+ escapes ("held by pid N (sync); retry shortly or stop the scheduler") —
43
+ replace silent 15s blocking at the mutating entry points. [agentsview]
44
+ 4. **Caller-class policy split**: foreground CLI verbs wait briefly (250ms)
45
+ then fail typed; the scheduled daemon (env `LEDGER_SCHEDULER=1` set by
46
+ the ops installers) soft-skips the pass with a log line, exit 0.
47
+ [cass scheduler-verb pattern]
48
+ 5. **Worker exemption bound to parent authority**: sync worker children
49
+ inherit the parent's lease authority via an explicit invocation option
50
+ plus a child-side check that the lease label's pid is `process.ppid` —
51
+ an ambient env marker alone never exempts a foreground run. [agentsview
52
+ worker-marker pattern, hardened]
53
+ 6. **watch acquires per reconcile/batch tick** (short holds, skip-on-busy
54
+ with a note), never for process lifetime — the foreground watch must not
55
+ starve CLI verbs for hours. [agentsview daemon-cadence analysis]
56
+ 7. **No TOCTOU change needed**: `commitIngest` already re-reads staged/live
57
+ state inside its transaction; harness round 3 confirms that is the
58
+ correct shape for row-commit writers and that its grace-then-proceed
59
+ fence does NOT translate (no persistence engine; artifact writes are
60
+ non-atomic caches) — expiry in Ledger is the typed busy refusal.
61
+
62
+ ## Deferred
63
+
64
+ - Obelisk-style carve-out register (exempt routes with proof obligations) —
65
+ Ledger has no proven disjoint write route yet; the queue bookkeeping
66
+ stays under the lease.
67
+ - Owner-token predicates on `ingest_runtime_state` writes — schema change,
68
+ later cycle with run-state work.
69
+ - Reader policy changes (search/recent/emit-pi still open `TrajectoryDb`) —
70
+ read-path connection split is its own cycle.
@@ -0,0 +1,61 @@
1
+ # Confer round 5 — 2026-09-13
2
+
3
+ Read-connection-discipline round. Pins: obelisk `45eaac8b` (5th), agentsview
4
+ `532fd652` (3rd), cass `3ac128bf` (3rd), trajectory `21ae92d` (5th),
5
+ vercel/ai `6c6c2210` (3rd); letta-code +7 commits (`72b04acf`, lease stack
6
+ untouched). Baseline: main `a19916b`.
7
+
8
+ | Repo | File |
9
+ | --- | --- |
10
+ | letta-ai/trajectory | [trajectory.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-5/trajectory.md) |
11
+ | letta-ai/letta-code | [letta-code.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-5/letta-code.md) |
12
+ | tommy0103/obelisk | [obelisk.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-5/obelisk.md) |
13
+ | dicklesworthstone/cass | [cass.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-5/cass.md) |
14
+ | kenn-io/agentsview | [agentsview.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-5/agentsview.md) |
15
+ | vercel/ai harness | [vercel-ai-harness.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-5/vercel-ai-harness.md) |
16
+
17
+ ## Cycle-5 decision: read-path connection split (issue #23)
18
+
19
+ Verified on main (ReadPathScout5): `search`, `recent`, and `emit-pi` open
20
+ `TrajectoryDb`, whose constructor always performs writes (WAL pragma,
21
+ `CREATE_TABLES_SQL`, trigger-repair transaction; migrate on old schemas) —
22
+ read verbs can create or upgrade a store outside the writer lease, and
23
+ `querySemantic` backfills embeddings mid-query (a write on the read path).
24
+
25
+ Design (sources in brackets):
26
+
27
+ 1. **Reader class** (`TrajectoryReader`): `new Database(path,
28
+ {readonly: true})` — the open flag, engine-enforced and irreversible;
29
+ never `PRAGMA query_only` (reversible, still allows file creation).
30
+ [obelisk] No DDL, no migration, no trigger repair, no FTS config;
31
+ `busy_timeout` set; short-lived per verb invocation (no pool → no
32
+ stranded-inode hazard on replaced stores). [agentsview reader-pool
33
+ hazard] No WAL fallback to a writable open — the round-4 stale-`-shm`
34
+ `disk I/O error` is the same constraint; fail typed instead.
35
+ [trajectory's `openWithWalFallback` is the anti-pattern]
36
+ 2. **Typed read errors**: missing store → "not initialized; run ledger sync
37
+ or build" (beating Obelisk's untranslated raw error); too-new schema →
38
+ existing `SCHEMA_MISMATCH` vocabulary; readable-but-old schema → serve
39
+ reads, matching `store-status` semantics. [obelisk typed-refusal spec;
40
+ letta-code manifest refusal with remedy]
41
+ 3. **Semantic/hybrid without embeddings never writes**: skip the mid-query
42
+ backfill; fall back to lexical with
43
+ `requested_search_mode: "semantic"|"hybrid"`, `search_mode: "lexical"`,
44
+ 4. **Read-verb invariance pinned Cass-style**: byte-compare `<db>` and
45
+ `-wal` before/after read verbs on a checkpointed store — zero store-side
46
+ writes, no sidecar creation. (`-shm` is shared wal-index bookkeeping
47
+ that SQLite itself may refresh on the first read-only open of a dirty
48
+ WAL; excluded from the data-hash contract and documented as such.)
49
+ [cass gh422 byte-invariance test]
50
+ 5. Writers unchanged (lease + `TrajectoryDb`); the read/write boundary
51
+ documented in api-surface.
52
+
53
+ ## Deferred
54
+
55
+ - Obelisk's `ensureReadableSchema` (read-triggered, lease-arbitrated
56
+ upgrade): Ledger read verbs refuse instead of upgrading — revisit only if
57
+ an operator need appears.
58
+ - Reader pool with WAL-snapshot pinning across statements: per-invocation
59
+ readers make it unnecessary today.
60
+ - FTS5 `prefix=` index (issue #21) and the other queued candidates stay
61
+ next in the matrix.
@@ -0,0 +1,68 @@
1
+ # Confer round 6 — 2026-09-13
2
+
3
+ Read-boundary validation + discovery-taxonomy round. Pins: trajectory
4
+ `21ae92d` (6th), obelisk `45eaac8b` (5th), agentsview `532fd652` (2nd),
5
+ vercel/ai `6c6c2210`; letta-code +5 (`438f821a`, local-store anchors
6
+ exact); cass +9 (`6d445f6`, taxonomy files byte-identical). Baseline: main
7
+ `3469076`.
8
+
9
+ | Repo | File |
10
+ | --- | --- |
11
+ | letta-ai/trajectory | [trajectory.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-6/trajectory.md) |
12
+ | letta-ai/letta-code | [letta-code.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-6/letta-code.md) |
13
+ | tommy0103/obelisk | [obelisk.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-6/obelisk.md) |
14
+ | dicklesworthstone/cass | [cass.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-6/cass.md) |
15
+ | kenn-io/agentsview | [agentsview.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-6/agentsview.md) |
16
+ | vercel/ai harness | [vercel-ai-harness.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-6/vercel-ai-harness.md) |
17
+
18
+ ## Cycle-6 decision: typed read gate (issue #27)
19
+
20
+ Reproduced on main (ObeliskRound6): a foreign SQLite file with only a
21
+ `sessions` table and `user_version=0` makes `ledger status --json` die
22
+ with a raw `no such table: records` (exit 1, no code, no payload) and
23
+ `ledger last` with `no such column: updated_at`. Both gates
24
+ (`reader.ts` `openReadOnlyStore`, `store-status.ts` `readStoreStatus`)
25
+ test `sessions` presence alone; `db.ts` throws for `user_version=0 &&
26
+ sessions present` — the same foreign case the gate should name.
27
+
28
+ Design (sources in brackets):
29
+
30
+ 1. **Four-state ladder** in one shared classifier used by both gates:
31
+ absent/zero-byte → `STORE_NOT_INITIALIZED` (empty = not initialized,
32
+ never unreadable [letta-code]); not-a-database → `STORE_UNREADABLE`;
33
+ `user_version > SCHEMA_VERSION` → `SCHEMA_MISMATCH` (existing);
34
+ sessions present but required pairs missing → **new**
35
+ `STORE_SCHEMA_INCOMPLETE` naming the first gap in **sorted order**
36
+ (AgentsView's map-iteration nondeterminism is a named gap to avoid)
37
+ with the single-sourced remedy line. [agentsview error shape; harness
38
+ observed-vs-expected wording; obelisk four-outcome analysis]
39
+ 2. **Required pairs, not :memory: replay**: Ledger's DDL is a
40
+ branch-dependent migration sequence, so AgentsView's embedded-schema
41
+ trick does not port. Use Obelisk's shape — an explicit
42
+ `REQUIRED_READ_SCHEMA` (table, column) list — but derive it honestly:
43
+ a test materializes every migration-fixture store the repo can
44
+ generate (v1→v10) and asserts the gate passes on all of them plus a
45
+ fresh v10, and fails with the right gap on synthetic foreign shapes.
46
+ Readable-but-old keeps serving reads (round-5 decision preserved).
47
+ [obelisk pair-list spec; agentsview creator/expectation-drift
48
+ invariant adapted as the fixture test]
49
+ 3. **Index presence stays out of scope** (AgentsView's by-name index
50
+ check is itself a one-level-down hole — noted, not copied).
51
+ 4. **Dead-path removal**: `applyEmbeddingProvider` is dead at
52
+ `handleScan`, `handleLast`, and `handleEmitPi` (reader split made them
53
+ dead); remove all three (#27 item 2).
54
+ 5. `store-status` gains the same typed states (the diagnostic verb is
55
+ currently the one escaping untyped — ObeliskRound6 reproduction).
56
+
57
+ ## Deferred with recorded specs (cycle 7+)
58
+
59
+ - **Scanner listing taxonomy**: trajectory's closed 16-code union maps
60
+ `listing_unavailable` (exactly atif/copilot-cli/cursor/gemini-cli/
61
+ opencode + no-SQLite runtimes), `unknown_source`, and
62
+ store-unreadable-as-invalid-input (a conflation Ledger must not inherit
63
+ — caller error ≠ store error [trajectory finding 2]); Cass's
64
+ 7-state disposition × 8-kind failure taxonomy with per-connector
65
+ capability bools is the richer shape [cass]; today Ledger collapses all
66
+ of it into `read_error` at `scanner.ts:105-107` and `scanSessions`
67
+ returns items only. Spec complete in this round's files.
68
+ - FTS5 `prefix=` index (#21) unchanged in queue.
@@ -0,0 +1,64 @@
1
+ # Confer round 7 — 2026-09-13
2
+
3
+ Scan-outcome surfacing round. Pins: all six unchanged (trajectory `21ae92d`
4
+ 7th, obelisk `45eaac8b` 6th, agentsview `532fd652` 3rd, cass `6d445f6` 2nd,
5
+ letta-code `438f821a`, vercel/ai `6c6c2210`). Baseline: main `cb673ea`.
6
+
7
+ | Repo | File |
8
+ | --- | --- |
9
+ | letta-ai/trajectory | [trajectory.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-7/trajectory.md) |
10
+ | letta-ai/letta-code | [letta-code.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-7/letta-code.md) |
11
+ | tommy0103/obelisk | [obelisk.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-7/obelisk.md) |
12
+ | dicklesworthstone/cass | [cass.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-7/cass.md) |
13
+ | kenn-io/agentsview | [agentsview.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-7/agentsview.md) |
14
+ | vercel/ai harness | [vercel-ai-harness.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-7/vercel-ai-harness.md) |
15
+
16
+ ## Cycle-7 decision: per-source scan outcomes
17
+
18
+ Verified on main (ScanPathScout7): `scanner.ts:105-107` collapses every
19
+ listing failure into one `read_error` diagnostic delivered to an
20
+ `onDiagnostic` callback that NO caller passes (cli scan/build, sync,
21
+ watch) — sources fail silently and report 0 sessions; the extended
22
+ directory branch swallows fs errors with no diagnostic at all
23
+ (`scanner.ts:226`); `scanSessions` returns items only.
24
+
25
+ The upstream probe (trajectory.md, verified against the installed 0.3.0
26
+ under Bun) is decisive: **8 of 10 file listers return silent `items=0`
27
+ for missing/empty/unreadable roots**; only hermes/deepagents throw, and
28
+ their most common real failures (zero-byte store, wrong schema) escape as
29
+ raw `SQLiteError` with no code. The outcome cannot be reconstructed from
30
+ listing results — it must be computed scanner-side.
31
+
32
+ Design (sources in brackets):
33
+
34
+ 1. **Ledger's own fs probe per source** before listing: resolved root
35
+ stat → `missing_root` (ENOENT), `root_not_directory`,
36
+ `unreadable_root` (non-ENOENT stat error — never suppressed, first
37
+ scan included [obelisk errno split]), else attempt listing.
38
+ 2. **Closed status enum** per source row: `listable` (listing succeeded,
39
+ 0 items is legitimate), `missing_root`, `root_not_directory`,
40
+ `unreadable_root`, `listing_failed` (any throw from listTrajectories
41
+ or native discovery — detail = error name/class + errno, capped,
42
+ never a raw dump [cass curated-channel rule]); every row always
43
+ carries `discovered` count and `root` [cass all-keys rule; agentsview
44
+ one-row-per-source-including-healthy].
45
+ 3. **Return-shape cutover**: `scanSessions` returns
46
+ `{sessions, outcomes}`; all callers migrated (clean cutover). `scan
47
+ --robot` JSONL gains a leading `{"type":"scan_outcomes",...}` line
48
+ (search_meta precedent); `--json` gains `outcomes`; human output stays
49
+ byte-identical when every source is `listable` and prints one stderr
50
+ line per non-listable source otherwise. Outcomes sorted by source
51
+ [cass BTreeMap discipline].
52
+ 4. Native sources (cursor/opencode) funnel their existing diagnostics
53
+ into the outcome rows; extended sources (gemini-cli/copilot-cli)
54
+ replace silent skips with rows.
55
+ 5. Outcomes are recomputed per scan, never persisted [obelisk];
56
+ provenance-relative absence suppression is NOT adopted — the row is
57
+ always emitted, robots filter.
58
+
59
+ ## Deferred
60
+
61
+ - Durably recorded per-source coverage state (could ride
62
+ `ingest_queue.last_outcome` without schema change — scout note) —
63
+ later cycle with coverage work.
64
+ - FTS5 `prefix=` index (#21) unchanged in queue.
@@ -0,0 +1,59 @@
1
+ # Confer round 9 — 2026-09-13
2
+
3
+ Durable per-source state round. Pins: trajectory `21ae92d` (9th), obelisk
4
+ `45eaac8b` (8th), agentsview `532fd652` (5th), cass `6d445f6` (4th),
5
+ vercel/ai `6c6c2210`; letta-code `1ec6a43f` (2nd). Baseline: main
6
+ `8945146`. Ops this round: recovered a wedged sync that held the lease
7
+ 75× past its `--wall-ms` budget (bug filed as #35); live store migrated
8
+ to v11 (161,580 records), widening verified live.
9
+
10
+ | Repo | File |
11
+ | --- | --- |
12
+ | letta-ai/trajectory | [trajectory.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-9/trajectory.md) |
13
+ | letta-ai/letta-code | [letta-code.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-9/letta-code.md) |
14
+ | tommy0103/obelisk | [obelisk.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-9/obelisk.md) |
15
+ | dicklesworthstone/cass | [cass.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-9/cass.md) |
16
+ | kenn-io/agentsview | [agentsview.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-9/agentsview.md) |
17
+ | vercel/ai harness | [vercel-ai-harness.md](https://github.com/archeism/ledger/blob/43081aef54c23b4bd017b6c0e11fc42a9a1cb381/confer/2026-09-13-round-9/vercel-ai-harness.md) |
18
+
19
+ ## Cycle-9 decision: durable source coverage (schema v12)
20
+
21
+ Cycle 7's scan outcomes are dropped on every floor today (verified:
22
+ `sync.ts:687` and `watch.ts:548` destructure `sessions` only;
23
+ `buildStore` logs them only under `--verbose`). Recording them durably
24
+ closes the "visible coverage reporting / expose unsupported-failed-
25
+ pending sources" gap named since round 1.
26
+
27
+ Design (sources in brackets):
28
+
29
+ 1. **`source_coverage` table** (schema v12): one last-write-wins row per
30
+ source — `source PK, root, status (ScanOutcomeStatus), discovered,
31
+ detail, updated_at, first_seen_at` [letta-code outcome slot;
32
+ agentsview raw_coverage shape]. Version discipline: the SCHEMA_VERSION
33
+ bump is the epoch; no version-in-key strings [agentsview anti-pattern
34
+ named]. No TTL, no counters this cycle — the row is state, not
35
+ notification history.
36
+ 2. **Single writer choke point**: one shared `recordSourceCoverage`
37
+ helper called at the end of the scan phase from exactly the three
38
+ lease-holding passes (sync `runSync`, `buildStore`, watch reconcile),
39
+ writing inside the pass's existing transaction — marker written last,
40
+ only after outcomes are complete [harness rule; obelisk marker-in-txn].
41
+ 3. **Reader ships in the same change** [obelisk's proven failure: its
42
+ durable markers have zero production readers]: `ledger status` gains a
43
+ `coverage` block (per-source rows, sorted; robot gets the array, human
44
+ gets non-listable rows + a count), read through the existing
45
+ sqlite_master-guarded probe (`null` pre-v12, like diagnostics).
46
+ 4. **Compute counts at read time; persist only non-derivable truth**
47
+ [cass rule]: the row persists the scan verdict; anything derivable
48
+ (queue pending, cursor states) is not duplicated.
49
+ 5. Post-pass transitions always write [letta-code's stale-success
50
+ qualifier]: a source that becomes listable overwrites its failing row;
51
+ first_seen_at survives while the source is seen.
52
+
53
+ ## Deferred
54
+
55
+ - Coverage-driven retry/notification semantics (letta-code's in-row dedup
56
+ gate) — no notification consumer exists yet.
57
+ - Certified/rescanned distinction (cass source-ledger) — Ledger's
58
+ cursor/queue state already covers per-file reuse.
59
+ - #35 wall-budget enforcement — separate bug, needs its own cycle.