@plurnk/plurnk-service 0.42.0 → 0.43.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 (52) hide show
  1. package/.env.example +21 -3
  2. package/SPEC.md +1 -0
  3. package/bin/plurnk-service.ts +50 -7
  4. package/dist/core/ChannelWrite.d.ts.map +1 -1
  5. package/dist/core/ChannelWrite.js +2 -1
  6. package/dist/core/ChannelWrite.js.map +1 -1
  7. package/dist/core/Engine.d.ts.map +1 -1
  8. package/dist/core/Engine.js +84 -60
  9. package/dist/core/Engine.js.map +1 -1
  10. package/dist/core/SchemeRegistry.d.ts +2 -0
  11. package/dist/core/SchemeRegistry.d.ts.map +1 -1
  12. package/dist/core/SchemeRegistry.js +16 -2
  13. package/dist/core/SchemeRegistry.js.map +1 -1
  14. package/dist/core/packet-wire.d.ts +30 -31
  15. package/dist/core/packet-wire.d.ts.map +1 -1
  16. package/dist/core/packet-wire.js +81 -80
  17. package/dist/core/packet-wire.js.map +1 -1
  18. package/dist/core/plurnk-uri.d.ts +3 -0
  19. package/dist/core/plurnk-uri.d.ts.map +1 -0
  20. package/dist/core/plurnk-uri.js +23 -0
  21. package/dist/core/plurnk-uri.js.map +1 -0
  22. package/dist/core/scheme-types.d.ts +4 -0
  23. package/dist/core/scheme-types.d.ts.map +1 -1
  24. package/dist/core/scheme-types.js.map +1 -1
  25. package/dist/schemes/Plurnk.d.ts.map +1 -1
  26. package/dist/schemes/Plurnk.js +8 -4
  27. package/dist/schemes/Plurnk.js.map +1 -1
  28. package/dist/schemes/_entry-manifest.d.ts.map +1 -1
  29. package/dist/schemes/_entry-manifest.js +2 -1
  30. package/dist/schemes/_entry-manifest.js.map +1 -1
  31. package/dist/schemes/_entry-ops.d.ts.map +1 -1
  32. package/dist/schemes/_entry-ops.js +6 -1
  33. package/dist/schemes/_entry-ops.js.map +1 -1
  34. package/dist/server/Daemon.d.ts.map +1 -1
  35. package/dist/server/Daemon.js +3 -1
  36. package/dist/server/Daemon.js.map +1 -1
  37. package/dist/server/clientTurn.d.ts.map +1 -1
  38. package/dist/server/clientTurn.js +1 -2
  39. package/dist/server/clientTurn.js.map +1 -1
  40. package/dist/server/envelope.d.ts +1 -0
  41. package/dist/server/envelope.d.ts.map +1 -1
  42. package/dist/server/envelope.js +9 -0
  43. package/dist/server/envelope.js.map +1 -1
  44. package/dist/server/methods/loop_run.js +2 -2
  45. package/dist/server/methods/loop_run.js.map +1 -1
  46. package/dist/server/methods/session_rename.d.ts +5 -0
  47. package/dist/server/methods/session_rename.d.ts.map +1 -0
  48. package/dist/server/methods/session_rename.js +32 -0
  49. package/dist/server/methods/session_rename.js.map +1 -0
  50. package/migrations/0000-00-00.01_schema.sql +3 -5
  51. package/package.json +9 -34
  52. package/requirements.md +2 -8
package/.env.example CHANGED
@@ -6,6 +6,18 @@
6
6
  # --- Storage ---
7
7
  PLURNK_DB_PATH=./plurnk.db
8
8
 
9
+ # --- Sqlite tuning (curated knobs passed through to sqlrite; optional) ---
10
+ # sqlrite already sets the safe posture (WAL + synchronous=NORMAL + busy_timeout=5000ms).
11
+ # These are operator overrides — integers; unset = sqlrite/sqlite default. Uncomment to tune.
12
+ # busy_timeout (ms): how long a writer waits on a lock before SQLITE_BUSY. 0 = immediate.
13
+ # PLURNK_SQLITE_TIMEOUT=5000
14
+ # cache_size: positive = pages, negative = KiB of memory. Bigger = fewer disk reads on a hot db.
15
+ # PLURNK_SQLITE_CACHE_SIZE=-16000
16
+ # mmap_size: bytes of memory-mapped I/O (read perf on large file-backed dbs). 0 disables.
17
+ # PLURNK_SQLITE_MMAP_SIZE=268435456
18
+ # max_page_count: hard db-size ceiling in PAGES — a write past it errors (disk-fill guard).
19
+ # PLURNK_SQLITE_MAX_PAGE_COUNT=524288
20
+
9
21
  # --- Daemon transport ---
10
22
  PLURNK_HOST=127.0.0.1
11
23
  PLURNK_PORT=3044
@@ -89,6 +101,12 @@ PLURNK_GIT_AUTO=1
89
101
  # session.create settings.manifestItems, which replaces this value (#231).
90
102
  PLURNK_MANIFEST_ITEMS=-1
91
103
 
104
+ # Prompt-preview cap: the loop's prompt renders in user.prompt every turn, and a fat prompt
105
+ # replays each turn (bloat). Show the first N CHARS of the body + a pointer to the full
106
+ # prompt (always READable at its plurnk://prompt/<loop>/<seq> entry — nothing is lost).
107
+ # -1 = no cap (render the full prompt every turn). Default 512.
108
+ PLURNK_PROMPT_PREVIEW_CHARS=512
109
+
92
110
  # Session-tier ceiling on CONCURRENT active runs (a run with a non-terminal loop)
93
111
  # — the fork-bomb / destabilization brake. -1 = no cap (default); only concurrency
94
112
  # is bounded, never lifetime, since sessions persist for months. A spawn/fork past
@@ -100,12 +118,12 @@ PLURNK_SESSION_RUNS_MAX_ACTIVE=-1
100
118
  # fail-hard if unset — 0 = native reasoning off (in-DSL PLAN does the reasoning), -1 =
101
119
  # adaptive / no cap, N = capped at N tokens. Provider modules translate it per model
102
120
  # family (reasoning_effort tiers, budget_tokens). Floor (gemma): 0.
103
- PLURNK_PROVIDERS_REASONING_BUDGET=0
121
+ PLURNK_PROVIDERS_REASONING_BUDGET=-1
104
122
  #
105
123
  # Planning: enable the grammar's <<PLAN:...:PLAN op so the model reasons in-band before
106
124
  # acting. A shared universal knob (like PLURNK_FETCH_TIMEOUT below): the service advertises
107
125
  # the op in # Plurnk System Tools; the provider reads it too. =1 on, =0 off.
108
- PLURNK_PLAN=1
126
+ PLURNK_PLAN=0
109
127
  # Service-wide fetch timeout in ms — the universal upper bound on any
110
128
  # single outbound request (provider calls, future http:// scheme reads,
111
129
  # anything that does network IO). Streamed completions can run long;
@@ -122,7 +140,7 @@ PLURNK_VERSION_POLL_TTL=3600000
122
140
  # /v1/models fingerprint) can only sample valid plurnk DSL; others drop it silently.
123
141
  # A bare name (plurnk.gbnf) is a variant shipped by
124
142
  # @plurnk/plurnk-grammar; an absolute/relative path is your own. =0 (or empty) disables.
125
- PLURNK_PROVIDERS_GBNF=plurnk.gbnf
143
+ # PLURNK_PROVIDERS_GBNF=plurnk.gbnf
126
144
  # Provider retry attempts (providers 0.7+): how many times generate() retries a
127
145
  # TRANSIENT failure (429 rate-limit, 5xx/network) with exponential backoff (base 2s
128
146
  # is a provider constant — the COUNT is the operator knob). REQUIRED, fail-hard if
package/SPEC.md CHANGED
@@ -856,6 +856,7 @@ registry.register("loop.run", {
856
856
  | `session.runs` | `id?: number` | `{ runs: Run[] }` | Lists runs in a session (defaults to attached session); most-recent first. |
857
857
  | `session.prompts` | `id?: number`, `limit?: number` | `{ prompts: string[] }` | A session's prior user prompts (the conversation run's loop seeds), newest-first, capped by `limit` (default 100); defaults to attached session. Lets a client seed up/down recall without log archaeology. |
858
858
  | `session.set_root` | `projectRoot: string \| null` | `{ projectRoot }` | Update the workspace pointer on the attached session. Null reverts to headless. |
859
+ | `session.rename` | `name: string` | `{ id, name }` | Rename the attached session — its name is a **mutable handle** on the world (unlike a run, whose name is frozen at instantiation, §machine-processes). Mutates `sessions.name` only; runs, log, and membership untouched. A name another session holds is rejected (`sessions.name` is unique). {§methods-session-rename} |
859
860
  | `session.constrain` | `effect: "pick" \| "hide" \| "view" \| "repo"`, `glob: string` | `{ effect, glob }` | Add a workspace membership constraint (§membership overlay): `pick` admits a file git misses (the sole source when git is absent), `hide` drops a tracked match, `view` admits a member read-only (refused at the edit gate), `repo` declares a git repo folder anywhere so its members join the manifest. Immediate. |
860
861
  | `session.unconstrain` | `effect: "pick" \| "hide" \| "view" \| "repo"`, `glob: string` | `{ effect, glob }` | Remove a membership constraint (the `drop` verb) — the inverse of `session.constrain`. Immediate. |
861
862
  | `session.constraints` | none | `{ constraints }` | List the attached session's membership constraints. |
@@ -24,10 +24,25 @@ export default class Cli {
24
24
  try { process.loadEnvFile(path); }
25
25
  catch (cause) { Cli.#die(64, `failed to load ${path}: ${cause instanceof Error ? cause.message : String(cause)}`); }
26
26
  } else if (required) {
27
- Cli.#die(64, `--config: ${path} does not exist`);
27
+ Cli.#die(64, `${path} does not exist`);
28
28
  }
29
29
  }
30
30
 
31
+ // node-style env-file flags: --env-file=<path> (required) / --env-file-if-exists=<path>
32
+ // (skip if missing), repeatable, in command-line order. They layer extra files ABOVE
33
+ // the .env cascade but BELOW shell env (loadEnvFile is set-if-unset) and the --<knob>
34
+ // CLI flags (assigned last). The `=` form only — node's canonical syntax (so it never
35
+ // leaks a positional). NB: node validates these paths from the full argv (and exits on
36
+ // a missing *required* one), but only LOADS pre-script files — the post-script loading
37
+ // a published `plurnk-service --env-file=…` needs is this.
38
+ static #envFileArgs(): Array<{ path: string; required: boolean }> {
39
+ return process.argv.flatMap((a): Array<{ path: string; required: boolean }> => {
40
+ if (a.startsWith("--env-file-if-exists=")) return [{ path: a.slice(a.indexOf("=") + 1), required: false }];
41
+ if (a.startsWith("--env-file=")) return [{ path: a.slice(a.indexOf("=") + 1), required: true }];
42
+ return [];
43
+ });
44
+ }
45
+
31
46
  // The .env cascade always populates these from .env.example, so absence is
32
47
  // a broken config, not a runtime branch — fail hard rather than `?? ""`.
33
48
  static #requireEnv(name: string): string {
@@ -36,11 +51,34 @@ export default class Cli {
36
51
  return value;
37
52
  }
38
53
 
54
+ // Optional integer sqlite tuning knob — undefined when unset (so it never clobbers
55
+ // sqlrite's default by spreading an explicit `undefined`); fail-hard on a non-integer.
56
+ static #sqliteKnob(name: string): number | undefined {
57
+ const raw = process.env[name];
58
+ if (raw === undefined || raw.trim() === "") return undefined;
59
+ const n = Number(raw);
60
+ if (!Number.isInteger(n)) Cli.#die(78, `${name} must be an integer, got ${JSON.stringify(raw)}`);
61
+ return n;
62
+ }
63
+
39
64
  static async #openDb(dbPath: string): Promise<Db> {
65
+ // Curated sqlite tuning (sqlrite 5.2.0, #7) — pass through ONLY the knobs the
66
+ // operator set, so an unset one keeps sqlrite's default (e.g. busy_timeout=5000).
67
+ const tuning: Record<string, number> = {};
68
+ for (const [env, opt] of [
69
+ ["PLURNK_SQLITE_TIMEOUT", "timeout"],
70
+ ["PLURNK_SQLITE_CACHE_SIZE", "cacheSize"],
71
+ ["PLURNK_SQLITE_MMAP_SIZE", "mmapSize"],
72
+ ["PLURNK_SQLITE_MAX_PAGE_COUNT", "maxPageCount"],
73
+ ] as const) {
74
+ const v = Cli.#sqliteKnob(env);
75
+ if (v !== undefined) tuning[opt] = v;
76
+ }
40
77
  const db = await SqlRite.open({
41
78
  path: dbPath,
42
79
  dir: [resolve(Cli.#projectRoot, "migrations"), resolve(Cli.#projectRoot, "src")],
43
80
  functions: [resolve(Cli.#projectRoot, "src/schemes/cosine.ts")],
81
+ ...tuning,
44
82
  });
45
83
  return db as unknown as Db;
46
84
  }
@@ -71,10 +109,13 @@ export default class Cli {
71
109
  }
72
110
 
73
111
  static async main(): Promise<void> {
74
- // Env cascade: .env.example (shipped defaults) < .env (project) <
75
- // .env.<config> (--config) < shell. process.loadEnvFile is set-if-unset,
76
- // so loading in low→high precedence order yields the right effective env
77
- // (highest precedence loads FIRST first write wins).
112
+ // Env cascade, highest precedence loads FIRST (loadEnvFile is set-if-unset,
113
+ // first write wins): --env-file(s) < --config < .env < .env.example, all of them
114
+ // OUTRANKED by pre-set shell env, then by the --<knob> CLI flags (assigned last,
115
+ // below). So --env-file overrides the .env files but never a shell var or a CLI
116
+ // arg — node-idiomatic layering.
117
+ for (const { path: envFile, required } of Cli.#envFileArgs()) Cli.#loadEnv(envFile, required);
118
+
78
119
  const configFlagIndex = process.argv.findIndex((a) => a === "--config" || a.startsWith("--config="));
79
120
  const configFile = ((): string | null => {
80
121
  if (configFlagIndex === -1) return null;
@@ -97,8 +138,10 @@ export default class Cli {
97
138
 
98
139
  ${EnvFlags.formatFlagsHelp(flagDescriptors)}
99
140
 
100
- --config=<path> layer additional env from <path>
101
- -h, --help show this help
141
+ --env-file=<path> layer env from <path> (repeatable; errors if missing)
142
+ --env-file-if-exists=<path> layer env from <path> if present (repeatable)
143
+ --config=<path> layer additional env from <path>
144
+ -h, --help show this help
102
145
  `;
103
146
 
104
147
  const { positionals, values } = parseArgs({
@@ -1 +1 @@
1
- {"version":3,"file":"ChannelWrite.d.ts","sourceRoot":"","sources":["../../src/core/ChannelWrite.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChannelWrite.d.ts","sourceRoot":"","sources":["../../src/core/ChannelWrite.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@
6
6
  // Helpers update entry_channels (content / state) and subscriptions, and emit
7
7
  // stream/event notifications scoped to the entry's session via an optional
8
8
  // callback the daemon wires in.
9
+ import { renderAddress } from "./plurnk-uri.js";
9
10
  export default class ChannelWrite {
10
11
  static #channelMeta(db) { return db.channel_meta; }
11
12
  static #appendStmt(db) { return db.append_to_channel; }
@@ -19,7 +20,7 @@ export default class ChannelWrite {
19
20
  // a filesystem entry (the file scheme stores scheme=NULL), so it decodes to
20
21
  // file:///.
21
22
  static #targetUri(scheme, pathname) {
22
- return `${scheme === null ? "file" : scheme}://${pathname}`;
23
+ return renderAddress(scheme === null ? "file" : scheme, pathname);
23
24
  }
24
25
  // A stream chunk accumulates into the channel's content (§chunk-accumulation-chunks-accumulate)
25
26
  // and fires a stream/event (§live-updates-stream-event-fires-on-chunk); the log carries the
@@ -1 +1 @@
1
- {"version":3,"file":"ChannelWrite.js","sourceRoot":"","sources":["../../src/core/ChannelWrite.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChannelWrite.js","sourceRoot":"","sources":["../../src/core/ChannelWrite.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Engine.d.ts","sourceRoot":"","sources":["../../src/core/Engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Engine.d.ts","sourceRoot":"","sources":["../../src/core/Engine.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,7 @@ import { Mimetypes, emptyRegistry } from "@plurnk/plurnk-mimetypes";
4
4
  import EntryCrud from "../schemes/_entry-crud.js";
5
5
  import EntryManifest from "../schemes/_entry-manifest.js";
6
6
  import GitMembership from "./git-membership.js";
7
+ import { foldAuthorityIntoPath, renderAddress } from "./plurnk-uri.js";
7
8
  import GitState from "./git-state.js";
8
9
  import Fork from "./fork.js";
9
10
  import RunCap from "./run-cap.js";
@@ -538,10 +539,10 @@ class Engine {
538
539
  const promptRow = await this.#db.engine_get_loop_prompt.get({ loop_id: loopId });
539
540
  if (promptRow !== undefined && typeof promptRow.prompt === "string" && promptRow.prompt.length > 0) {
540
541
  const promptPath = {
541
- kind: "url", raw: `plurnk:///prompt/${loopId}/${seq}`,
542
+ kind: "url", raw: `plurnk://prompt/${loopId}/${seq}`,
542
543
  scheme: "plurnk", username: null, password: null,
543
- hostname: null, port: null,
544
- pathname: `/prompt/${loopId}/${seq}`, params: {}, fragment: null,
544
+ hostname: "prompt", port: null,
545
+ pathname: `/${loopId}/${seq}`, params: {}, fragment: null,
545
546
  };
546
547
  const promptStmt = {
547
548
  op: "EDIT", suffix: "", signal: null,
@@ -554,9 +555,9 @@ class Engine {
554
555
  sequence: nextActionIndex, origin: "plurnk",
555
556
  onDispatch: (id) => { promptLogId = id; onDispatch?.(id); },
556
557
  });
557
- // §prompt-fold (User Note 6): the prompt EDIT duplicates
558
- // packet.user.prompt (its own section), so fold it — logged for
559
- // forensics, collapsed in the model's log, re-OPENable.
558
+ // §prompt-fold (User Note 6): the prompt EDIT duplicates the
559
+ // prompt section, so fold it — logged for forensics, collapsed
560
+ // in the model's log, re-OPENable.
560
561
  if (promptLogId !== undefined)
561
562
  await this.#db.engine_fold_log_entry.run({ id: promptLogId });
562
563
  nextActionIndex++;
@@ -659,7 +660,7 @@ class Engine {
659
660
  // grammar can't bound degeneration *inside* a statement body — this caps the
660
661
  // decode at the free window so a runaway can't reach the context wall.
661
662
  const genCeiling = _a.computeCeiling(provider.contextSize, this.#budgetCeiling); // provider.contextSize, the immutable identity, read by the budget — §provider-surface-identity
662
- const maxTokens = genCeiling === null ? undefined : Math.max(1, genCeiling - requestPacket.system.tokens - requestPacket.user.tokens);
663
+ const maxTokens = genCeiling === null ? undefined : Math.max(1, genCeiling - requestPacket.tokens);
663
664
  const response = await provider.generate({ messages: modelMessages, runId: String(runId), signal, grammar: await this.#grammarConstraint(), maxTokens }); // §provider-surface-generate §provider-guarantees-single-call §provider-guarantees-signal-wired
664
665
  // Engine splits wire-level response: emission (content, reasoning,
665
666
  // parsed ops) → packet.assistant per Packet.json §assistant;
@@ -853,14 +854,15 @@ class Engine {
853
854
  // scheme-agnostic, so the service teaches what schemes exist + what they do
854
855
  // at packet-time (grammar#239 item 7). SchemeRegistry.teach() assembles it.
855
856
  const system_definition = `${byRole("system")}\n\n${this.#schemes.teach()}`;
856
- // user.prompt sources from the loop's most recent prompt entry first
857
+ // the prompt section sources from the loop's most recent prompt entry first
857
858
  // (plurnk:///prompt/<loop_id>/<N> for the highest N written to date).
858
859
  // This is what inject + the turn-1 foist write into. Falls back to
859
860
  // the runLoop caller's messages.user for tests that bypass the
860
861
  // foist mechanism entirely.
861
- const latestPromptRow = await this.#db.drain_get_latest_prompt_body_for_loop.get({ pattern: `prompt/${loopId}/%` });
862
+ const latestPromptRow = await this.#db.drain_get_latest_prompt_body_for_loop.get({ pattern: `/prompt/${loopId}/%` });
863
+ const promptCap = Number.parseInt(process.env.PLURNK_PROMPT_PREVIEW_CHARS ?? "", 10);
862
864
  const prompt = (latestPromptRow !== undefined && typeof latestPromptRow.content === "string" && latestPromptRow.content.length > 0)
863
- ? latestPromptRow.content
865
+ ? PacketWire.previewPrompt(latestPromptRow.content, renderAddress("plurnk", latestPromptRow.pathname), Number.isInteger(promptCap) ? promptCap : -1)
864
866
  : byRole("user");
865
867
  // Requirements is engine-sourced, NOT threaded from callers — that threading is
866
868
  // exactly how it went missing (callers read the sysprompt but never the
@@ -874,65 +876,82 @@ class Engine {
874
876
  const requirementsText = `Syntax: <<OPsuffix[signal]?(target)?<Line/Result>?:body?:OPsuffix\n\n${planDirective}${baseRequirements}`;
875
877
  const log = await this.#buildLog(runId);
876
878
  const telemetryErrors = presetTelemetry ?? await this.#buildTelemetryErrors(loopId, currentTurnSeq);
877
- // Per-section render-cost subtotals via provider's tokenizer.
878
- // Engine approximates each section by tokenizing its serialized
879
- // form — wire-payload tokens may differ slightly because chat-
880
- // template scaffolding adds bytes, but the subtotal tracks "what
881
- // the model has to process" closely enough for budget diagnostics.
882
879
  const countTokens = (t) => provider.countTokens(t); // §provider-surface-counttokens
883
- // Budget readout (SPEC.md §tokenomics). Two-pass: measure the wire-rendered
884
- // index/log sections (budget-independent), install the readout with a
885
- // tokensFree placeholder, measure the assembled total, resolve free,
886
- // substitute. Subtotals come from the real render meta and fences
887
- // included not a serialized approximation. ceiling is the provider's
888
- // window × PLURNK_BUDGET_CEILING (null when no window is reported →
889
- // headline omitted, section lines still shown).
880
+ const tools = this.#collectTools();
881
+ // Budget readout (SPEC.md §tokenomics). Two-pass: render the budget from
882
+ // the structured log's subtotals with a {{tokensFree}} placeholder, build
883
+ // the section list, measure the assembled total, resolve free, substitute.
884
+ // Subtotals come from the real log render meta and fences included — not
885
+ // a serialized approximation. ceiling is the provider's window ×
886
+ // PLURNK_BUDGET_CEILING (null when no window is reported → headline
887
+ // omitted, section lines still shown). §tokenomics-render-weight-budget
890
888
  const ceiling = _a.computeCeiling(provider.contextSize, this.#budgetCeiling);
891
- const scratch = {
892
- system: { system_definition, log },
893
- user: { prompt, telemetry: { budget: "", errors: telemetryErrors, git: gitStatus }, tools: this.#collectTools(), system_requirements: requirementsText },
894
- };
895
- const sections = PacketWire.measureBudgetSections(scratch, countTokens);
896
- scratch.user.telemetry.budget = this.#renderBudget(sections, ceiling);
897
- const total = countTokens(PacketWire.renderSystemContent(scratch.system)) + countTokens(PacketWire.renderUserContent(scratch.user));
889
+ const budgetReadout = this.#renderBudget(PacketWire.measureLogBudget(log, countTokens), ceiling);
890
+ // The default packet: an ordered list of sections, each addressable state
891
+ // (§packet-construction). `slot` is the prompt-cache boundary; order within
892
+ // a slot is the render order (requirements last — the contract closest to
893
+ // the assistant turn). budget/errors/git are peer sections (unbundled
894
+ // each independently overridable). The budget section still carries its
895
+ // {{tokensFree}} placeholders here; they resolve below once the assembled
896
+ // total is known.
897
+ const defaults = [
898
+ { name: "definition", slot: "system", header: null, content: system_definition, tokens: 0 },
899
+ { name: "log", slot: "system", header: "Plurnk System Log", content: PacketWire.renderLog(log), tokens: 0 },
900
+ { name: "prompt", slot: "user", header: "Plurnk System User Prompt", content: prompt, tokens: 0 },
901
+ { name: "budget", slot: "user", header: "Plurnk System Budget", content: budgetReadout, tokens: 0 },
902
+ { name: "errors", slot: "user", header: "Plurnk System Errors", content: PacketWire.renderErrors(telemetryErrors), tokens: 0 },
903
+ { name: "git", slot: "user", header: "Plurnk System Git Status", content: PacketWire.renderGit(gitStatus), tokens: 0 },
904
+ { name: "tools", slot: "user", header: "Plurnk System Tools", content: tools.join("\n"), tokens: 0 },
905
+ { name: "requirements", slot: "user", header: "Plurnk System Requirements", content: requirementsText, tokens: 0 },
906
+ ];
907
+ // Plugin packet control (§packet-construction): trusted schemes rewrite the
908
+ // default list — add, remove, reorder — in-process, before measurement.
909
+ const sections = await this.#schemes.transformSections(defaults);
910
+ // Pass 1: measure the assembled total with the placeholder budget in
911
+ // place, resolve free/percent, substitute into the budget section.
912
+ const total = countTokens(PacketWire.renderSlot(sections, "system")) + countTokens(PacketWire.renderSlot(sections, "user"));
898
913
  const tokensFree = ceiling === null ? null : Math.max(0, ceiling - total); // free floors at 0 on overshoot — §tokenomics-over-budget-floor
899
914
  const percent = ceiling === null ? null : Math.round((total / ceiling) * 100); // usage as % of the ceiling — §tokenomics-context-percent
900
- const budget = tokensFree === null
901
- ? scratch.user.telemetry.budget
902
- : scratch.user.telemetry.budget
903
- .replace(TOKEN_USAGE_PLACEHOLDER, String(total))
904
- .replace(TOKEN_PERCENT_PLACEHOLDER, String(percent))
905
- .replace(TOKENS_FREE_PLACEHOLDER, String(tokensFree));
906
- const system = { tokens: 0, system_definition, log };
907
- const user = { tokens: 0, prompt, telemetry: { budget, errors: telemetryErrors, git: gitStatus }, tools: scratch.user.tools, system_requirements: requirementsText };
908
- system.tokens = countTokens(PacketWire.renderSystemContent(system));
909
- user.tokens = countTokens(PacketWire.renderUserContent(user));
910
- return { system, user };
915
+ if (tokensFree !== null) {
916
+ const budgetSec = sections.find((s) => s.name === "budget"); // a plugin may have removed it
917
+ if (budgetSec) {
918
+ budgetSec.content = budgetSec.content
919
+ .replace(TOKEN_USAGE_PLACEHOLDER, String(total))
920
+ .replace(TOKEN_PERCENT_PLACEHOLDER, percent === 0 && total > 0 ? "<1" : String(percent))
921
+ .replace(TOKENS_FREE_PLACEHOLDER, String(tokensFree));
922
+ }
923
+ }
924
+ // Pass 2: per-section render-weight + the assembled packet total (post
925
+ // substitution the placeholder/number length delta is negligible).
926
+ for (const s of sections)
927
+ s.tokens = countTokens(PacketWire.renderSection(s));
928
+ const packetTokens = countTokens(PacketWire.renderSlot(sections, "system")) + countTokens(PacketWire.renderSlot(sections, "user"));
929
+ return { tokens: packetTokens, sections, telemetryErrors };
911
930
  }
912
931
  // Budget readout body, rendered into the `# Plurnk System Budget` section.
913
932
  // Headline `ceiling/free` only when a ceiling exists; section lines for the
914
933
  // curatable index/log weight the model can FOLD back. tokensFree is a
915
934
  // placeholder here — buildSystem substitutes it after measuring the packet.
916
- #renderBudget(sections, ceiling) {
935
+ #renderBudget(log, ceiling) {
917
936
  const lines = [];
918
937
  if (ceiling !== null)
919
938
  lines.push(`ceiling ${ceiling} · usage ${TOKEN_USAGE_PLACEHOLDER} (${TOKEN_PERCENT_PLACEHOLDER}%) · free ${TOKENS_FREE_PLACEHOLDER}`);
920
- if (sections.log.entries > 0) {
921
- lines.push(`Log entries: ${sections.log.entries} entries, ${sections.log.tokens} tokens`);
939
+ if (log.entries > 0) {
940
+ lines.push(`Log entries: ${log.entries} entries, ${log.tokens} tokens`);
922
941
  // Per-turn weight — the grinder's rollback unit, oldest first: the
923
942
  // model sees what's first to go (§tokenomics {§tokenomics-turn-totals}).
924
- if (sections.log.byTurn.length > 0) {
943
+ if (log.byTurn.length > 0) {
925
944
  lines.push("Turns:", "| turn | tokens |", "|---|--:|");
926
- for (const t of sections.log.byTurn)
945
+ for (const t of log.byTurn)
927
946
  lines.push(`| ${t.turn} | ${t.tokens} |`);
928
947
  }
929
948
  // The heaviest individual log items — the FOLD targets behind the weight
930
949
  // (§tokenomics {§tokenomics-largest-entries}). "items", not "entries": the readout
931
950
  // lists log:/// rows (log items), distinct from catalog entries (plurnk.md: "EDIT
932
951
  // is only for entries. Do not attempt to edit log items.").
933
- if (sections.log.largest.length > 0) {
952
+ if (log.largest.length > 0) {
934
953
  lines.push("Heaviest items:", "| item | tokens |", "|---|--:|");
935
- for (const e of sections.log.largest)
954
+ for (const e of log.largest)
936
955
  lines.push(`| ${e.path} | ${e.tokens} |`);
937
956
  }
938
957
  }
@@ -958,16 +977,16 @@ class Engine {
958
977
  const entry = this.#executors.entry(tag);
959
978
  if (entry?.example)
960
979
  tools.push(`* ${entry.example}`);
961
- // #note12 — link the executor's fuller doc (materialized at plurnk:///docs/<tag>);
980
+ // #note12 — link the executor's fuller doc (materialized at plurnk:///docs/<tag>.md);
962
981
  // its token cost rides that manifest entry, so no inline recount here.
963
982
  if (entry?.documentation)
964
- tools.push(`* docs for ${tag}: plurnk:///docs/${tag}`);
983
+ tools.push(`* docs for ${tag}: plurnk://docs/${tag}.md`);
965
984
  }
966
985
  }
967
986
  return tools;
968
987
  }
969
988
  // #note12 — the daughter-provided reference docs (schemes' + execs' `documentation`),
970
- // materialized at plurnk:///docs/<name> by loop_run (like operator docs) so the
989
+ // materialized at plurnk:///docs/<name>.md by loop_run (like operator docs) so the
971
990
  // catalogue's doc-links READ and the manifest carries each doc's token cost.
972
991
  docEntries() {
973
992
  const out = this.#schemes.docs();
@@ -988,7 +1007,7 @@ class Engine {
988
1007
  // §grinder-overflow-only — fires only on actual overflow, never speculatively
989
1008
  async #enforceBudget({ packet, provider, runId, loopId, turnId, sessionId, turnNumber, rebuild }) {
990
1009
  const ceiling = _a.computeCeiling(provider.contextSize, this.#budgetCeiling);
991
- const measure = (p) => p.system.tokens + p.user.tokens;
1010
+ const measure = (p) => p.tokens;
992
1011
  if (ceiling === null || measure(packet) <= ceiling)
993
1012
  return { packet, fit: true, struck: false };
994
1013
  const folded = new Map();
@@ -1000,7 +1019,7 @@ class Engine {
1000
1019
  note(le.scheme ?? "log");
1001
1020
  if (priorLogs.length > 0)
1002
1021
  await this.#db.engine_grinder_fold_prior_turn_logs.run({ loop_id: loopId, turn_id: turnId });
1003
- const errors = packet.user.telemetry.errors;
1022
+ const errors = packet.telemetryErrors;
1004
1023
  let current = priorLogs.length > 0 ? await rebuild(errors) : packet;
1005
1024
  if (measure(current) <= ceiling) {
1006
1025
  this.#emitBudgetOverflow(sessionId, loopId, folded);
@@ -1037,9 +1056,9 @@ class Engine {
1037
1056
  #completePacket(requestPacket, assistant, assistantRaw, provider) {
1038
1057
  const assistantTokens = provider.countTokens(assistant.content);
1039
1058
  return {
1040
- tokens: requestPacket.system.tokens + requestPacket.user.tokens + assistantTokens,
1041
- system: requestPacket.system,
1042
- user: requestPacket.user,
1059
+ tokens: requestPacket.tokens + assistantTokens,
1060
+ sections: requestPacket.sections,
1061
+ telemetryErrors: requestPacket.telemetryErrors,
1043
1062
  assistant,
1044
1063
  assistantRaw,
1045
1064
  };
@@ -1074,7 +1093,7 @@ class Engine {
1074
1093
  });
1075
1094
  return [...this.#drainTelemetry(loopId), ...actionFailures];
1076
1095
  }
1077
- // SPEC §packet packet.system.log — chronological action-entries for the loop.
1096
+ // SPEC §packet the log section — chronological action-entries for the loop.
1078
1097
  // Snapshot is taken at packet build (pre-dispatch this turn), so it
1079
1098
  // reflects "what has happened before this turn." Each row carries a
1080
1099
  // log:///<loop_seq>/<turn_seq>/<sequence> coordinate the model can READ.
@@ -1404,8 +1423,8 @@ class Engine {
1404
1423
  return (row?.n ?? 0) > 0;
1405
1424
  }
1406
1425
  // Inject a prompt into the run's currently-executing loop. Writes a
1407
- // plurnk:///prompt/<loop_id>/<next-turn> entry whose body becomes
1408
- // packet.user.prompt at the next turn boundary. Last-wins: if two
1426
+ // plurnk:///prompt/<loop_id>/<next-turn> entry whose body becomes the
1427
+ // prompt section at the next turn boundary. Last-wins: if two
1409
1428
  // injects target the same next-turn slot, the second overwrites the
1410
1429
  // first.
1411
1430
  //
@@ -1425,7 +1444,7 @@ class Engine {
1425
1444
  const sessionRow = await this.#db.drain_get_run_session.get({ run_id: runId });
1426
1445
  if (sessionRow === undefined)
1427
1446
  throw new Error(`Engine.inject: run ${runId} not found`);
1428
- const pathname = `prompt/${loopId}/${turnSeq}`;
1447
+ const pathname = `/prompt/${loopId}/${turnSeq}`; // canonical storage form (leading slash), matching the foist via #pathnameOf
1429
1448
  const ctx = {
1430
1449
  db: this.#db, sessionId: sessionRow.session_id, runId, loopId,
1431
1450
  turnId: 0, // no turn open at inject time; entries don't pin turnId
@@ -1955,9 +1974,14 @@ class Engine {
1955
1974
  if (path.kind === "local")
1956
1975
  return { scheme: null, username: null, password: null, hostname: null, port: null, pathname: decodePathParens(path.raw), params: null, fragment: null }; // #239 item 4
1957
1976
  const scheme = path.scheme === "file" ? null : path.scheme;
1977
+ // plurnk uses its authority as a namespace — fold it into the canonical pathname so the
1978
+ // log keys identically to the entry (/prompt/<loop>, /docs/x.md). A web host (http://) is
1979
+ // NOT a namespace: keep it in hostname.
1980
+ const foldNs = scheme === "plurnk";
1958
1981
  return {
1959
1982
  scheme, username: path.username, password: path.password,
1960
- hostname: path.hostname, port: path.port, pathname: decodePathParens(path.pathname), // #239 item 4
1983
+ hostname: foldNs ? null : path.hostname, port: path.port,
1984
+ pathname: decodePathParens(foldNs ? foldAuthorityIntoPath(path.hostname, path.pathname) : path.pathname), // #239 item 4
1961
1985
  params: JSON.stringify(path.params), fragment: path.fragment,
1962
1986
  };
1963
1987
  }