@plurnk/plurnk-service 0.43.0 → 0.45.0

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 (141) hide show
  1. package/.env.example +28 -28
  2. package/README.md +37 -18
  3. package/SPEC.md +64 -35
  4. package/dist/core/ChannelWrite.d.ts +4 -0
  5. package/dist/core/ChannelWrite.d.ts.map +1 -1
  6. package/dist/core/ChannelWrite.js +9 -0
  7. package/dist/core/ChannelWrite.js.map +1 -1
  8. package/dist/core/ChannelWrite.sql +69 -0
  9. package/dist/core/Engine.d.ts.map +1 -1
  10. package/dist/core/Engine.js +115 -77
  11. package/dist/core/Engine.js.map +1 -1
  12. package/dist/core/Engine.sql +291 -0
  13. package/dist/core/ExecutorRegistry.d.ts +4 -2
  14. package/dist/core/ExecutorRegistry.d.ts.map +1 -1
  15. package/dist/core/ExecutorRegistry.js +14 -4
  16. package/dist/core/ExecutorRegistry.js.map +1 -1
  17. package/dist/core/SchemeRegistry.d.ts +1 -0
  18. package/dist/core/SchemeRegistry.d.ts.map +1 -1
  19. package/dist/core/SchemeRegistry.js +22 -21
  20. package/dist/core/SchemeRegistry.js.map +1 -1
  21. package/dist/core/fork.d.ts.map +1 -1
  22. package/dist/core/fork.js +8 -1
  23. package/dist/core/fork.js.map +1 -1
  24. package/dist/core/fork.sql +50 -0
  25. package/dist/core/plugin-attribution.d.ts +5 -0
  26. package/dist/core/plugin-attribution.d.ts.map +1 -0
  27. package/dist/core/plugin-attribution.js +39 -0
  28. package/dist/core/plugin-attribution.js.map +1 -0
  29. package/dist/core/run-ops.sql +16 -0
  30. package/dist/core/session-settings.d.ts +1 -0
  31. package/dist/core/session-settings.d.ts.map +1 -1
  32. package/dist/core/session-settings.js +2 -1
  33. package/dist/core/session-settings.js.map +1 -1
  34. package/dist/schemes/Exec.d.ts +1 -1
  35. package/dist/schemes/Exec.d.ts.map +1 -1
  36. package/dist/schemes/Exec.js +19 -6
  37. package/dist/schemes/Exec.js.map +1 -1
  38. package/dist/schemes/File.d.ts +0 -1
  39. package/dist/schemes/File.d.ts.map +1 -1
  40. package/dist/schemes/File.js +29 -4
  41. package/dist/schemes/File.js.map +1 -1
  42. package/dist/schemes/Known.d.ts +0 -1
  43. package/dist/schemes/Known.d.ts.map +1 -1
  44. package/dist/schemes/Known.js +2 -1
  45. package/dist/schemes/Known.js.map +1 -1
  46. package/dist/schemes/Log.d.ts +0 -1
  47. package/dist/schemes/Log.d.ts.map +1 -1
  48. package/dist/schemes/Log.js +2 -1
  49. package/dist/schemes/Log.js.map +1 -1
  50. package/dist/schemes/Log.sql +37 -0
  51. package/dist/schemes/Plurnk.d.ts +0 -1
  52. package/dist/schemes/Plurnk.d.ts.map +1 -1
  53. package/dist/schemes/Plurnk.js +2 -1
  54. package/dist/schemes/Plurnk.js.map +1 -1
  55. package/dist/schemes/Run.d.ts +0 -1
  56. package/dist/schemes/Run.d.ts.map +1 -1
  57. package/dist/schemes/Run.js +2 -1
  58. package/dist/schemes/Run.js.map +1 -1
  59. package/dist/schemes/Unknown.d.ts +0 -1
  60. package/dist/schemes/Unknown.d.ts.map +1 -1
  61. package/dist/schemes/Unknown.js +2 -1
  62. package/dist/schemes/Unknown.js.map +1 -1
  63. package/dist/schemes/_entry-crud.sql +88 -0
  64. package/dist/schemes/_entry-find.sql +31 -0
  65. package/dist/schemes/_entry-graph.sql +60 -0
  66. package/dist/schemes/_entry-manifest.d.ts.map +1 -1
  67. package/dist/schemes/_entry-manifest.js +4 -1
  68. package/dist/schemes/_entry-manifest.js.map +1 -1
  69. package/dist/schemes/_entry-ops.sql +20 -0
  70. package/dist/schemes/_entry-semantic.sql +64 -0
  71. package/dist/schemes/exec-env.js +1 -1
  72. package/dist/schemes/exec-env.js.map +1 -1
  73. package/dist/server/Daemon.d.ts.map +1 -1
  74. package/dist/server/Daemon.js +103 -37
  75. package/dist/server/Daemon.js.map +1 -1
  76. package/dist/server/clientTurn.sql +10 -0
  77. package/dist/server/drain.sql +82 -0
  78. package/dist/server/dsl.d.ts.map +1 -1
  79. package/dist/server/dsl.js +11 -4
  80. package/dist/server/dsl.js.map +1 -1
  81. package/dist/server/envelope.sql +75 -0
  82. package/dist/server/logEntry.sql +10 -0
  83. package/dist/server/methods/_dispatchAsClient.d.ts.map +1 -1
  84. package/dist/server/methods/_dispatchAsClient.js +11 -6
  85. package/dist/server/methods/_dispatchAsClient.js.map +1 -1
  86. package/dist/server/methods/entry_read.sql +21 -0
  87. package/dist/server/methods/log_read.sql +11 -0
  88. package/dist/server/methods/loop_run.d.ts.map +1 -1
  89. package/dist/server/methods/loop_run.js +4 -0
  90. package/dist/server/methods/loop_run.js.map +1 -1
  91. package/dist/server/methods/loop_run.sql +9 -0
  92. package/dist/server/methods/session_create.d.ts.map +1 -1
  93. package/dist/server/methods/session_create.js +10 -3
  94. package/dist/server/methods/session_create.js.map +1 -1
  95. package/dist/service.d.ts +6 -0
  96. package/dist/service.d.ts.map +1 -0
  97. package/dist/service.js +221 -0
  98. package/dist/service.js.map +1 -0
  99. package/package.json +29 -15
  100. package/requirements.md +2 -1
  101. package/bin/plurnk-service.ts +0 -176
  102. package/dist/core/ProviderRegistry.d.ts +0 -42
  103. package/dist/core/ProviderRegistry.d.ts.map +0 -1
  104. package/dist/core/ProviderRegistry.js +0 -72
  105. package/dist/core/ProviderRegistry.js.map +0 -1
  106. package/dist/core/line-marker.d.ts +0 -23
  107. package/dist/core/line-marker.d.ts.map +0 -1
  108. package/dist/core/line-marker.js +0 -321
  109. package/dist/core/line-marker.js.map +0 -1
  110. package/dist/core/matcher.d.ts +0 -12
  111. package/dist/core/matcher.d.ts.map +0 -1
  112. package/dist/core/matcher.js +0 -72
  113. package/dist/core/matcher.js.map +0 -1
  114. package/dist/core/mimetype-binary.d.ts +0 -6
  115. package/dist/core/mimetype-binary.d.ts.map +0 -1
  116. package/dist/core/mimetype-binary.js +0 -82
  117. package/dist/core/mimetype-binary.js.map +0 -1
  118. package/dist/core/path-mimetype.d.ts +0 -3
  119. package/dist/core/path-mimetype.d.ts.map +0 -1
  120. package/dist/core/path-mimetype.js +0 -47
  121. package/dist/core/path-mimetype.js.map +0 -1
  122. package/dist/core/plugin-trust.d.ts +0 -4
  123. package/dist/core/plugin-trust.d.ts.map +0 -1
  124. package/dist/core/plugin-trust.js +0 -23
  125. package/dist/core/plugin-trust.js.map +0 -1
  126. package/dist/providers/Mock.d.ts +0 -43
  127. package/dist/providers/Mock.d.ts.map +0 -1
  128. package/dist/providers/Mock.js +0 -36
  129. package/dist/providers/Mock.js.map +0 -1
  130. package/dist/server/methods/op_hide.d.ts +0 -5
  131. package/dist/server/methods/op_hide.d.ts.map +0 -1
  132. package/dist/server/methods/op_hide.js +0 -24
  133. package/dist/server/methods/op_hide.js.map +0 -1
  134. package/dist/server/methods/op_show.d.ts +0 -5
  135. package/dist/server/methods/op_show.d.ts.map +0 -1
  136. package/dist/server/methods/op_show.js +0 -24
  137. package/dist/server/methods/op_show.js.map +0 -1
  138. package/dist/server/methods/session_set_persona.d.ts +0 -5
  139. package/dist/server/methods/session_set_persona.d.ts.map +0 -1
  140. package/dist/server/methods/session_set_persona.js +0 -29
  141. package/dist/server/methods/session_set_persona.js.map +0 -1
@@ -5,7 +5,6 @@ import type { EntryData, ReadEntryResult, WriteEntryResult, DeleteEntryResult }
5
5
  import type { SendResult } from "./_entry-send.ts";
6
6
  import type { FindResult } from "./_entry-find.ts";
7
7
  export default class Unknown {
8
- static teach: string;
9
8
  static manifest: SchemeManifest;
10
9
  edit(statement: EditStatement, ctx: PlurnkSchemeContext): Promise<EditResult>;
11
10
  read(statement: ReadStatement, ctx: PlurnkSchemeContext): Promise<ReadResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"Unknown.d.ts","sourceRoot":"","sources":["../../src/schemes/Unknown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnF,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAKzG,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACxG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,CAAC,OAAO,OAAO,OAAO;IACxB,MAAM,CAAC,KAAK,SAA+R;IAE3S,MAAM,CAAC,QAAQ,EAAE,cAAc,CAS7B;IAEI,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;IAI7E,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;IAI7E,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,eAAe,CAAC;IAI/E,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAInG,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAInF,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;IAI7E,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;CAGtF"}
1
+ {"version":3,"file":"Unknown.d.ts","sourceRoot":"","sources":["../../src/schemes/Unknown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnF,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAKzG,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACxG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,CAAC,OAAO,OAAO,OAAO;IACxB,MAAM,CAAC,QAAQ,EAAE,cAAc,CAW7B;IAEI,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;IAI7E,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;IAI7E,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,eAAe,CAAC;IAI/E,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAInG,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAInF,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;IAI7E,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;CAGtF"}
@@ -3,7 +3,6 @@ import EntryCrud from "./_entry-crud.js";
3
3
  import EntrySend from "./_entry-send.js";
4
4
  import EntryFind from "./_entry-find.js";
5
5
  export default class Unknown {
6
- static teach = "The catch-all an address falls into when its scheme isn't one you recognize. It behaves like `known:///` — the unrecognized URI still becomes an addressable entry you can EDIT, READ, FIND, and SEND — so a typo or an unmodeled scheme degrades to a usable entry rather than an error.";
7
6
  static manifest = {
8
7
  name: "unknown",
9
8
  channels: { body: "text/markdown" },
@@ -13,6 +12,8 @@ export default class Unknown {
13
12
  writableBy: ["model", "client"],
14
13
  volatile: false,
15
14
  modelVisible: true,
15
+ example: "<<READ(unknown:///entry.md)::READ",
16
+ documentation: "The catch-all an address falls into when its scheme isn't one you recognize. It behaves like `known:///` — the unrecognized URI still becomes an addressable entry you can EDIT, READ, FIND, and SEND — so a typo or an unmodeled scheme degrades to a usable entry rather than an error.",
16
17
  };
17
18
  async edit(statement, ctx) {
18
19
  return EntryOps.editSessionEntry(statement, ctx, Unknown.manifest);
@@ -1 +1 @@
1
- {"version":3,"file":"Unknown.js","sourceRoot":"","sources":["../../src/schemes/Unknown.ts"],"names":[],"mappings":"AAEA,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AACvC,OAAO,SAAS,MAAM,kBAAkB,CAAC;AACzC,OAAO,SAAS,MAAM,kBAAkB,CAAC;AACzC,OAAO,SAAS,MAAM,kBAAkB,CAAC;AAMzC,MAAM,CAAC,OAAO,OAAO,OAAO;IACxB,MAAM,CAAC,KAAK,GAAG,2RAA2R,CAAC;IAE3S,MAAM,CAAC,QAAQ,GAAmB;QAC9B,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE;QACnC,cAAc,EAAE,MAAM;QACtB,QAAQ,EAAE,MAAM;QAChB,KAAK,EAAE,SAAS;QAChB,UAAU,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;QAC/B,QAAQ,EAAE,KAAK;QACf,YAAY,EAAE,IAAI;KACrB,CAAC;IAEF,KAAK,CAAC,IAAI,CAAC,SAAwB,EAAE,GAAwB;QACzD,OAAO,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAwB,EAAE,GAAwB;QACzD,OAAO,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,QAAgB,EAAE,GAAwB;QACtD,OAAO,SAAS,CAAC,SAAS,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,QAAgB,EAAE,KAAgB,EAAE,GAAwB;QACzE,OAAO,SAAS,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC7E,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,QAAgB,EAAE,GAAwB;QACxD,OAAO,SAAS,CAAC,WAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAwB,EAAE,GAAwB;QACzD,OAAO,SAAS,CAAC,kBAAkB,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/E,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAwB,EAAE,GAAwB;QACzD,OAAO,SAAS,CAAC,kBAAkB,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1E,CAAC"}
1
+ {"version":3,"file":"Unknown.js","sourceRoot":"","sources":["../../src/schemes/Unknown.ts"],"names":[],"mappings":"AAEA,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AACvC,OAAO,SAAS,MAAM,kBAAkB,CAAC;AACzC,OAAO,SAAS,MAAM,kBAAkB,CAAC;AACzC,OAAO,SAAS,MAAM,kBAAkB,CAAC;AAMzC,MAAM,CAAC,OAAO,OAAO,OAAO;IACxB,MAAM,CAAC,QAAQ,GAAmB;QAC9B,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE;QACnC,cAAc,EAAE,MAAM;QACtB,QAAQ,EAAE,MAAM;QAChB,KAAK,EAAE,SAAS;QAChB,UAAU,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;QAC/B,QAAQ,EAAE,KAAK;QACf,YAAY,EAAE,IAAI;QAClB,OAAO,EAAE,mCAAmC;QAC5C,aAAa,EAAE,2RAA2R;KAC7S,CAAC;IAEF,KAAK,CAAC,IAAI,CAAC,SAAwB,EAAE,GAAwB;QACzD,OAAO,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAwB,EAAE,GAAwB;QACzD,OAAO,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,QAAgB,EAAE,GAAwB;QACtD,OAAO,SAAS,CAAC,SAAS,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,QAAgB,EAAE,KAAgB,EAAE,GAAwB;QACzE,OAAO,SAAS,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC7E,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,QAAgB,EAAE,GAAwB;QACxD,OAAO,SAAS,CAAC,WAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAwB,EAAE,GAAwB;QACzD,OAAO,SAAS,CAAC,kBAAkB,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/E,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,SAAwB,EAAE,GAAwB;QACzD,OAAO,SAAS,CAAC,kBAAkB,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1E,CAAC"}
@@ -0,0 +1,88 @@
1
+ -- Entry CRUD primitives (SPEC §crud). Used by entry-bearing schemes
2
+ -- (known/unknown/skill) and the engine for cross-scheme COPY/MOVE/SEND[410].
3
+
4
+ -- PREP: crud_find_session_entry
5
+ -- Null-aware scheme comparison: the file scheme is the routing internal
6
+ -- for bare/absolute paths; storage normalizes its rows to scheme=NULL
7
+ -- (Engine.#extractTarget). SQL's `=` doesn't match NULL, so use `IS`.
8
+ SELECT id FROM entries
9
+ WHERE scope = 'session' AND session_id = $session_id AND scheme IS $scheme AND pathname = $pathname;
10
+
11
+ -- PREP: crud_read_channels
12
+ SELECT name, content, mimetype FROM entry_channels WHERE entry_id = $entry_id;
13
+
14
+ -- PREP: crud_read_tags
15
+ SELECT tag FROM entry_tags WHERE entry_id = $entry_id ORDER BY tag;
16
+
17
+ -- PREP: crud_insert_session_entry
18
+ INSERT INTO entries (scope, session_id, scheme, pathname)
19
+ VALUES ('session', $session_id, $scheme, $pathname)
20
+ RETURNING id;
21
+
22
+ -- PREP: crud_register_session_member
23
+ -- Idempotent bare-membership insert (SPEC §membership D4 — git ls-files membership).
24
+ -- A git-tracked file is a session member by virtue of being tracked; the row
25
+ -- is the membership marker the File read-gate checks and FIND globs by path.
26
+ -- Channel-less by design — disk stays the truth (D3). ON CONFLICT no-ops so
27
+ -- re-resolving membership each turn never duplicates or churns rows.
28
+ INSERT INTO entries (scope, session_id, scheme, pathname, membership_origin)
29
+ VALUES ('session', $session_id, $scheme, $pathname, $membership_origin)
30
+ ON CONFLICT (session_id, scheme, pathname) WHERE scope = 'session'
31
+ DO NOTHING
32
+ RETURNING id;
33
+
34
+ -- PREP: crud_get_member_sig
35
+ -- SPEC §membership-change-gated-sync — the member's last-synced disk signature
36
+ -- (mtime:size), read before materializing so an unchanged file short-circuits
37
+ -- before any content read. Null-aware scheme (file members store scheme=NULL).
38
+ SELECT id, synced_sig FROM entries
39
+ WHERE scope = 'session' AND session_id = $session_id AND scheme IS $scheme AND pathname = $pathname;
40
+
41
+ -- PREP: crud_set_synced_sig
42
+ -- Stamp the disk signature after a member materializes to disk truth; the next
43
+ -- pass compares against it to skip an unchanged member.
44
+ UPDATE entries SET synced_sig = $synced_sig WHERE id = $entry_id;
45
+
46
+ -- PREP: crud_delete_channels
47
+ DELETE FROM entry_channels WHERE entry_id = $entry_id;
48
+
49
+ -- PREP: crud_delete_channel
50
+ DELETE FROM entry_channels WHERE entry_id = $entry_id AND name = $name
51
+ RETURNING name;
52
+
53
+ -- PREP: crud_delete_tags
54
+ DELETE FROM entry_tags WHERE entry_id = $entry_id;
55
+
56
+ -- PREP: crud_write_channel
57
+ INSERT INTO entry_channels (entry_id, name, content, mimetype, tokens, state)
58
+ VALUES ($entry_id, $name, $content, $mimetype, $tokens, $state);
59
+
60
+ -- PREP: crud_write_tag
61
+ INSERT OR IGNORE INTO entry_tags (entry_id, tag) VALUES ($entry_id, $tag);
62
+
63
+ -- PREP: crud_delete_tag
64
+ DELETE FROM entry_tags WHERE entry_id = $entry_id AND tag = $tag;
65
+
66
+ -- PREP: crud_delete_entry
67
+ DELETE FROM entries WHERE id = $entry_id;
68
+
69
+ -- PREP: crud_list_reconcilable_members
70
+ -- Overlay-owned file members of a session (membership_origin IN git, constraint).
71
+ -- The reconciliation set: resolveGitMembership compares this against the desired
72
+ -- ((git ls-files ∪ add) − ignore) and un-registers the difference, so entries ==
73
+ -- members. Model-created ('client') members are excluded — not git's to reclaim.
74
+ SELECT id, pathname FROM entries
75
+ WHERE scope = 'session' AND session_id = $session_id AND scheme IS NULL AND membership_origin IN ('git', 'constraint');
76
+
77
+ -- PREP: crud_insert_session_constraint
78
+ -- SPEC §membership constraint overlay — the client supersede. Idempotent per
79
+ -- (session, effect, glob); effect ∈ {add, ignore, read-only}.
80
+ INSERT OR IGNORE INTO session_constraints (session_id, effect, glob)
81
+ VALUES ($session_id, $effect, $glob);
82
+
83
+ -- PREP: crud_list_session_constraints
84
+ SELECT effect, glob FROM session_constraints WHERE session_id = $session_id;
85
+
86
+ -- PREP: crud_delete_session_constraint
87
+ -- "remove" a constraint — deleting the row, not a fourth effect.
88
+ DELETE FROM session_constraints WHERE session_id = $session_id AND effect = $effect AND glob = $glob;
@@ -0,0 +1,31 @@
1
+ -- FIND / multi-entry OPEN / FOLD candidate selection for entry-bearing
2
+ -- schemes (SPEC §find; plurnk.md FIND row).
3
+ --
4
+ -- Scope (target) + tag filters ONLY. The body matcher does NOT belong here:
5
+ -- per plurnk.md §"Body matcher dispatch" it runs against entry CONTENT, which
6
+ -- needs the mimetypes daughter (xpath/jsonpath/regex/glob over structured
7
+ -- content) — so the body match runs in JS (Matcher.matchAgainstContent) over
8
+ -- the default-channel content this query returns. Static query handles every
9
+ -- filter combination via IS-NULL guards (per SqlRite LLMS.md §channels).
10
+
11
+ -- PREP: find_session_entry_candidates
12
+ -- $channel: default-channel name whose content the body matcher runs against
13
+ -- $scope_pathname: pathname-prefix glob (e.g., "foo/*") or NULL for no prefix
14
+ -- $tags: JSON string of tag list (e.g., '["a","b"]'); '[]' or NULL for no tag filter
15
+ SELECT e.id AS entry_id, e.pathname, ec.content, ec.mimetype
16
+ FROM entries e
17
+ JOIN entry_channels ec ON ec.entry_id = e.id AND ec.name = $channel
18
+ WHERE e.scope = 'session'
19
+ AND e.session_id = $session_id
20
+ AND e.scheme IS $scheme
21
+ AND ($scope_pathname IS NULL OR e.pathname GLOB $scope_pathname)
22
+ AND (
23
+ json_array_length(COALESCE($tags, '[]')) = 0
24
+ OR e.id IN (
25
+ SELECT entry_id FROM entry_tags
26
+ WHERE tag IN (SELECT value FROM json_each(COALESCE($tags, '[]')))
27
+ GROUP BY entry_id
28
+ HAVING COUNT(DISTINCT tag) = json_array_length(COALESCE($tags, '[]'))
29
+ )
30
+ )
31
+ ORDER BY e.pathname;
@@ -0,0 +1,60 @@
1
+ -- @graph (plurnk-service#186) — symbol_defs/refs population + @< / @> / @
2
+ -- resolution. Populated delete-then-insert per entry at EntryCrud.writeEntry;
3
+ -- queried by the FIND `graph` dialect via EntryGraph. Traversal is kind-agnostic
4
+ -- (every ref is an edge; `kind` is edge metadata, never filtered here). 1-hop —
5
+ -- the grammar's `@<sym` surface is single-hop; WITH RECURSIVE the day it grows one.
6
+
7
+ -- PREP: graph_delete_defs
8
+ DELETE FROM symbol_defs WHERE entry_id = $entry_id;
9
+
10
+ -- PREP: graph_delete_refs
11
+ DELETE FROM symbol_refs WHERE entry_id = $entry_id;
12
+
13
+ -- PREP: graph_insert_def
14
+ INSERT INTO symbol_defs (session_id, entry_id, name, kind, container, line, end_line)
15
+ VALUES ($session_id, $entry_id, $name, $kind, $container, $line, $end_line);
16
+
17
+ -- PREP: graph_enclosing_symbol
18
+ -- Project Findings — the smallest symbol_def covering a line: the structural unit a match
19
+ -- at line N belongs to (function/class/heading). Ties → tightest span; a point symbol
20
+ -- (NULL end_line) covers only its own line.
21
+ SELECT name, kind, line, end_line
22
+ FROM symbol_defs
23
+ WHERE entry_id = $entry_id AND line <= $line AND COALESCE(end_line, line) >= $line
24
+ ORDER BY (COALESCE(end_line, line) - line) ASC
25
+ LIMIT 1;
26
+
27
+ -- PREP: graph_insert_ref
28
+ INSERT INTO symbol_refs (session_id, entry_id, name, kind, container, line, col)
29
+ VALUES ($session_id, $entry_id, $name, $kind, $container, $line, $col);
30
+
31
+ -- PREP: graph_referrers
32
+ -- @<sym — entries (scheme-scoped) that reference sym.
33
+ SELECT DISTINCT e.pathname
34
+ FROM symbol_refs r JOIN entries e ON e.id = r.entry_id
35
+ WHERE r.session_id = $session_id AND e.scheme IS $scheme AND r.name = $name
36
+ ORDER BY e.pathname;
37
+
38
+ -- PREP: graph_def_pathnames_by_name
39
+ -- Resolve a name → the defining entries' pathnames (scheme-scoped). Serves @>'s
40
+ -- target resolution and @'s neighborhood def lookup.
41
+ SELECT DISTINCT e.pathname
42
+ FROM symbol_defs d JOIN entries e ON e.id = d.entry_id
43
+ WHERE d.session_id = $session_id AND e.scheme IS $scheme AND d.name = $name
44
+ ORDER BY e.pathname;
45
+
46
+ -- PREP: graph_resolve_def
47
+ -- sym → its def(s): (entry_id, container) to compose the qualified path for @>.
48
+ SELECT entry_id, container FROM symbol_defs
49
+ WHERE session_id = $session_id AND name = $name;
50
+
51
+ -- PREP: graph_refs_from_source
52
+ -- @>sym step — the target names sym's def references (its own ref rows, keyed
53
+ -- by the source def's full qualified path = the @> join semantics from #186).
54
+ SELECT DISTINCT name FROM symbol_refs
55
+ WHERE session_id = $session_id AND entry_id = $entry_id AND container IS $container;
56
+
57
+ -- PREP: graph_set_deep_hash
58
+ -- Stamp the body-content hash at the moment an entry's deep channels were
59
+ -- (re)derived. The next manifest-add pass skips the entry while the hash holds.
60
+ UPDATE entries SET deep_hash = $deep_hash WHERE id = $entry_id;
@@ -1 +1 @@
1
- {"version":3,"file":"_entry-manifest.d.ts","sourceRoot":"","sources":["../../src/schemes/_entry-manifest.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAYnE,MAAM,CAAC,OAAO,OAAO,aAAa;;WAOjB,iBAAiB,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC;CA4F5E"}
1
+ {"version":3,"file":"_entry-manifest.d.ts","sourceRoot":"","sources":["../../src/schemes/_entry-manifest.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAYnE,MAAM,CAAC,OAAO,OAAO,aAAa;;WAUjB,iBAAiB,CAAC,GAAG,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC;CA4F5E"}
@@ -20,7 +20,10 @@ import EntrySemantic from "./_entry-semantic.js";
20
20
  export default class EntryManifest {
21
21
  static #MANIFEST_PATH = "plurnk:///manifest.json";
22
22
  static #toPath(scheme, pathname) {
23
- return scheme === null ? pathname : renderAddress(scheme, pathname);
23
+ // Bare (file, scheme===null) entries store the namespace-absolute key (`/notes.md`)
24
+ // but the model types the relative path it reads — render the leading slash off so
25
+ // the catalog matches what the model writes back (READ/EDIT resolve either form).
26
+ return scheme === null ? pathname.replace(/^\//, "") : renderAddress(scheme, pathname);
24
27
  }
25
28
  static async buildManifestBody(ctx) {
26
29
  const { db, sessionId, mimetypes, tokenize } = ctx;
@@ -1 +1 @@
1
- {"version":3,"file":"_entry-manifest.js","sourceRoot":"","sources":["../../src/schemes/_entry-manifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"_entry-manifest.js","sourceRoot":"","sources":["../../src/schemes/_entry-manifest.ts"],"names":[],"mappings":"AAAA,uGAAuG;AACvG,iFAAiF;AACjF,0EAA0E;AAC1E,kDAAkD;AAClD,gFAAgF;AAChF,oFAAoF;AACpF,+EAA+E;AAC/E,gFAAgF;AAChF,6EAA6E;AAC7E,mEAAmE;AACnE,EAAE;AACF,kFAAkF;AAClF,+EAA+E;AAC/E,wDAAwD;AAGxD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGtD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,UAAU,MAAM,mBAAmB,CAAC;AAC3C,OAAO,aAAa,MAAM,sBAAsB,CAAC;AAKjD,MAAM,CAAC,OAAO,OAAO,aAAa;IAC9B,MAAM,CAAC,cAAc,GAAG,yBAAyB,CAAC;IAElD,MAAM,CAAC,OAAO,CAAC,MAAqB,EAAE,QAAgB;QAClD,oFAAoF;QACpF,mFAAmF;QACnF,kFAAkF;QAClF,OAAO,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC3F,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,GAAwB;QACnD,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC;QACnD,IAAI,SAAS,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAC;QAC1H,IAAI,QAAQ,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,8IAA8I,CAAC,CAAC;QAC5L,MAAM,IAAI,GAAG,MAAO,EAAE,CAAC,2BAA0C,CAAC,GAAG,CAAc,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;QAC9G,oFAAoF;QACpF,wEAAwE;QACxE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAoB,CAAC;QAC7C,KAAK,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,MAAO,EAAE,CAAC,8BAA6C,CAAC,GAAG,CAAoC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;YACxJ,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACpC,IAAI,IAAI,KAAK,SAAS;gBAAE,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;;gBAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC/E,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAwB,CAAC;QAChD,2EAA2E;QAC3E,oFAAoF;QACpF,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC;QACtE,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACnB,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;YACzD,IAAI,IAAI,KAAK,aAAa,CAAC,cAAc;gBAAE,SAAS;YACpD,IAAI,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACtB,KAAK,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;gBAC/B,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;gBACtC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;oBAAE,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC;gBAC7D,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC7B,CAAC;YACD,sEAAsE;YACtE,wEAAwE;YACxE,IAAI,CAAC,CAAC,OAAO,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS;gBAAE,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC;YACjF,oEAAoE;YACpE,gFAAgF;YAChF,yEAAyE;YACzE,2EAA2E;YAC3E,0EAA0E;YAC1E,qEAAqE;YACrE,wEAAwE;YACxE,wEAAwE;YACxE,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,KAAK,MAAM,CAAC;YACpC,8EAA8E;YAC9E,gFAAgF;YAChF,4EAA4E;YAC5E,gFAAgF;YAChF,2EAA2E;YAC3E,oEAAoE;YACpE,IAAI,MAAqB,CAAC;YAC1B,IAAI,CAAC;gBACD,IAAI,MAAM,EAAE,CAAC;oBACT,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBAClG,IAAI,IAAI,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC;wBACvB,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;oBACjG,CAAC;yBAAM,CAAC;wBACJ,MAAM,SAAS,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;wBACvF,IAAI,SAAS,EAAE,CAAC;4BACZ,IAAI,CAAC;gCACD,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,SAAS,EAAE,YAAY,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,wCAAwC;gCAC1K,MAAM,UAAU,CAAC,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;4BAC5G,CAAC;4BAAC,MAAM,CAAC;gCACL,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;gCAC7F,MAAM,UAAU,CAAC,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;4BACrE,CAAC;wBACL,CAAC;6BAAM,CAAC;4BACJ,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;4BAC7F,MAAM,UAAU,CAAC,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;wBACrE,CAAC;wBACD,gEAAgE;wBAChE,uEAAuE;wBACvE,kEAAkE;wBAClE,MAAM,aAAa,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;wBACxD,mEAAmE;wBACnE,kEAAkE;wBAClE,wEAAwE;wBACxE,2DAA2D;wBAC3D,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,aAAa,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;wBACpJ,MAAM,aAAa,CAAC,cAAc,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;wBAClE,MAAO,EAAE,CAAC,mBAAkC,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;oBAChG,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;gBACjG,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACL,MAAM,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,EAAmB,CAAC;gBACpG,IAAI,MAAM,EAAE,CAAC;oBACT,MAAM,UAAU,CAAC,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;oBACjE,MAAM,aAAa,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;oBACjD,MAAM,aAAa,CAAC,cAAc,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,EAAE,SAAS,CAAC,CAAC;oBAClE,MAAO,EAAE,CAAC,mBAAkC,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBAChL,CAAC;YACL,CAAC;YACD,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC;QAChH,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC1D,CAAC"}
@@ -0,0 +1,20 @@
1
+ -- Session-entry op handlers for entry-bearing schemes (SPEC §scheme, §channel-selection).
2
+ -- Some queries reuse PREPs declared in _entry-crud.sql:
3
+ -- crud_find_session_entry, crud_write_tag
4
+
5
+ -- PREP: ops_upsert_channel
6
+ -- EDIT semantics: replace channel content if it exists.
7
+ INSERT OR REPLACE INTO entry_channels (entry_id, name, content, mimetype, tokens, state)
8
+ VALUES ($entry_id, $name, $content, $mimetype, $tokens, 'static');
9
+
10
+ -- PREP: ops_read_channel
11
+ -- READ targeting a specific channel of a session entry.
12
+ SELECT ec.content, ec.mimetype
13
+ FROM entries e
14
+ JOIN entry_channels ec ON ec.entry_id = e.id
15
+ WHERE e.scope = 'session'
16
+ AND e.session_id = $session_id
17
+ AND e.scheme IS $scheme
18
+ AND e.pathname = $pathname
19
+ AND ec.name = $channel;
20
+
@@ -0,0 +1,64 @@
1
+ -- ~semantic (plurnk-service#186) — the FTS half of the dialect (FTS narrow →
2
+ -- cosine rank). Populated at the gated manifest-add hook; the FTS5 rowid IS the
3
+ -- entry id, so a re-index is delete-by-rowid then insert.
4
+
5
+ -- PREP: fts_delete
6
+ DELETE FROM entry_fts WHERE rowid = $entry_id;
7
+
8
+ -- PREP: fts_insert
9
+ INSERT INTO entry_fts (rowid, content) VALUES ($entry_id, $content);
10
+
11
+ -- PREP: embedding_set
12
+ -- Insert ONE chunk's vector + its <L> extent + the model. The caller clears the
13
+ -- entry's rows (embedding_delete) first and inserts each chunk in seq order, so no
14
+ -- upsert is needed — a re-derivation is delete-all then insert-each.
15
+ INSERT INTO entry_embeddings (entry_id, chunk_seq, line_start, line_end, vector, embedding_model)
16
+ VALUES ($entry_id, $chunk_seq, $line_start, $line_end, $vector, $embedding_model);
17
+
18
+ -- PREP: embedding_delete
19
+ -- Clears ALL of an entry's chunk rows (the re-derivation reset).
20
+ DELETE FROM entry_embeddings WHERE entry_id = $entry_id;
21
+
22
+ -- PREP: semantic_rank
23
+ -- The ~semantic fusion: FTS narrows by keyword ($fts_query), then cosine ranks the
24
+ -- narrowed candidates over the query embedding ($query_vector), top-K. Scheme-scoped
25
+ -- like every dialect. FTS does the scale-cut; cosine the precise rank — so a high-
26
+ -- cosine entry that doesn't match the keyword is correctly excluded by the narrow.
27
+ -- Many chunk rows per entry → rank by the entry's BEST chunk (per-entry top cosine via
28
+ -- ROW_NUMBER), and surface that winning chunk's line span as the finding extent
29
+ -- (Project Findings). embedding_model filter keeps cosine within one model's dimensions.
30
+ WITH ranked AS (
31
+ SELECT e.pathname, em.line_start, em.line_end,
32
+ cosine(em.vector, $query_vector) AS score,
33
+ ROW_NUMBER() OVER (PARTITION BY e.id ORDER BY cosine(em.vector, $query_vector) DESC) AS rn
34
+ FROM entry_fts f
35
+ JOIN entries e ON e.id = f.rowid
36
+ JOIN entry_embeddings em ON em.entry_id = e.id AND em.embedding_model = $embedding_model
37
+ WHERE f.content MATCH $fts_query
38
+ AND e.session_id = $session_id
39
+ AND e.scheme IS $scheme
40
+ )
41
+ SELECT pathname, line_start, line_end FROM ranked
42
+ WHERE rn = 1
43
+ ORDER BY score DESC
44
+ LIMIT $k;
45
+
46
+ -- PREP: semantic_rank_threshold
47
+ -- #209 — the <0.x> similarity-threshold form: same FTS+cosine fusion, but a cosine
48
+ -- floor ($threshold, in (0,1)) replaces top-K, and $cap (-1 = unbounded) is the
49
+ -- optional <0.x,N> result cap.
50
+ WITH ranked AS (
51
+ SELECT e.pathname, em.line_start, em.line_end,
52
+ cosine(em.vector, $query_vector) AS score,
53
+ ROW_NUMBER() OVER (PARTITION BY e.id ORDER BY cosine(em.vector, $query_vector) DESC) AS rn
54
+ FROM entry_fts f
55
+ JOIN entries e ON e.id = f.rowid
56
+ JOIN entry_embeddings em ON em.entry_id = e.id AND em.embedding_model = $embedding_model
57
+ WHERE f.content MATCH $fts_query
58
+ AND e.session_id = $session_id
59
+ AND e.scheme IS $scheme
60
+ )
61
+ SELECT pathname, line_start, line_end FROM ranked
62
+ WHERE rn = 1 AND score >= $threshold
63
+ ORDER BY score DESC
64
+ LIMIT $cap;
@@ -14,7 +14,7 @@
14
14
  import { STANDARD_PROVIDERS } from "@plurnk/plurnk-providers";
15
15
  export default class ExecEnv {
16
16
  // apiKeyVar is optional (providers 0.9.0): an anonymous provider like `plurnk`
17
- // has none. It loses no secret here — plurnk's PLURNK_KEY/PLURNK_ACCOUNT creds are
17
+ // has none. It loses no secret here — plurnk's PLURNK_API_KEY cred is
18
18
  // already stripped by the PLURNK_ prefix rule below — so drop the empties.
19
19
  static #providerKeys = new Set(Object.values(STANDARD_PROVIDERS)
20
20
  .map((spec) => spec.apiKeyVar)
@@ -1 +1 @@
1
- {"version":3,"file":"exec-env.js","sourceRoot":"","sources":["../../src/schemes/exec-env.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,qFAAqF;AACrF,oFAAoF;AACpF,8EAA8E;AAC9E,wFAAwF;AACxF,qFAAqF;AACrF,kEAAkE;AAClE,EAAE;AACF,mFAAmF;AACnF,mFAAmF;AACnF,yFAAyF;AACzF,oDAAoD;AAEpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,MAAM,CAAC,OAAO,OAAO,OAAO;IACxB,+EAA+E;IAC/E,mFAAmF;IACnF,2EAA2E;IAC3E,MAAM,CAAC,aAAa,GAAwB,IAAI,GAAG,CAC/C,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC;SAC5B,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC;SAC7B,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CACnD,CAAC;IAEF,kFAAkF;IAClF,sCAAsC;IACtC,MAAM,CAAC,MAAM,CAAC,MAAyB,OAAO,CAAC,GAAG;QAC9C,MAAM,GAAG,GAAsB,EAAE,CAAC;QAClC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7C,IAAI,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS,CAAE,uCAAuC;YACnH,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACrB,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC"}
1
+ {"version":3,"file":"exec-env.js","sourceRoot":"","sources":["../../src/schemes/exec-env.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,qFAAqF;AACrF,oFAAoF;AACpF,8EAA8E;AAC9E,wFAAwF;AACxF,qFAAqF;AACrF,kEAAkE;AAClE,EAAE;AACF,mFAAmF;AACnF,mFAAmF;AACnF,yFAAyF;AACzF,oDAAoD;AAEpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,MAAM,CAAC,OAAO,OAAO,OAAO;IACxB,+EAA+E;IAC/E,sEAAsE;IACtE,2EAA2E;IAC3E,MAAM,CAAC,aAAa,GAAwB,IAAI,GAAG,CAC/C,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC;SAC5B,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC;SAC7B,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CACnD,CAAC;IAEF,kFAAkF;IAClF,sCAAsC;IACtC,MAAM,CAAC,MAAM,CAAC,MAAyB,OAAO,CAAC,GAAG;QAC9C,MAAM,GAAG,GAAsB,EAAE,CAAC;QAClC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7C,IAAI,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS,CAAE,uCAAuC;YACnH,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACrB,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Daemon.d.ts","sourceRoot":"","sources":["../../src/server/Daemon.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,EAAE,EAAc,MAAM,eAAe,CAAC;AAGpD,OAAO,MAAM,MAAM,mBAAmB,CAAC;AAEvC,OAAO,cAAc,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,OAAO,cAAc,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAgB,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAsCnF,MAAM,WAAW,aAAa;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,CAAC,OAAO,OAAO,MAAM;;gBA2BX,EACR,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,GACpD,EAAE;QACC,EAAE,EAAE,EAAE,CAAC;QACP,OAAO,CAAC,EAAE,cAAc,CAAC;QACzB,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;QAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;KAC5B;IAuED,IAAI,QAAQ,IAAI,cAAc,CAA2B;IACzD,IAAI,MAAM,IAAI,MAAM,CAAyB;IAC7C,IAAI,QAAQ,IAAI,QAAQ,GAAG,IAAI,CAA2B;IAC1D,IAAI,OAAO,IAAI,cAAc,CAA0B;IACvD,IAAI,SAAS,IAAI,SAAS,CAA4B;IAEhD,KAAK,CAAC,EAAE,IAAkB,EAAE,IAAW,EAAE,GAAE,aAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;IAsCtF,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA2I3B;;;;OAIG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAI7H;;;;;;OAMG;IACH,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAIzF;;;;;;;;;;;OAWG;IACG,MAAM,CAAC,IAAI,EAAE;QACf,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QACjD,QAAQ,EAAE,QAAQ,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC;KACjD,GAAG,OAAO,CAAC;QACR,MAAM,EAAE,oBAAoB,GAAG,mBAAmB,CAAC;QACnD,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,gBAAgB,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;QAC5C,YAAY,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;KACnC,CAAC;IA0OF;;;;;;OAMG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,GAAE,MAAyB,GAAG,OAAO;CA4IzE"}
1
+ {"version":3,"file":"Daemon.d.ts","sourceRoot":"","sources":["../../src/server/Daemon.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,EAAE,EAAc,MAAM,eAAe,CAAC;AAGpD,OAAO,MAAM,MAAM,mBAAmB,CAAC;AAEvC,OAAO,cAAc,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,OAAO,cAAc,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAgB,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAsCnF,MAAM,WAAW,aAAa;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,CAAC,OAAO,OAAO,MAAM;;gBA8BX,EACR,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,GACpD,EAAE;QACC,EAAE,EAAE,EAAE,CAAC;QACP,OAAO,CAAC,EAAE,cAAc,CAAC;QACzB,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;QAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;KAC5B;IAwED,IAAI,QAAQ,IAAI,cAAc,CAA2B;IACzD,IAAI,MAAM,IAAI,MAAM,CAAyB;IAC7C,IAAI,QAAQ,IAAI,QAAQ,GAAG,IAAI,CAA2B;IAC1D,IAAI,OAAO,IAAI,cAAc,CAA0B;IACvD,IAAI,SAAS,IAAI,SAAS,CAA4B;IAEhD,KAAK,CAAC,EAAE,IAAkB,EAAE,IAAW,EAAE,GAAE,aAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;IAsCtF,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA2I3B;;;;OAIG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAI7H;;;;;;OAMG;IACH,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAIzF;;;;;;;;;;;OAWG;IACG,MAAM,CAAC,IAAI,EAAE;QACf,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QACjD,QAAQ,EAAE,QAAQ,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE;YAAE,IAAI,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC;KACjD,GAAG,OAAO,CAAC;QACR,MAAM,EAAE,oBAAoB,GAAG,mBAAmB,CAAC;QACnD,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,gBAAgB,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;QAC5C,YAAY,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;KACnC,CAAC;IAiQF;;;;;;OAMG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,GAAE,MAAyB,GAAG,OAAO;CAqLzE"}
@@ -3,7 +3,8 @@
3
3
  // SPEC §rpc.
4
4
  import { WebSocketServer } from "ws";
5
5
  import { readFile } from "node:fs/promises";
6
- import { resolve } from "node:path";
6
+ import { resolve, dirname } from "node:path";
7
+ import ChannelWrite from "../core/ChannelWrite.js";
7
8
  import { Paths } from "../index.js";
8
9
  import Engine from "../core/Engine.js";
9
10
  import ExecutorRegistry from "../core/ExecutorRegistry.js";
@@ -54,6 +55,7 @@ export default class Daemon {
54
55
  #provider;
55
56
  #registry;
56
57
  #nodeModulesPath;
58
+ #discoveryCwd;
57
59
  #wss = null;
58
60
  #connections = new Set();
59
61
  // Run-level drain registry. At most one drain per run. The stored object
@@ -71,19 +73,23 @@ export default class Daemon {
71
73
  // any single (ephemeral) drain; replaced with a fresh controller once
72
74
  // aborted so a later loop.run isn't born cancelled.
73
75
  #runAborts = new Map();
76
+ // Per-run drain-transition lock — see #withDrainLock (R4 / §run-lifecycle-single-drain).
77
+ #drainLocks = new Map();
74
78
  constructor({ db, schemes, mimetypes, provider, nodeModulesPath, }) {
75
79
  this.#db = db;
76
80
  this.#schemes = schemes ?? new SchemeRegistry();
77
81
  this.#provider = provider ?? null;
78
- // Mimetypes owns discovery, detection, handler instantiation, and
79
- // budget-truncated preview rendering. plurnk-service stays mimetype-
80
- // illiterate we just inject the tokenize function (sourced from the
81
- // active provider's countTokens) and configure text/markdown as the
82
- // default mimetype (LLM output is overwhelmingly markdown; the
83
- // text-markdown handler is a hard dep so the default actually
84
- // resolves at runtime).
82
+ // Plugin discovery resolves from the SERVICE's node_modules (its exec/scheme/mimetype
83
+ // deps), NOT process.cwd() — else a globally-installed daemon started from a project dir
84
+ // finds no plugins. The bin passes the package-relative path; cwd default holds for
85
+ // in-repo tests. discover() takes a cwd and joins node_modules, so derive the parent.
86
+ this.#nodeModulesPath = nodeModulesPath ?? resolve(process.cwd(), "node_modules");
87
+ this.#discoveryCwd = dirname(this.#nodeModulesPath);
88
+ // Mimetypes owns discovery + detection; we inject the tokenize fn (from the provider's
89
+ // countTokens) and default to text/markdown.
85
90
  this.#mimetypes = mimetypes ?? new Mimetypes({
86
91
  defaultMimetype: "text/markdown",
92
+ discoverOptions: { cwd: this.#discoveryCwd },
87
93
  });
88
94
  this.#engine = new Engine({
89
95
  db, schemes: this.#schemes, mimetypes: this.#mimetypes,
@@ -112,7 +118,6 @@ export default class Daemon {
112
118
  cancelRun: (runId) => this.cancelDrain(runId, "killed via run:// KILL"),
113
119
  telemetryEventNotify: (sessionId, payload) => this.notifyTelemetryEvent(sessionId, payload),
114
120
  });
115
- this.#nodeModulesPath = nodeModulesPath ?? resolve(process.cwd(), "node_modules");
116
121
  this.#registry = new MethodRegistry();
117
122
  this.#registerBuiltins();
118
123
  this.#registerNotifications();
@@ -157,12 +162,12 @@ export default class Daemon {
157
162
  // Discover + probe the installed executor siblings, then hand the
158
163
  // registry to the engine for exec dispatch (plurnk-service#181). The
159
164
  // shell is the default runtime, so its executor must boot usable.
160
- const executors = await ExecutorRegistry.build({ defaultRuntime: "sh" });
165
+ const executors = await ExecutorRegistry.build({ defaultRuntime: "sh", cwd: this.#discoveryCwd });
161
166
  this.#engine.setExecutors(executors);
162
167
  // Discover external @plurnk/plurnk-schemes-* siblings + register them
163
168
  // (agnostic, by plurnk.kind:"scheme"). They light up http://, etc. with
164
169
  // no further engine change — #run wraps their ctx in SchemeCtxImpl (#195).
165
- await this.#schemes.discoverExternal();
170
+ await this.#schemes.discoverExternal(this.#discoveryCwd);
166
171
  return new Promise((resolve, reject) => {
167
172
  const wss = new WebSocketServer({ host, port });
168
173
  wss.on("listening", () => {
@@ -377,14 +382,14 @@ export default class Daemon {
377
382
  loop_id: loopId, flags: JSON.stringify(merged),
378
383
  });
379
384
  }
380
- // Guarantee a drain claims the loop we just enqueued. Synchronous
381
- // check-and-start (no await between the membership test and the
382
- // registry write): a live drain re-claims it; otherwise we start one.
383
- // The drain's exit coordinates via an identity-checked re-claim so the
384
- // loop is never stranded (the lost-loop hang). firstLoopPromise is
385
- // present only when THIS call started the drain — loop.run keys its
386
- // fast-path response on that.
387
- const started = this.#ensureDrain({
385
+ // Guarantee a drain claims the loop we just enqueued. #ensureDrain runs its
386
+ // check-and-start UNDER the per-run drain lock (§run-lifecycle-single-drain),
387
+ // serialized against a draining sibling's teardown relinquish so the two can't
388
+ // both register a drain (R4). A live drain re-claims the loop in its own
389
+ // iteration or its lock-held exit re-claim, so it's never stranded.
390
+ // firstLoopPromise is present only when THIS call started the drain — loop.run
391
+ // keys its fast-path response on that.
392
+ const started = await this.#ensureDrain({
388
393
  sessionId, runId, provider: args.provider,
389
394
  systemPrompt: args.systemPrompt,
390
395
  maxTurns: args.maxTurns ?? Number(process.env.PLURNK_MAX_TURNS ?? "50"),
@@ -429,17 +434,21 @@ export default class Daemon {
429
434
  controller.signal.throwIfAborted();
430
435
  let loopRow = await claim();
431
436
  if (loopRow === undefined) {
432
- // Queue empty → exit. Coordinate with a concurrent
433
- // inject + #ensureDrain: relinquish ownership, then
434
- // re-claim once. A loop that raced in during teardown
435
- // is caught here (re-acquire + run it); otherwise exit.
436
- // Identity-checked so we never delete a successor entry.
437
- if (this.#activeDrains.get(runId) === handle)
438
- this.#activeDrains.delete(runId);
439
- loopRow = await claim();
437
+ // Queue empty → teardown UNDER the per-run drain lock (R4 / I1),
438
+ // serialized against #ensureDrain so a concurrent inject can't
439
+ // start a 2nd drain in the gap. Re-claim while holding the lock;
440
+ // relinquish the registry slot only if it's empty too. A loop
441
+ // that raced in is returned and run — we stay registered, so
442
+ // there's no transient delete for #ensureDrain to catch.
443
+ loopRow = await this.#withDrainLock(runId, async () => {
444
+ const claimed = await claim();
445
+ if (claimed === undefined && this.#activeDrains.get(runId) === handle) {
446
+ this.#activeDrains.delete(runId);
447
+ }
448
+ return claimed;
449
+ });
440
450
  if (loopRow === undefined)
441
451
  break;
442
- this.#activeDrains.set(runId, handle);
443
452
  }
444
453
  currentLoopId = loopRow.id;
445
454
  const onDispatch = (logEntryId) => {
@@ -526,16 +535,34 @@ export default class Daemon {
526
535
  firstLoopPromise.catch(() => { });
527
536
  return { firstLoopPromise, drainPromise };
528
537
  }
529
- // Idempotent, synchronous drain guarantee. A live drain will claim the
530
- // just-enqueued loop in its own iteration (or its exit re-claim) return
531
- // null. Otherwise start one. MUST be called synchronously after the
532
- // enqueue (no await between) so the membership test and #startDrain's
533
- // registry write are one tick two concurrent injects can't both start a
534
- // drain for the same run.
538
+ // Per-run drain-transition lock (R4 / §run-lifecycle-single-drain). #ensureDrain's
539
+ // start and a drain's teardown relinquish both run under it, serialized, so the two
540
+ // can't interleave and register two drains for one run. The critical section is the
541
+ // registry decision only (never a loop's work) a sub-ms hop at drain boundaries.
542
+ // A promise-chain mutex: each caller awaits the prior holder; the tail self-prunes
543
+ // when idle so the Map stays bounded to runs mid-transition.
544
+ #withDrainLock(runId, fn) {
545
+ const prev = this.#drainLocks.get(runId) ?? Promise.resolve();
546
+ const run = prev.then(fn, fn);
547
+ const tail = run.catch(() => { });
548
+ this.#drainLocks.set(runId, tail);
549
+ void tail.then(() => { if (this.#drainLocks.get(runId) === tail)
550
+ this.#drainLocks.delete(runId); });
551
+ return run;
552
+ }
553
+ // The drain guarantee, serialized per run via #withDrainLock so it can't race a
554
+ // sibling drain's teardown relinquish into a double-drain (R4). A live drain
555
+ // (registered, NOT aborting) will claim the just-enqueued loop in its own iteration
556
+ // or its lock-held exit re-claim → return null. A registered-but-ABORTING drain is
557
+ // in teardown and won't claim, so we don't defer to it — start fresh, or the loop
558
+ // strands on a cancel/resume race (I6 no-lost-loop). Otherwise start one.
535
559
  #ensureDrain(opts) {
536
- if (this.#activeDrains.has(opts.runId))
537
- return null;
538
- return this.#startDrain(opts);
560
+ return this.#withDrainLock(opts.runId, async () => {
561
+ const existing = this.#activeDrains.get(opts.runId);
562
+ if (existing !== undefined && !existing.controller.signal.aborted)
563
+ return null;
564
+ return this.#startDrain(opts);
565
+ });
539
566
  }
540
567
  // After a loop terminates, promote any next-turn prompt it never consumed —
541
568
  // an injected wake (stream conclusion) or a loop.run-while-active prompt
@@ -579,9 +606,21 @@ export default class Daemon {
579
606
  */
580
607
  cancelDrain(runId, reason = "user_cancelled") {
581
608
  const hadWork = this.#activeDrains.has(runId) || this.#runHasActiveStreams(runId);
609
+ // Stop the active drain's turn-generation (its loop closes 499). The run
610
+ // signal is the optimization path — the fast, listener-driven reap.
582
611
  const scope = this.#runAborts.get(runId);
583
612
  if (scope !== undefined && !scope.signal.aborted)
584
613
  scope.abort(reason);
614
+ // Total reap by the REGISTRY (§run-lifecycle-total-reap): the durable source
615
+ // of truth. Every open subscription the run holds, aborted via its owning
616
+ // scheme — independent of the signal-listener timing, so an exec mid-spawn
617
+ // (registry row written before it is killable) is reaped too. A late spawn
618
+ // (registering after this) self-aborts against its captured, now-aborted
619
+ // epoch (§run-lifecycle-exec-loop-bound). Idempotent; fire-and-forget (the
620
+ // abort is sync, the registry read async; the 499 conclusion surfaces async).
621
+ void this.#reapRunStreams(runId, reason).catch((err) => {
622
+ console.error(`reapRunStreams(${runId}) failed:`, err);
623
+ });
585
624
  return hadWork;
586
625
  }
587
626
  // Does the run have an in-flight stream (a background exec)? Used only for
@@ -591,6 +630,19 @@ export default class Daemon {
591
630
  const exec = this.#schemes.get("exec");
592
631
  return exec?.hasActiveSpawns?.(runId) ?? false;
593
632
  }
633
+ // The registry-routed reap (§run-lifecycle-total-reap): every open subscription
634
+ // the run holds, aborted via its owning scheme. The durable answer to "reap
635
+ // everything" — the in-process AbortSignal listener is the optimization, this is
636
+ // the source of truth: an exec mid-spawn (registry row written before it is
637
+ // killable) or a background exec from any past loop is caught regardless of
638
+ // listener timing. Idempotent — a stream the signal already reaped is a no-op.
639
+ async #reapRunStreams(runId, reason) {
640
+ const open = await ChannelWrite.findOpenSubscriptionsForRun(this.#db, runId);
641
+ for (const { id, scheme } of open) {
642
+ const handler = this.#schemes.get(scheme);
643
+ handler?.abortSubscription?.(id, reason);
644
+ }
645
+ }
594
646
  /**
595
647
  * Wake-on-completion handler. Streaming schemes call this when a
596
648
  * subscription closes. If the run has an active loop, the channel
@@ -612,6 +664,20 @@ export default class Daemon {
612
664
  });
613
665
  return;
614
666
  }
667
+ // No resurrection (§run-lifecycle-no-resurrection): a non-499 completion whose
668
+ // run was CANCELLED (idle + its scope aborted) must not start a fresh drain —
669
+ // the cancel was deliberate. The deliverable is already in the channel/log and
670
+ // surfaces as a `collect` environment delta (§env-delta) if the run is read or
671
+ // resumed; we just don't inject a turn. (An active run folds the wake into its
672
+ // next turn via inject below; a resumed run is active, never aborted, so it is
673
+ // unaffected.)
674
+ const scope = this.#runAborts.get(payload.runId);
675
+ if (scope?.signal.aborted === true && !this.#activeDrains.has(payload.runId)) {
676
+ this.#broadcast({ sessionId: payload.sessionId }, null, "stream/concluded", {
677
+ ...payload, wakeAction: "skipped-cancelled",
678
+ });
679
+ return;
680
+ }
615
681
  if (this.#provider === null) {
616
682
  this.#broadcast({ sessionId: payload.sessionId }, null, "stream/concluded", {
617
683
  ...payload, wakeAction: "skipped-no-provider",