@plurnk/plurnk-service 0.64.0 → 0.68.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 (109) hide show
  1. package/.env.example +110 -54
  2. package/INSTALL.md +69 -0
  3. package/README.md +1 -1
  4. package/SPEC.md +51 -46
  5. package/dist/Paths.js +5 -5
  6. package/dist/Paths.js.map +1 -1
  7. package/dist/core/ChannelWrite.d.ts.map +1 -1
  8. package/dist/core/ChannelWrite.js +17 -0
  9. package/dist/core/ChannelWrite.js.map +1 -1
  10. package/dist/core/ChannelWrite.sql +5 -0
  11. package/dist/core/Dispatcher.d.ts +1 -1
  12. package/dist/core/Dispatcher.d.ts.map +1 -1
  13. package/dist/core/Dispatcher.js +12 -5
  14. package/dist/core/Dispatcher.js.map +1 -1
  15. package/dist/core/Engine.d.ts +1 -0
  16. package/dist/core/Engine.d.ts.map +1 -1
  17. package/dist/core/Engine.js +65 -59
  18. package/dist/core/Engine.js.map +1 -1
  19. package/dist/core/Engine.sql +1 -0
  20. package/dist/core/ExecutorRegistry.js +2 -2
  21. package/dist/core/ExecutorRegistry.js.map +1 -1
  22. package/dist/core/PacketBuilder.js +11 -11
  23. package/dist/core/PacketBuilder.js.map +1 -1
  24. package/dist/core/ProposalLifecycle.js +1 -1
  25. package/dist/core/ProposalLifecycle.js.map +1 -1
  26. package/dist/core/ProviderInstantiate.d.ts +2 -0
  27. package/dist/core/ProviderInstantiate.d.ts.map +1 -1
  28. package/dist/core/ProviderInstantiate.js +36 -1
  29. package/dist/core/ProviderInstantiate.js.map +1 -1
  30. package/dist/core/SchemeRegistry.js +2 -2
  31. package/dist/core/SchemeRegistry.js.map +1 -1
  32. package/dist/core/StrikeRail.d.ts.map +1 -1
  33. package/dist/core/StrikeRail.js +5 -1
  34. package/dist/core/StrikeRail.js.map +1 -1
  35. package/dist/core/fork.js +1 -1
  36. package/dist/core/fork.js.map +1 -1
  37. package/dist/core/fork.sql +2 -2
  38. package/dist/core/git-membership.d.ts.map +1 -1
  39. package/dist/core/git-membership.js +18 -6
  40. package/dist/core/git-membership.js.map +1 -1
  41. package/dist/core/git-state.js +2 -2
  42. package/dist/core/git-state.js.map +1 -1
  43. package/dist/core/packet-inject.js +8 -8
  44. package/dist/core/packet-inject.js.map +1 -1
  45. package/dist/core/packet-wire.js +2 -2
  46. package/dist/core/packet-wire.js.map +1 -1
  47. package/dist/core/run-cap.js +3 -3
  48. package/dist/core/run-cap.js.map +1 -1
  49. package/dist/core/run-ops.sql +1 -1
  50. package/dist/core/session-settings.js +3 -3
  51. package/dist/core/session-settings.js.map +1 -1
  52. package/dist/core/teaching.d.ts.map +1 -1
  53. package/dist/core/teaching.js +2 -2
  54. package/dist/core/teaching.js.map +1 -1
  55. package/dist/digest/Digest.js +2 -2
  56. package/dist/digest/Digest.js.map +1 -1
  57. package/dist/schemes/Plurnk.d.ts.map +1 -1
  58. package/dist/schemes/Plurnk.js +8 -19
  59. package/dist/schemes/Plurnk.js.map +1 -1
  60. package/dist/schemes/_entry-crud.d.ts.map +1 -1
  61. package/dist/schemes/_entry-crud.js +10 -4
  62. package/dist/schemes/_entry-crud.js.map +1 -1
  63. package/dist/schemes/_entry-find.d.ts.map +1 -1
  64. package/dist/schemes/_entry-find.js +3 -0
  65. package/dist/schemes/_entry-find.js.map +1 -1
  66. package/dist/schemes/_entry-manifest.d.ts +7 -0
  67. package/dist/schemes/_entry-manifest.d.ts.map +1 -1
  68. package/dist/schemes/_entry-manifest.js +87 -33
  69. package/dist/schemes/_entry-manifest.js.map +1 -1
  70. package/dist/schemes/_entry-ops.d.ts.map +1 -1
  71. package/dist/schemes/_entry-ops.js +4 -0
  72. package/dist/schemes/_entry-ops.js.map +1 -1
  73. package/dist/schemes/_entry-semantic.d.ts +2 -1
  74. package/dist/schemes/_entry-semantic.d.ts.map +1 -1
  75. package/dist/schemes/_entry-semantic.js +32 -13
  76. package/dist/schemes/_entry-semantic.js.map +1 -1
  77. package/dist/schemes/_entry-semantic.sql +15 -0
  78. package/dist/schemes/exec-abort.js +1 -1
  79. package/dist/schemes/exec-abort.js.map +1 -1
  80. package/dist/server/ClientConnection.js +2 -2
  81. package/dist/server/ClientConnection.js.map +1 -1
  82. package/dist/server/Daemon.d.ts.map +1 -1
  83. package/dist/server/Daemon.js +7 -6
  84. package/dist/server/Daemon.js.map +1 -1
  85. package/dist/server/methods/loop_inject.js +3 -3
  86. package/dist/server/methods/loop_inject.js.map +1 -1
  87. package/dist/server/methods/loop_run.js +5 -5
  88. package/dist/server/methods/loop_run.js.map +1 -1
  89. package/dist/server/methods/mcp_install.js +4 -4
  90. package/dist/server/methods/mcp_install.js.map +1 -1
  91. package/dist/server/methods/op_copy.js +1 -1
  92. package/dist/server/methods/op_copy.js.map +1 -1
  93. package/dist/server/methods/op_dispatch.js +1 -1
  94. package/dist/server/methods/op_dispatch.js.map +1 -1
  95. package/dist/server/methods/op_edit.js +1 -1
  96. package/dist/server/methods/op_edit.js.map +1 -1
  97. package/dist/server/methods/op_exec.js +1 -1
  98. package/dist/server/methods/op_exec.js.map +1 -1
  99. package/dist/server/methods/op_move.js +1 -1
  100. package/dist/server/methods/op_move.js.map +1 -1
  101. package/dist/server/methods/session_create.js +1 -1
  102. package/dist/server/methods/session_create.js.map +1 -1
  103. package/dist/server/version-info.js +1 -1
  104. package/dist/server/version-info.js.map +1 -1
  105. package/dist/service.d.ts.map +1 -1
  106. package/dist/service.js +25 -11
  107. package/dist/service.js.map +1 -1
  108. package/migrations/0000-00-00.01_schema.sql +1 -0
  109. package/package.json +19 -16
package/.env.example CHANGED
@@ -1,32 +1,32 @@
1
- # plurnk-service configthe shipped legend: every knob + its default.
1
+ # REFERENCE ONLY ~/.plurnk/.env.example is OVERWRITTEN from the installed package on every
2
+ # restart/update. Do NOT edit it; your edits are lost. Put YOUR config in ~/.plurnk/.env (yours,
3
+ # seeded once, never touched) or ./.env. This file is the shipped legend: every knob + its default,
4
+ # and the source of the derived --<knob> CLI flags (INSTALL.md is the agent-facing breakdown).
2
5
  #
3
- # On first run this file is copied to ~/.plurnk/.env.example, which is the cascade FLOOR.
4
- # Edit there (or layer ~/.plurnk/.env over it). This node_modules copy is the SEED + the
5
- # source of derived --<knob> CLI flags it is NOT itself a runtime layer.
6
- #
7
- # Override order (low → high precedence):
8
- # ~/.plurnk/.env.example (the floor — override, don't remove!)
9
- # < ~/.plurnk/.env (your home config)
6
+ # Cascade (low high precedence last writer wins):
7
+ # package .env.example (the TRUE floor evolves with the installed version)
8
+ # < ~/.plurnk/.env.example (this readable legendrefreshed from the package each boot)
9
+ # < ~/.plurnk/.env (your home config — seeded once, yours to keep)
10
10
  # < ./.env (per-project, current directory)
11
11
  # < --env-file=… / --config=…
12
12
  # < shell environment
13
- # < --<knob> CLI flags
13
+ # < --<knob> CLI flags (the 1:1 mirror: --service-max-turns <-> PLURNK_SERVICE_MAX_TURNS)
14
14
  # Feature-flag bools use `=== "1"` exactly, never `=== "true"`. `~/` expands to your home.
15
15
 
16
16
  # --- Storage ---
17
- PLURNK_DB_PATH=~/.plurnk/plurnk.db
17
+ PLURNK_SERVICE_DB_PATH=~/.plurnk/plurnk.db
18
18
 
19
19
  # --- Sqlite tuning (curated knobs passed through to sqlrite; optional) ---
20
20
  # sqlrite already sets the safe posture (WAL + synchronous=NORMAL + busy_timeout=5000ms).
21
21
  # These are operator overrides — integers; unset = sqlrite/sqlite default. Uncomment to tune.
22
22
  # busy_timeout (ms): how long a writer waits on a lock before SQLITE_BUSY. 0 = immediate.
23
- # PLURNK_SQLITE_TIMEOUT=5000
23
+ # PLURNK_SERVICE_SQLITE_TIMEOUT=5000
24
24
  # cache_size: positive = pages, negative = KiB of memory. Bigger = fewer disk reads on a hot db.
25
- # PLURNK_SQLITE_CACHE_SIZE=-16000
25
+ # PLURNK_SERVICE_SQLITE_CACHE_SIZE=-16000
26
26
  # mmap_size: bytes of memory-mapped I/O (read perf on large file-backed dbs). 0 disables.
27
- # PLURNK_SQLITE_MMAP_SIZE=268435456
27
+ # PLURNK_SERVICE_SQLITE_MMAP_SIZE=268435456
28
28
  # max_page_count: hard db-size ceiling in PAGES — a write past it errors (disk-fill guard).
29
- # PLURNK_SQLITE_MAX_PAGE_COUNT=524288
29
+ # PLURNK_SERVICE_SQLITE_MAX_PAGE_COUNT=524288
30
30
 
31
31
  # --- Daemon transport ---
32
32
  PLURNK_HOST=127.0.0.1
@@ -35,6 +35,7 @@ PLURNK_PORT=3044
35
35
  # --- Client (read by the `plurnk` CLI from this shared home; the daemon ignores it) ---
36
36
  # The daemon WebSocket URL the client connects to (mirrors PLURNK_HOST/PORT above).
37
37
  # PLURNK_WS=ws://127.0.0.1:3044
38
+ # Client-side knobs live under PLURNK_CLIENT_* (--session/--run/--yolo/--json…); see `plurnk --help`.
38
39
 
39
40
  # --- Model aliases ---
40
41
  # PLURNK_MODEL is the active provider for every loop (a client may override per loop
@@ -99,28 +100,31 @@ MODELSCOPE_BASE_URL=https://api-inference.modelscope.cn/v1
99
100
  # Operator turn ceiling. -1 (default) = no cap (loops end via SEND, budget,
100
101
  # strikes, or cycle detection). A positive value is an inviolable hard cap a
101
102
  # per-call loop.run({maxTurns}) cannot exceed (min wins).
102
- PLURNK_MAX_TURNS=-1
103
+ PLURNK_SERVICE_MAX_TURNS=-1
103
104
  # Per-emission op cap (runaway-loop guard). A client may tighten it per session via
104
105
  # session.create settings.maxCommands (min wins); never raise it past this (#232).
105
- PLURNK_MAX_COMMANDS=99
106
- PLURNK_RPC_TIMEOUT=30000
106
+ PLURNK_SERVICE_MAX_COMMANDS=99
107
+ PLURNK_SERVICE_RPC_TIMEOUT=30000
108
+ # Proposal auto-cancel: a proposed (202) side-effecting op auto-cancels if no resolution arrives
109
+ # within this many ms (loop/resolve RPC, in-tree YOLO listener, or this timeout). Default 300000 (5 min).
110
+ PLURNK_SERVICE_PROPOSAL_TIMEOUT_MS=300000
107
111
  # Post-EXEC breath: after a turn fires a non-inline EXEC whose spawn is still in
108
112
  # flight at the turn boundary, wait this many ms before assembling the next packet
109
113
  # so a fast exec's output can land in it instead of a turn later. A fixed grace
110
114
  # beat, NOT a wait-for-completion (slow execs proceed + surface via the wake path).
111
115
  # 0 = off (the model sees fast-exec output a turn late, as today).
112
- PLURNK_EXEC_WAIT_MS=1000
116
+ PLURNK_SERVICE_EXEC_WAIT_MS=1000
113
117
  # Teardown reap grace: when a loop/run tears down a background exec, the spawn gets a polite
114
118
  # signal first (SIGHUP, or the model's KILL[code]); a stream that IGNORES it is hard-killed
115
119
  # (SIGKILL, to the whole process group) this many ms later — so the reap can't wedge on a
116
120
  # signal-ignoring child. plurnk-execs refuses to bake this number; the consumer owns it.
117
- PLURNK_EXEC_KILL_GRACE_MS=2000
118
- PLURNK_LOOP_TIMEOUT=86400000
121
+ PLURNK_SERVICE_EXEC_KILL_GRACE_MS=2000
122
+ PLURNK_SERVICE_LOOP_TIMEOUT=86400000
119
123
 
120
124
  # --- Engine rails ---
121
- PLURNK_MAX_STRIKES=3
122
- PLURNK_MIN_CYCLES=3
123
- PLURNK_MAX_CYCLE_PERIOD=4
125
+ PLURNK_SERVICE_MAX_STRIKES=3
126
+ PLURNK_SERVICE_MIN_CYCLES=3
127
+ PLURNK_SERVICE_MAX_CYCLE_PERIOD=4
124
128
 
125
129
  # --- Schemes ---
126
130
  # (Workspace root for file ops is per-session — supplied by the client
@@ -128,18 +132,18 @@ PLURNK_MAX_CYCLE_PERIOD=4
128
132
  # stored on sessions.project_root. No env-level default.)
129
133
 
130
134
  # --- Git integration ---
131
- # PLURNK_GIT_ALLOWED — hard ceiling for git membership + integration (repo telemetry,
135
+ # PLURNK_SERVICE_GIT_ALLOWED — hard ceiling for git membership + integration (repo telemetry,
132
136
  # EXEC[git]). =1 permits it (then declared repos + per-session config decide; a client
133
137
  # may deny its own session via session.create settings.git:false, #232); =0 flatly
134
138
  # denies it service-wide, un-re-enableable (the sandbox/benchmark lockout).
135
- PLURNK_GIT_ALLOWED=1
136
- # PLURNK_GIT_AUTO — default repo declaration. =1 auto-declares an implicit `repo` at
139
+ PLURNK_SERVICE_GIT_ALLOWED=1
140
+ # PLURNK_SERVICE_GIT_AUTO — default repo declaration. =1 auto-declares an implicit `repo` at
137
141
  # project_root (no-op when it isn't a git tree); =0 declares nothing — clients add
138
142
  # repos explicitly via the `repo` overlay. SPEC §membership forest.
139
- PLURNK_GIT_AUTO=1
143
+ PLURNK_SERVICE_GIT_AUTO=1
140
144
 
141
145
  # --- Reference docs (auto-READ at turn 1) ---
142
- # PLURNK_MD_<ALIAS>=<path> materializes <path>'s markdown as a plurnk://<ALIAS>.md
146
+ # PLURNK_SERVICE_MD_<ALIAS>=<path> materializes <path>'s markdown as a plurnk://<ALIAS>.md
143
147
  # entry the model READs at turn 0 — an idiomatic way to inject standing context
144
148
  # (an ordinary entry + READ op, not a bespoke packet section). ~ expands to home;
145
149
  # relative paths resolve against the package root. A client may add its own docs
@@ -147,7 +151,7 @@ PLURNK_GIT_AUTO=1
147
151
  # with these env docs, keyed by alias — the client wins a collision (#231).
148
152
  # Commented out = no docs by default. (The operating policy is NOT a doc: readSystemPolicy
149
153
  # already renders ~/.plurnk/AGENTS.md as the ## Plurnk Service Policy section — pointing a
150
- # PLURNK_MD_* alias at it injects the same file twice.)
154
+ # PLURNK_SERVICE_MD_* alias at it injects the same file twice.)
151
155
  # Turn-0 catalog preview, FIND-served (foisted as FIND(<scheme>:///**) per scheme) so a run
152
156
  # opens oriented, not blank. The model's OWN surface — known/unknown (memory), run (scratch),
153
157
  # plurnk (docs) — always foists FULL when the preview is on, never truncated: a partial view of
@@ -156,19 +160,19 @@ PLURNK_GIT_AUTO=1
156
160
  # (everything full); N = the first N files (memory still full); 0 = preview off entirely (the model
157
161
  # FINDs on demand). Servicewide default; a client overrides per session via session.create
158
162
  # settings.filesItems (#231).
159
- PLURNK_FILES_ITEMS=-1
163
+ PLURNK_SERVICE_FILES_ITEMS=-1
160
164
 
161
165
  # Prompt-preview cap: the loop's prompt renders in user.prompt every turn, and a fat prompt
162
166
  # replays each turn (bloat). Show the first N CHARS of the body + a pointer to the full
163
167
  # prompt (always READable at its plurnk://prompt/<loop>/<seq> entry — nothing is lost).
164
168
  # -1 = no cap (render the full prompt every turn).
165
- PLURNK_PROMPT_PREVIEW_CHARS=1024
169
+ PLURNK_SERVICE_PROMPT_PREVIEW_CHARS=1024
166
170
 
167
171
  # Session-tier ceiling on CONCURRENT active runs (a run with a non-terminal loop)
168
172
  # — the fork-bomb / destabilization brake. -1 = no cap (default); only concurrency
169
173
  # is bounded, never lifetime, since sessions persist for months. A spawn/fork past
170
174
  # the ceiling fails hard (508 — no queue, no retry); the acting run counts itself.
171
- PLURNK_SESSION_RUNS_MAX_ACTIVE=-1
175
+ PLURNK_SERVICE_SESSION_RUNS_MAX_ACTIVE=-1
172
176
 
173
177
  # --- Providers (universal knobs) ---
174
178
  # Native thinking (providers 0.31+, the activation/capacity split — a numeric budget
@@ -191,11 +195,11 @@ PLURNK_PROVIDERS_THINKING_CAPACITY=4096
191
195
  # partitions to EXACTLY 65536 prompt tokens (78848 − 4096 − 8192 − 1024).
192
196
  # COUPLING (F7): per-request numeric reasoning budgets are IGNORED by llama-server —
193
197
  # if thinking is enabled, the serving box's --reasoning-budget launch flag MUST equal
194
- # PLURNK_PROVIDERS_REASONING, or the reserve is fiction. The service warns at boot.
195
- PLURNK_PROVIDERS_CTX=78848
196
- PLURNK_PROVIDERS_REASONING=4096
197
- PLURNK_PROVIDERS_ASSISTANT=8192
198
- PLURNK_PROVIDERS_SAFETY=1024
198
+ # PLURNK_SERVICE_REASONING, or the reserve is fiction. The service warns at boot.
199
+ PLURNK_SERVICE_CTX=78848
200
+ PLURNK_SERVICE_REASONING=4096
201
+ PLURNK_SERVICE_ASSISTANT=8192
202
+ PLURNK_SERVICE_SAFETY=1024
199
203
 
200
204
  # countTokens is a chars/2 UPPER BOUND (safe, never undercounts; calibration trues
201
205
  # up the residual, §tokenomics-ceiling-calibrates-to-usage). Exact counting arrives
@@ -207,10 +211,10 @@ PLURNK_PROVIDERS_SAFETY=1024
207
211
  # own vendor-specific overrides for narrower defaults, but they honor
208
212
  # this as the operator's universal ceiling.
209
213
  PLURNK_PROVIDERS_FETCH_TIMEOUT=600000
210
- # PLURNK_VERSION_POLL_TTL — how long (ms) discover caches its npm-registry version poll
214
+ # PLURNK_SERVICE_VERSION_POLL_TTL — how long (ms) discover caches its npm-registry version poll
211
215
  # (service + client `latest`) before a background refresh. Best-effort; the poll never
212
216
  # blocks discover, and offline/registry-down omits `latest`. ~hourly is plenty. #235
213
- PLURNK_VERSION_POLL_TTL=3600000
217
+ PLURNK_SERVICE_VERSION_POLL_TTL=3600000
214
218
  # Grammar-constrained sampling: SELECTS the GBNF variant the provider constrains
215
219
  # every generate() to, so capable backends (llama-server, detected via the
216
220
  # /v1/models fingerprint) can only sample valid plurnk DSL; others drop it silently.
@@ -218,15 +222,31 @@ PLURNK_VERSION_POLL_TTL=3600000
218
222
  # @plurnk/plurnk-grammar; an absolute/relative path is your own. =0 (or empty) disables.
219
223
  PLURNK_PROVIDERS_GBNF=plurnk.gbnf
220
224
 
221
- # GBNF debug, honored natively by @plurnk/plurnk-providers (>=0.13.0): validate the grammar locally
222
- # (fail-hard if malformed) and run UNCONSTRAINED, never sending it to the model. Dev aid; off by default.
223
- PLURNK_GBNF_DEBUG=0
225
+ # GBNF filter mode (providers 0.33, renamed from PLURNK_GBNF_DEBUG; alias-scopable _<alias>):
226
+ # validate the grammar locally (fail-hard if malformed) and run UNCONSTRAINED, never sending it.
227
+ # Dev aid, off by default. Unset = normal constrained sampling.
228
+ # PLURNK_PROVIDERS_GBNF_DEBUG=
224
229
 
225
230
  # Provider retry attempts (providers 0.7+): how many times generate() retries a
226
231
  # TRANSIENT failure (429 rate-limit, 5xx/network) with exponential backoff (base 2s
227
232
  # is a provider constant — the COUNT is the operator knob). REQUIRED, fail-hard if
228
233
  # unset. Terminal errors (auth, quota, model refusal) never retry. 0 = no retries.
229
234
  PLURNK_PROVIDERS_RETRY_ATTEMPTS=3
235
+ # Transient-retry backoff base (ms); attempt N waits DELAY·2^(N−1); a Retry-After header wins.
236
+ PLURNK_PROVIDERS_RETRY_DELAY=2000
237
+ # Boot capability-probe (providers 0.33, #34): retries + backoff base (ms) for the /v1/models
238
+ # fingerprint that decides grammar transport. A flaky probe under load once silently disabled
239
+ # the rails — retrying closes that. Prefer the deterministic LLAMA_SERVER pin below over probing.
240
+ PLURNK_PROVIDERS_PROBE_ATTEMPTS=3
241
+ PLURNK_PROVIDERS_PROBE_DELAY=250
242
+ # Near-greedy decode: the default TEMPERATURE (every request, under caller sampling) + the
243
+ # REPEAT_PENALTY floor wherever a grammar rides. Both required (providers 0.33).
244
+ PLURNK_PROVIDERS_TEMPERATURE=0.2
245
+ PLURNK_PROVIDERS_REPEAT_PENALTY=1.15
246
+ # Pin a known llama-server box to llamacpp capabilities WITHOUT probing (providers 0.33, #34):
247
+ # _<alias>=1 forces grammar transport + slot pinning + native /tokenize, no /v1/models race.
248
+ # The deterministic cure for the silent-unconstrained class — set it per real llama-server alias.
249
+ PLURNK_PROVIDERS_LLAMA_SERVER_turboderp=1
230
250
  # Override the model's reported context window in tokens. Provider modules
231
251
  # normally read this from the model/API; set this to force a specific
232
252
  # value (smaller for testing, larger for models that under-report). Unset
@@ -244,15 +264,24 @@ PLURNK_PROVIDERS_RETRY_ATTEMPTS=3
244
264
  # for "on, zero third-party". Example: =acme-execs-cobol,@firewolf/firepad
245
265
  PLURNK_PLUGINS_TRUSTED_ONLY=0
246
266
 
247
- # PLURNK_DOCS_EXCLUDE — comma list of scheme/exec names dropped from BOTH the teaching oneliner
267
+ # PLURNK_SERVICE_DOCS_EXCLUDE — comma list of scheme/exec names dropped from BOTH the teaching oneliner
248
268
  # and the materialized pull-doc on load. The self-evident (plurnk/file) + retired (exec) names the
249
269
  # model needs no doc for. Empty → exclude nothing. Unknown names are inert (a filter, not a contract).
250
- PLURNK_DOCS_EXCLUDE="plurnk,file,exec"
270
+ PLURNK_SERVICE_DOCS_EXCLUDE="plurnk,file,exec"
251
271
 
252
- # PLURNK_PACKET_INJECT — an operator markdown file injected as a section right after the teaching
272
+ # PLURNK_SERVICE_PACKET_INJECT — an operator markdown file injected as a section right after the teaching
253
273
  # (the cached prefix). Read per-turn (live edits); a set-but-unreadable path fails the turn HARD.
254
274
  # `~/` expands to home. Unset → no section. The pressure valve for "improve the packet" without a fork.
255
- # PLURNK_PACKET_INJECT="~/injection.md"
275
+ # PLURNK_SERVICE_PACKET_INJECT="~/injection.md"
276
+
277
+ # PLURNK_SERVICE_POLICY — the operating-policy markdown, rendered as the ## Plurnk Service Policy
278
+ # section. Unset = the seeded ~/.plurnk/AGENTS.md; a path = that file; EXPLICITLY empty = policy off.
279
+ # PLURNK_SERVICE_POLICY=
280
+ # PLURNK_SERVICE_PROJECT — a per-project policy markdown (relative to projectRoot). Unset = <root>/AGENTS.md.
281
+ # PLURNK_SERVICE_PROJECT=
282
+ # PLURNK_SERVICE_REQUIREMENTS — override the requirements.md recency-footer path (relative to the package
283
+ # root). Unset = the packaged requirements.md.
284
+ # PLURNK_SERVICE_REQUIREMENTS=
256
285
 
257
286
  # --- Semantic search (~query chunking) ---
258
287
  # Project Semantics tiles each entry into <=window chunks so a large body is fully
@@ -263,19 +292,46 @@ PLURNK_DOCS_EXCLUDE="plurnk,file,exec"
263
292
  # window — NO model-specific number is assumed, so it scales to whatever embedder you
264
293
  # install. Set a positive value ONLY to cap below the window (e.g. to sweep
265
294
  # granularity); it is clamped to the window either way.
266
- PLURNK_SEMANTIC_CHUNK_TOKENS=
295
+ PLURNK_SERVICE_SEMANTIC_CHUNK_TOKENS=
267
296
  # Overlap fraction [0,1): trailing context re-covered at each chunk boundary so a
268
297
  # concept split across a cut still matches in both. ~0.15 is a standard RAG default.
269
- PLURNK_SEMANTIC_CHUNK_OVERLAP=0.15
270
- # embedBatch worker-pool size (read by @plurnk/plurnk-mimetypes-embeddings). Each worker holds
298
+ PLURNK_SERVICE_SEMANTIC_CHUNK_OVERLAP=0.15
299
+ # embedBatch worker-pool size (read by @plurnk/plurnk-mimetypes-embeddings, renamed to the
300
+ # PLURNK_MIMETYPES_* family). Each worker holds
271
301
  # its own model copy — a memory↔throughput dial. -1 = one worker per core (match the box); a
272
302
  # positive integer pins an exact count. Explicit floor → the embedder is default-ON out of the box.
273
- PLURNK_EMBED_WORKERS=-1
303
+ PLURNK_MIMETYPES_EMBED_WORKERS=-1
274
304
  # =1 forces the FTS-only path even with the embeddings package installed — the ~query
275
305
  # degrades to keyword ranking and no vectors are derived (no MiniLM pool spun up). For
276
306
  # hosts/runs that don't want vector search; the fast test lane sets it in .env.test.
277
- PLURNK_EMBED_DISABLE=0
307
+ PLURNK_SERVICE_EMBED_DISABLE=0
308
+
309
+ # --- Schemes: http (@plurnk/plurnk-schemes-http) ---
310
+ # Render-path knobs, REQUIRED once an HTML fetch renders (byte-only fetches never read them);
311
+ # these reproduce the old built-ins exactly. Optional Playwright/Chromium knobs below.
312
+ PLURNK_SCHEMES_HTTP_FETCH_TIMEOUT=30000
313
+ PLURNK_SCHEMES_HTTP_SALVAGE_MIN_BODY_CHARS=200
314
+ PLURNK_SCHEMES_HTTP_IDLE_TIMEOUT=900000
315
+ # PLURNK_SCHEMES_HTTP_PLAYWRIGHT_WS=ws://localhost:9222
316
+ # PLURNK_SCHEMES_HTTP_NO_SANDBOX=1
317
+ # PLURNK_SCHEMES_HTTP_CHROMIUM_HEAP_MB=2048
318
+
319
+ # --- Execs (@plurnk/plurnk-execs family) ---
320
+ # Runtime registration ceiling (subtractive, execs 0.4.31+). A disabled tag is ABSENT — never
321
+ # registered, never on the capability sheet (a de-register, distinct from a §3.2 deactivate).
322
+ # PLURNK_EXECS_ONLY=sh,jq,search # allowlist: register ONLY these tags (lowercase, csv); all else off
323
+ # Per-tag kill-switch — UPPERCASE tag name (PLURNK_EXECS_<TAG>=0); omit to keep a runtime enabled.
324
+ # PLURNK_EXECS_PYTHON=0
325
+ # PLURNK_EXECS_BC=0
326
+ # MCP bridge (execs-mcp 0.5, renamed from PLURNK_MCP_*) — one var per server; name IS the var.
327
+ # PLURNK_EXECS_MCP_<server> = <https url | stdio command line>
328
+ # PLURNK_EXECS_MCP_<server>_ENV = <json> # stdio: env overlay (tokens)
329
+ # PLURNK_EXECS_MCP_<server>_HEADERS = <json> # http: request headers (auth)
330
+ # PLURNK_EXECS_MCP_INSTALL=0 # gate: may /mcp hotload add servers at runtime
331
+ # Web search (execs-search) — SEARXNG_URL is the enable gate (unset ⇒ search unavailable).
332
+ PLURNK_EXECS_SEARCH_SEARXNG_URL=
333
+ # PLURNK_EXECS_SEARCH_LANGUAGE=en
334
+ # PLURNK_EXECS_SEARCH_LIMIT=12
335
+ # PLURNK_EXECS_SEARCH_TIMEOUT=10000
336
+ # PLURNK_EXECS_SEARCH_SAFESEARCH=
278
337
 
279
- # --- Diagnostics ---
280
- PLURNK_DEBUG=0
281
- PLURNK_LOG_LEVEL=info
package/INSTALL.md ADDED
@@ -0,0 +1,69 @@
1
+ # Configuring plurnk-service
2
+
3
+ Agent guide. Read this, then generate a `~/.plurnk/.env` fit to the user's box and intent. `.env.example` is the terse machine floor — the authoritative flag list and defaults; this is its reasoning layer. Every claimed coupling below is enforced by a `test/intg` check, so it is current with the installed version.
4
+
5
+ ## Install
6
+
7
+ ```
8
+ npm install -g @plurnk/plurnk-service
9
+ plurnk-service start # `migrate` first if the DB is uninitialized
10
+ ```
11
+
12
+ First run creates `~/.plurnk/`: `.env` (yours, seeded once with a model picker — **edit this**), `AGENTS.md` (the operating policy, yours), `.env.example` + `INSTALL.md` (package-owned references, **refreshed every boot** — never edit them). No model ships active; a fresh daemon runs until `PLURNK_MODEL` is set.
13
+
14
+ Optional vector search: `npm i @plurnk/plurnk-mimetypes-embeddings` (heavy native deps). Absent → `~query` degrades to FTS keyword ranking.
15
+
16
+ ## The cascade (where a value actually comes from)
17
+
18
+ Lowest precedence first; the last writer wins:
19
+
20
+ 1. **package `.env.example`** — the true floor, evolves with the installed version.
21
+ 2. **`~/.plurnk/.env.example`** — the readable legend, refreshed from the package each boot (a reference, not a place to edit).
22
+ 3. **`~/.plurnk/.env`** — the user's home config, seeded once, theirs to keep. **Write generated config here.**
23
+ 4. **`./.env`** — per-project, current working directory.
24
+ 5. **`--env-file=<path>` / `--config=<path>`** — explicit layers.
25
+ 6. **shell environment** — beats every file.
26
+ 7. **`--<flag>` CLI args** — top layer, overrides all.
27
+
28
+ CLI flags are the **1:1 mirror** of the env vars: strip `PLURNK_`, lowercase, `_`→`-`. `PLURNK_SERVICE_MAX_TURNS` ↔ `--service-max-turns`; `PLURNK_MODEL` ↔ `--model`. The flag surface and `--help` are generated from `.env.example`, so a var and its flag never diverge. Feature-flag bools are `=== "1"` exactly (never `"true"`); `~/` expands to home.
29
+
30
+ ## The prefix law (who owns a flag)
31
+
32
+ The prefix is the **owning package**: `PLURNK_SERVICE_*` (this daemon), `PLURNK_PROVIDERS_*`, `PLURNK_MIMETYPES_*`, `PLURNK_EXECS_*`, `PLURNK_SCHEMES_HTTP_*`, `PLURNK_CLIENT_*` (the CLI). **Bare `PLURNK_*` is reserved** for the front-door + cross-package set no single package owns: `PLURNK_MODEL[_*]`, `PLURNK_BASEURL_*`, `PLURNK_HOST`/`PLURNK_PORT`/`PLURNK_WS` (the connection rendezvous), and `PLURNK_PLUGINS_TRUSTED_ONLY` (the cross-family plugin gate). Vendor keys (`OPENAI_API_KEY`, `FIREWORKS_API_KEY`…) are vendor conventions — untouched.
33
+
34
+ A bare flag is a signal: more than one component depends on it. A prefixed one is single-owner. When a flag is `REQUIRED`, an unset or old-named value **fails the boot loudly** naming the var — never a silent default.
35
+
36
+ ## Couplings (the edges an agent gets wrong)
37
+
38
+ These are relationships *between* flags. Set them as a unit.
39
+
40
+ - **The window partition is exact.** `promptBudget = min(PLURNK_SERVICE_CTX, real window) − REASONING − ASSISTANT − SAFETY`; `REASONING + ASSISTANT` is the per-call `max_tokens`. Shipped invariant: any window ≥ 77Ki partitions to **exactly 65536** prompt tokens (`78848 − 4096 − 8192 − 1024`). Reserves exceeding the window fail the boot. *(Pinned: `Engine.budget` / `shipped-defaults`.)*
41
+ - **Reasoning capacity is one number in three places.** `PLURNK_SERVICE_REASONING` (the partition's reserve) **must equal** `PLURNK_PROVIDERS_THINKING_CAPACITY` (the provider's thinking cap) **must equal** the serving box's `--reasoning-budget` launch flag. llama-server ignores per-request numeric budgets, so only the launch flag clamps it; a mismatch makes the reserve fiction. The daemon warns at boot when thinking is on. *(Pinned: `shipped-defaults` asserts the first equality.)*
42
+ - **Grammar rails need a llama-server backend.** With `PLURNK_PROVIDERS_GBNF` set (rails on), the daemon **verifies enforcement at boot** and fails hard if the backend returns unconstrained output. For a known llama-server alias, pin `PLURNK_PROVIDERS_LLAMA_SERVER_<alias>=1` — it transports the grammar deterministically instead of probing `/v1/models` (a probe race once silently disabled the rails). *(Pinned: `grammar-enforcement-verify`.)*
43
+ - **A think-trained model must think somewhere.** `PLURNK_PROVIDERS_THINKING=off` reroutes a reasoning model's thought into the grammar's legal free zone as prose. Keep it `on` with a capacity; providers auto-clamp thinking on in-band grammar backends (fireworks), so one setting is right everywhere.
44
+
45
+ ## Profiles (examples, not a decision tree — adapt to the real box)
46
+
47
+ - **Local GPU (llama-server).** `PLURNK_MODEL_local="openai/<name>"`, `OPENAI_BASE_URL=http://127.0.0.1:<port>`, `PLURNK_MODEL=local`, `PLURNK_PROVIDERS_LLAMA_SERVER_local=1`, thinking `on`/`4096` **with the box launched `--reasoning-budget 4096`**. Full rails, exact tokenization.
48
+ - **Cloud, bring-your-own-key.** `PLURNK_MODEL_cloud="openrouter/<model>"`, `OPENROUTER_API_KEY=…`, `PLURNK_MODEL=cloud`. No `LLAMA_SERVER` pin (not llama-server); a `response_format`-grammar backend auto-clamps thinking to none.
49
+ - **plurnk.ai endpoint.** `PLURNK_MODEL_plurnk="plurnk/plurnk"`, `PLURNK_API_KEY=…`, `PLURNK_MODEL=plurnk`.
50
+ - **Headless / CI / constrained container.** `PLURNK_SERVICE_EMBED_DISABLE=1` (skip the embedder — a CPU-only box CPU-embedding a large corpus starves the loop), consider `PLURNK_SERVICE_MAX_TURNS=<n>` as a cost cap, `PLURNK_SERVICE_GIT_ALLOWED=0` to lock out git in a sandbox.
51
+
52
+ ## Flag sections (breakdown of `.env.example`)
53
+
54
+ Each mirrors a `# --- section ---` in the floor; consult the floor for exact defaults.
55
+
56
+ - **Storage** — `PLURNK_SERVICE_DB_PATH`, and the optional `PLURNK_SERVICE_SQLITE_*` passthroughs (sqlrite already sets a safe WAL posture; tune only for a hot/large DB).
57
+ - **Daemon transport** — bare `PLURNK_HOST`/`PLURNK_PORT` (the daemon binds); bare `PLURNK_WS` is the client's dial string (the daemon ignores it).
58
+ - **Model aliases** — bare `PLURNK_MODEL` selects the active provider; `PLURNK_MODEL_<alias>` defines one; `PLURNK_BASEURL_<alias>` overrides its endpoint. The front door — keep these bare and short.
59
+ - **Loop control / Engine rails** — `PLURNK_SERVICE_MAX_TURNS` (−1 = uncapped), `_MAX_COMMANDS`, `_MAX_STRIKES`, `_MIN_CYCLES`, `_MAX_CYCLE_PERIOD`, `_RPC_TIMEOUT`, `_LOOP_TIMEOUT`, `_PROPOSAL_TIMEOUT_MS`, `_EXEC_WAIT_MS`, `_EXEC_KILL_GRACE_MS`, `_SESSION_RUNS_MAX_ACTIVE`. Guardrails; the shipped values are sane.
60
+ - **Git** — `PLURNK_SERVICE_GIT_ALLOWED` (0 = hard sandbox lockout), `_GIT_AUTO`.
61
+ - **Packet / reference docs** — `PLURNK_SERVICE_FILES_ITEMS` (turn-1 file catalog cap), `_PROMPT_PREVIEW_CHARS`, `_DOCS_EXCLUDE`, `_PACKET_INJECT` (operator markdown section), `_POLICY`/`_PROJECT`/`_REQUIREMENTS` (policy + footer overrides; unset = the seeded/packaged defaults), `_MD_<alias>` (inject a markdown doc as a turn-0 entry).
62
+ - **Providers** — `PLURNK_PROVIDERS_THINKING`/`_THINKING_CAPACITY`, `_TEMPERATURE`, `_REPEAT_PENALTY`, `_FETCH_TIMEOUT`, `_RETRY_ATTEMPTS`/`_RETRY_DELAY`, `_PROBE_ATTEMPTS`/`_PROBE_DELAY`, `_GBNF` (grammar variant), `_LLAMA_SERVER_<alias>`, `_CONTEXT_SIZE`, `_GBNF_DEBUG`. Alias-scopable: any knob takes a `_<alias>` suffix that wins over the bare fallback.
63
+ - **The window partition** — `PLURNK_SERVICE_CTX`/`_REASONING`/`_ASSISTANT`/`_SAFETY` (see Couplings).
64
+ - **Plugins** — bare `PLURNK_PLUGINS_TRUSTED_ONLY` (0/unset = load all installed; a value = `@plurnk/*` plus an allowlist).
65
+ - **Semantic search** — `PLURNK_SERVICE_SEMANTIC_CHUNK_TOKENS`/`_CHUNK_OVERLAP` (service-side chunking), `PLURNK_SERVICE_EMBED_DISABLE` (FTS-only), `PLURNK_MIMETYPES_EMBED_WORKERS` (the embedder's pool — mimetypes-owned).
66
+ - **Schemes: http** — `PLURNK_SCHEMES_HTTP_FETCH_TIMEOUT`/`_SALVAGE_MIN_BODY_CHARS`/`_IDLE_TIMEOUT` (required on the HTML render path), optional Playwright/Chromium knobs.
67
+ - **Execs** — `PLURNK_EXECS_<runtime>=0` disables a runtime; `PLURNK_EXECS_MCP_<server>` bridges an MCP server; `PLURNK_EXECS_SEARCH_SEARXNG_URL` enables web search (unset = search off).
68
+
69
+ The client's own knobs live under `PLURNK_CLIENT_*` (`--session`, `--run`, `--yolo`, `--json`…) — see `plurnk --help`.
package/README.md CHANGED
@@ -32,7 +32,7 @@ npm install -g @plurnk/plurnk-service
32
32
  plurnk-service start # daemon (`migrate` initializes the DB)
33
33
  ```
34
34
 
35
- Config + state live in `~/.plurnk/` (created on first run): set `PLURNK_MODEL` and friends in `~/.plurnk/.env`; the DB defaults to `~/.plurnk/plurnk.db`. Provider-agnostic — point `PLURNK_MODEL` at any vendor. Full override cascade (`~/.plurnk` < `./.env` < `--env-file` < shell < `--flags`) is documented at the top of `.env.example`. Also exports `{ Engine, Daemon, SchemeRegistry }` for in-process embedding.
35
+ Config + state live in `~/.plurnk/` (created on first run): put your config in `~/.plurnk/.env` (yours, seeded once); the DB defaults to `~/.plurnk/plurnk.db`. Provider-agnostic — point `PLURNK_MODEL` at any vendor. **[`INSTALL.md`](./INSTALL.md) is the config guide** the cascade, the prefix taxonomy, the coupling matrix, and profiles for common deployments; `.env.example` is the terse machine floor it breaks down. Also exports `{ Engine, Daemon, SchemeRegistry }` for in-process embedding.
36
36
 
37
37
  ## Contract & siblings
38
38