@plurnk/plurnk-service 0.60.0 → 0.62.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 (104) hide show
  1. package/.env.example +54 -16
  2. package/PLURNK_PERSONALITY.md +53 -0
  3. package/SPEC.md +22 -18
  4. package/dist/core/Dispatcher.d.ts +61 -0
  5. package/dist/core/Dispatcher.d.ts.map +1 -0
  6. package/dist/core/Dispatcher.js +811 -0
  7. package/dist/core/Dispatcher.js.map +1 -0
  8. package/dist/core/Engine.d.ts +9 -46
  9. package/dist/core/Engine.d.ts.map +1 -1
  10. package/dist/core/Engine.js +209 -1513
  11. package/dist/core/Engine.js.map +1 -1
  12. package/dist/core/Engine.sql +7 -2
  13. package/dist/core/ExecutorRegistry.d.ts +2 -1
  14. package/dist/core/ExecutorRegistry.d.ts.map +1 -1
  15. package/dist/core/ExecutorRegistry.js +16 -3
  16. package/dist/core/ExecutorRegistry.js.map +1 -1
  17. package/dist/core/PacketBuilder.d.ts +64 -0
  18. package/dist/core/PacketBuilder.d.ts.map +1 -0
  19. package/dist/core/PacketBuilder.js +380 -0
  20. package/dist/core/PacketBuilder.js.map +1 -0
  21. package/dist/core/ProposalLifecycle.d.ts +56 -0
  22. package/dist/core/ProposalLifecycle.d.ts.map +1 -0
  23. package/dist/core/ProposalLifecycle.js +197 -0
  24. package/dist/core/ProposalLifecycle.js.map +1 -0
  25. package/dist/core/SchemeRegistry.d.ts +2 -0
  26. package/dist/core/SchemeRegistry.d.ts.map +1 -1
  27. package/dist/core/SchemeRegistry.js +20 -15
  28. package/dist/core/SchemeRegistry.js.map +1 -1
  29. package/dist/core/StrikeRail.d.ts +27 -0
  30. package/dist/core/StrikeRail.d.ts.map +1 -0
  31. package/dist/core/StrikeRail.js +147 -0
  32. package/dist/core/StrikeRail.js.map +1 -0
  33. package/dist/core/TelemetryChannel.d.ts +37 -0
  34. package/dist/core/TelemetryChannel.d.ts.map +1 -0
  35. package/dist/core/TelemetryChannel.js +77 -0
  36. package/dist/core/TelemetryChannel.js.map +1 -0
  37. package/dist/core/fork.d.ts +1 -0
  38. package/dist/core/fork.d.ts.map +1 -1
  39. package/dist/core/fork.js +17 -4
  40. package/dist/core/fork.js.map +1 -1
  41. package/dist/core/fork.sql +6 -0
  42. package/dist/core/packet-wire.js +1 -1
  43. package/dist/core/packet-wire.js.map +1 -1
  44. package/dist/core/plurnk-uri.d.ts +2 -0
  45. package/dist/core/plurnk-uri.d.ts.map +1 -1
  46. package/dist/core/plurnk-uri.js +11 -0
  47. package/dist/core/plurnk-uri.js.map +1 -1
  48. package/dist/core/run-cap.js +1 -1
  49. package/dist/core/run-cap.js.map +1 -1
  50. package/dist/digest/Digest.d.ts +14 -0
  51. package/dist/digest/Digest.d.ts.map +1 -0
  52. package/dist/digest/Digest.js +321 -0
  53. package/dist/digest/Digest.js.map +1 -0
  54. package/dist/digest/digest.sql +55 -0
  55. package/dist/schemes/Exec.d.ts.map +1 -1
  56. package/dist/schemes/Exec.js +22 -23
  57. package/dist/schemes/Exec.js.map +1 -1
  58. package/dist/schemes/File.d.ts.map +1 -1
  59. package/dist/schemes/File.js +7 -4
  60. package/dist/schemes/File.js.map +1 -1
  61. package/dist/schemes/Log.d.ts.map +1 -1
  62. package/dist/schemes/Log.js +5 -1
  63. package/dist/schemes/Log.js.map +1 -1
  64. package/dist/schemes/Run.js +3 -3
  65. package/dist/schemes/Run.js.map +1 -1
  66. package/dist/server/ClientConnection.d.ts.map +1 -1
  67. package/dist/server/ClientConnection.js +48 -2
  68. package/dist/server/ClientConnection.js.map +1 -1
  69. package/dist/server/Daemon.d.ts +1 -1
  70. package/dist/server/Daemon.d.ts.map +1 -1
  71. package/dist/server/Daemon.js +5 -1
  72. package/dist/server/Daemon.js.map +1 -1
  73. package/dist/server/methods/auth.d.ts +6 -0
  74. package/dist/server/methods/auth.d.ts.map +1 -0
  75. package/dist/server/methods/auth.js +45 -0
  76. package/dist/server/methods/auth.js.map +1 -0
  77. package/dist/server/methods/mcp_install.d.ts +6 -0
  78. package/dist/server/methods/mcp_install.d.ts.map +1 -0
  79. package/dist/server/methods/mcp_install.js +66 -0
  80. package/dist/server/methods/mcp_install.js.map +1 -0
  81. package/dist/server/methods/op_copy.d.ts.map +1 -1
  82. package/dist/server/methods/op_copy.js +1 -0
  83. package/dist/server/methods/op_copy.js.map +1 -1
  84. package/dist/server/methods/op_dispatch.d.ts.map +1 -1
  85. package/dist/server/methods/op_dispatch.js +1 -0
  86. package/dist/server/methods/op_dispatch.js.map +1 -1
  87. package/dist/server/methods/op_edit.d.ts.map +1 -1
  88. package/dist/server/methods/op_edit.js +1 -0
  89. package/dist/server/methods/op_edit.js.map +1 -1
  90. package/dist/server/methods/op_exec.d.ts.map +1 -1
  91. package/dist/server/methods/op_exec.js +1 -0
  92. package/dist/server/methods/op_exec.js.map +1 -1
  93. package/dist/server/methods/op_move.d.ts.map +1 -1
  94. package/dist/server/methods/op_move.js +1 -0
  95. package/dist/server/methods/op_move.js.map +1 -1
  96. package/dist/server/yolo.js +1 -1
  97. package/dist/server/yolo.js.map +1 -1
  98. package/dist/service.d.ts.map +1 -1
  99. package/dist/service.js +31 -2
  100. package/dist/service.js.map +1 -1
  101. package/docs/run.md +7 -3
  102. package/migrations/0000-00-00.01_schema.sql +3 -3
  103. package/package.json +22 -17
  104. package/requirements.md +2 -1
@@ -0,0 +1,197 @@
1
+ import { schemeNameOf } from "./plurnk-uri.js";
2
+ // Resolution timeout — proposed entries auto-cancel if nothing arrives
3
+ // within this window. SPEC.md §engine-rails (proposal lifecycle) + §methods (loop.resolve).
4
+ const PROPOSAL_TIMEOUT_DEFAULT_MS = 300000;
5
+ const readProposalTimeoutMs = () => {
6
+ const raw = process.env.PLURNK_PROPOSAL_TIMEOUT_MS;
7
+ if (raw === undefined || raw.length === 0)
8
+ return PROPOSAL_TIMEOUT_DEFAULT_MS;
9
+ const n = Number(raw);
10
+ if (!Number.isFinite(n) || n <= 0)
11
+ return PROPOSAL_TIMEOUT_DEFAULT_MS;
12
+ return n;
13
+ };
14
+ // The proposal lifecycle (SPEC.md §engine-rails + §methods loop.resolve): a
15
+ // side-effecting op that returns 202 pauses in dispatch until a resolution
16
+ // arrives — from the loop/resolve RPC, the in-tree YOLO listener, or the
17
+ // timeout — then the scheme's applyResolution hook applies the accept.
18
+ export default class ProposalLifecycle {
19
+ #db;
20
+ #schemes;
21
+ #telemetry;
22
+ #streamEventNotify;
23
+ #wakeRunNotify;
24
+ #tokenize;
25
+ // Boot-discovered runtime executors, late-injected on Engine — thunked.
26
+ #executors;
27
+ // Per-loop abort signal, owned by Engine.runLoop — thunked.
28
+ #loopSignal;
29
+ // Proposal lifecycle: pending dispatch pauses waiting for resolution.
30
+ // Dispatch awaits the promise when a scheme returns status 202;
31
+ // Engine.resolveProposal feeds the resolution back in. Map is per-log-
32
+ // entry-id; entries clear on resolution. SPEC.md §engine-rails + §methods (loop.resolve).
33
+ #pending = new Map();
34
+ // External observers of proposal lifecycle events. Daemon subscribes
35
+ // here to push `loop/proposal` notifications when an entry enters
36
+ // pending state. YOLO listener (Phase E.3) subscribes here too. Lean
37
+ // event emitter — no priority, no veto chain at this layer; filter
38
+ // chains come later if a real consumer needs them.
39
+ #listeners = [];
40
+ constructor({ db, schemes, telemetry, streamEventNotify, wakeRunNotify, tokenize, executors, loopSignal }) {
41
+ this.#db = db;
42
+ this.#schemes = schemes;
43
+ this.#telemetry = telemetry;
44
+ this.#streamEventNotify = streamEventNotify;
45
+ this.#wakeRunNotify = wakeRunNotify;
46
+ this.#tokenize = tokenize;
47
+ this.#executors = executors;
48
+ this.#loopSignal = loopSignal;
49
+ }
50
+ // External API to feed a resolution into a pending proposal. Called by
51
+ // the loop/resolve RPC handler (Phase E.2), the in-tree YOLO listener
52
+ // (Phase E.3), or the timeout watcher. Throws when the logEntryId has no
53
+ // pending waiter — duplicate resolutions, IDs for non-proposed entries,
54
+ // or entries already-resolved are caller errors.
55
+ resolve(logEntryId, resolution) {
56
+ const waiter = this.#pending.get(logEntryId);
57
+ if (waiter === undefined) {
58
+ throw new Error(`Engine.resolveProposal: no pending proposal for log_entry ${logEntryId}`);
59
+ }
60
+ clearTimeout(waiter.timeoutHandle);
61
+ this.#pending.delete(logEntryId);
62
+ waiter.resolve(resolution);
63
+ }
64
+ // Snapshot of pending proposals (for diagnostic / RPC listings). Returns
65
+ // the log entry IDs currently awaiting resolution.
66
+ pendingIds() {
67
+ return [...this.#pending.keys()];
68
+ }
69
+ // Subscribe to proposal-pending events. Daemon registers a listener
70
+ // that broadcasts the loop/proposal WS notification; YOLO listener
71
+ // (Phase E.3) registers one that auto-resolves. Listeners fire BEFORE
72
+ // dispatch awaits resolution, so synchronous (or fast-async) handlers
73
+ // can resolve inline.
74
+ onPending(listener) {
75
+ this.#listeners.push(listener);
76
+ }
77
+ notifyPending(event) {
78
+ for (const listener of this.#listeners) {
79
+ try {
80
+ listener(event);
81
+ }
82
+ catch (_) { /* listener errors don't break dispatch */ }
83
+ }
84
+ }
85
+ awaitResolution(logEntryId) {
86
+ const timeoutMs = readProposalTimeoutMs();
87
+ return new Promise((resolve) => {
88
+ const timeoutHandle = setTimeout(() => {
89
+ // Timeout: synthesize a cancel resolution and feed it back
90
+ // through the same path as any other resolution. State
91
+ // transitions to cancelled with outcome='timeout'.
92
+ if (this.#pending.has(logEntryId)) {
93
+ this.#pending.delete(logEntryId);
94
+ resolve({ decision: "cancel", outcome: "timeout" }); // §proposal-timeout-cancels
95
+ }
96
+ }, timeoutMs);
97
+ this.#pending.set(logEntryId, { resolve, timeoutHandle });
98
+ });
99
+ }
100
+ // On accept, run the scheme's applyResolution — File writes disk, Exec spawns. §proposal-accept-applies
101
+ async runApply(statement, originalResult, resolution, ids) {
102
+ const { sessionId, runId, loopId, turnId } = ids;
103
+ if (resolution.decision !== "accept")
104
+ return resolution;
105
+ // EXEC routes to the exec scheme regardless of target (cwd, not
106
+ // a scheme address). All other ops resolve their handler from
107
+ // statement.target's scheme.
108
+ // COPY/MOVE write the DEST (statement.body), not the source (target): the
109
+ // accept must reach the dest scheme's applyResolution (File writes disk).
110
+ const schemeName = statement.op === "EXEC" ? "exec"
111
+ : (statement.op === "COPY" || statement.op === "MOVE") ? schemeNameOf(statement.body)
112
+ : schemeNameOf(statement.target);
113
+ if (schemeName === null)
114
+ return resolution;
115
+ const handler = this.#schemes.get(schemeName);
116
+ if (handler === undefined || typeof handler.applyResolution !== "function")
117
+ return resolution;
118
+ try {
119
+ // Build a ctx for the scheme's applyResolution. The proposal
120
+ // was raised inside a specific (session, run, loop, turn);
121
+ // the scheme uses ctx to write the entry that makes the
122
+ // operation's artifact visible in the next packet's index.
123
+ const applyCtx = {
124
+ db: this.#db, sessionId, runId, loopId, turnId,
125
+ writer: "model", signal: this.#loopSignal(loopId),
126
+ streamEventNotify: this.#streamEventNotify,
127
+ wakeRunNotify: this.#wakeRunNotify,
128
+ tokenize: this.#tokenize,
129
+ pushTelemetry: (event) => this.#telemetry.push(sessionId, loopId, event),
130
+ executors: this.#executors(),
131
+ };
132
+ const applyResult = await handler.applyResolution({
133
+ attrs: (originalResult.attrs ?? {}),
134
+ body: resolution.body,
135
+ }, applyCtx);
136
+ if (applyResult.status >= 400) {
137
+ return {
138
+ decision: "reject",
139
+ outcome: applyResult.outcome ?? "apply_failed",
140
+ body: applyResult.body,
141
+ };
142
+ }
143
+ // Propagate applyResolution.outcome onto the accepted resolution
144
+ // (operational metadata, e.g. exec's "exit_N") AND its body — an
145
+ // inline (read/pure) run returns its output as the body, which has
146
+ // to reach the model-facing result this turn, not just stream to
147
+ // the entry. Host accepts carry no body (fire-and-forget).
148
+ const withOutcome = applyResult.outcome !== undefined && resolution.outcome === undefined
149
+ ? { ...resolution, outcome: applyResult.outcome }
150
+ : resolution;
151
+ return applyResult.body === undefined ? withOutcome : { ...withOutcome, body: applyResult.body };
152
+ }
153
+ catch (err) {
154
+ return {
155
+ decision: "reject",
156
+ outcome: "apply_threw",
157
+ body: err instanceof Error ? err.message : String(err),
158
+ };
159
+ }
160
+ }
161
+ async applyResolution(logEntryId, resolution) {
162
+ // Map decision → terminal state + HTTP-aligned status:
163
+ // accept → state='resolved', status=200
164
+ // reject → state='failed', status=400, outcome='rejected' (default) §proposal-reject-fails
165
+ // cancel → state='cancelled',status=499, outcome='loop_aborted' (default) §proposal-cancel-aborts
166
+ // resolution.outcome wins over the default when supplied; this is how
167
+ // veto filters (Phase E.2 proposal.accepting) can specify a more
168
+ // precise outcome string like 'policy_veto' or 'timeout'.
169
+ const decision = resolution.decision;
170
+ const state = decision === "accept" ? "resolved"
171
+ : decision === "reject" ? "failed"
172
+ : "cancelled";
173
+ const status = decision === "accept" ? 200
174
+ : decision === "reject" ? 400
175
+ : 499;
176
+ const defaultOutcome = decision === "accept" ? null
177
+ : decision === "reject" ? "rejected"
178
+ : "loop_aborted";
179
+ const outcome = resolution.outcome ?? defaultOutcome;
180
+ // rx is the model-facing operation result. Status always. Body is normally dropped —
181
+ // the propose preview was an input echo — EXCEPT an inline auto-run (read/pure) carries
182
+ // its run output AS the body, the "what happened" the model needs this turn. A non-accept
183
+ // carries the outcome TOKEN as its terse error (write_failed / rejected / timeout — one
184
+ // word, never prose): a bare {"status":400} left the model blind to a mechanically failed
185
+ // apply and parking on a phantom worker (the fan-out digest).
186
+ const rx = (decision === "accept" && resolution.body !== undefined)
187
+ ? JSON.stringify({ status, body: resolution.body })
188
+ : decision === "accept"
189
+ ? JSON.stringify({ status })
190
+ : JSON.stringify({ status, error: outcome });
191
+ await this.#db.engine_resolve_log_entry.run({
192
+ id: logEntryId, state, outcome, status_rx: status, rx,
193
+ });
194
+ return { status, outcome, body: resolution.body };
195
+ }
196
+ }
197
+ //# sourceMappingURL=ProposalLifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProposalLifecycle.js","sourceRoot":"","sources":["../../src/core/ProposalLifecycle.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,13 @@
1
1
  import type { LoopFlags } from "./types.ts";
2
2
  import type { PacketSection } from "./packet-wire.ts";
3
3
  import type ExecutorRegistry from "./ExecutorRegistry.ts";
4
+ import type { Executor } from "./ExecutorRegistry.ts";
4
5
  export default class SchemeRegistry {
5
6
  #private;
6
7
  constructor();
7
8
  register(name: string, handler: object): void;
8
9
  registerRuntimeSchemes(executors: ExecutorRegistry): void;
10
+ registerRuntimeScheme(tag: string, executor: Executor): void;
9
11
  get(name: string): object | undefined;
10
12
  has(name: string): boolean;
11
13
  isExternal(name: string): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"SchemeRegistry.d.ts","sourceRoot":"","sources":["../../src/core/SchemeRegistry.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAItD,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAC;AAiB1D,MAAM,CAAC,OAAO,OAAO,cAAc;;;IA6B/B,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAU7C,sBAAsB,CAAC,SAAS,EAAE,gBAAgB,GAAG,IAAI;IAiBzD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAErC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAEjC,IAAI,IAAI,MAAM,EAAE;IAIhB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM;IAehD,KAAK,IAAI,MAAM;IAgBf,IAAI,IAAI,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAkB1C,iBAAiB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAiBtE,gBAAgB,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBlE,YAAY,IAAI,MAAM,EAAE;IAIxB,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC;CAGhD"}
1
+ {"version":3,"file":"SchemeRegistry.d.ts","sourceRoot":"","sources":["../../src/core/SchemeRegistry.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAItD,OAAO,KAAK,gBAAgB,MAAM,uBAAuB,CAAC;AAC1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAiBtD,MAAM,CAAC,OAAO,OAAO,cAAc;;;IA6B/B,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAU7C,sBAAsB,CAAC,SAAS,EAAE,gBAAgB,GAAG,IAAI;IAazD,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAU5D,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAErC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAEjC,IAAI,IAAI,MAAM,EAAE;IAIhB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM;IAehD,KAAK,IAAI,MAAM;IAgBf,IAAI,IAAI,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAkB1C,iBAAiB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAiBtE,gBAAgB,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBlE,YAAY,IAAI,MAAM,EAAE;IAIxB,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC;CAGhD"}
@@ -38,7 +38,7 @@ const SCHEME_DOCS = await (async () => {
38
38
  export default class SchemeRegistry {
39
39
  // Heterogeneous handler store — in-tree schemes take PlurnkSchemeContext, external
40
40
  // siblings the DB-free SchemeCtx of the imported SchemeHandler; the common supertype
41
- // is `object`. Dispatch (Engine.#run) borrows SchemeHandler's op-key set, not its ctx.
41
+ // is `object`. Dispatch (Dispatcher.#run) borrows SchemeHandler's op-key set, not its ctx.
42
42
  #handlers = new Map();
43
43
  #external = new Set();
44
44
  #attributions = []; // #249 — declared attribution tags of discovered external schemes
@@ -73,26 +73,31 @@ export default class SchemeRegistry {
73
73
  // delegated to the shared Exec handler. Minted from the boot ExecutorRegistry; in-tree
74
74
  // names take precedence (a tag shadowing a built-in is skipped, never overrides it).
75
75
  registerRuntimeSchemes(executors) {
76
- const exec = this.#handlers.get("exec");
77
- if (!(exec instanceof Exec))
78
- throw new Error("registerRuntimeSchemes: the exec handler is not registered");
79
76
  for (const tag of executors.availableRuntimes()) {
80
- if (this.#reserved.has(tag))
81
- throw new Error(`executor tag '${tag}' collides with a reserved built-in scheme — boot fail-hard (#240)`);
82
- if (this.#runtimeSchemes.has(tag))
83
- continue; // idempotent re-scan — already this tag's own runtime scheme
84
- // #240 cross-family namespace: a tag already claimed by a DIFFERENT scheme (an external
85
- // scheme sibling) is a collision, not a re-scan — one name, one owner across the exec and
86
- // scheme families. Fail the boot hard rather than silently first-wins-skipping the tag.
87
- if (this.#handlers.has(tag))
88
- throw new Error(`executor tag '${tag}' collides with an already-claimed scheme '${tag}' — one name, one owner across the exec/scheme families (#240)`);
89
77
  const entry = executors.entry(tag);
90
78
  if (entry === undefined)
91
79
  continue;
92
- this.register(tag, new ExecOutputScheme(entry.executor, exec));
93
- this.#runtimeSchemes.add(tag);
80
+ this.registerRuntimeScheme(tag, entry.executor);
94
81
  }
95
82
  }
83
+ // Register ONE executor tag's scheme face (the boot loop above + the #289 runtime hotload:
84
+ // an MCP server connected live becomes EXEC[<server>]). The reserved/cross-family arbitration
85
+ // lives HERE so both paths share it — one name, one owner across the exec/scheme families (#240):
86
+ // idempotent on a tag that already has its own runtime scheme (a boot re-scan), fail-hard on a
87
+ // collision with a reserved built-in or a DIFFERENT already-claimed scheme.
88
+ registerRuntimeScheme(tag, executor) {
89
+ const exec = this.#handlers.get("exec");
90
+ if (!(exec instanceof Exec))
91
+ throw new Error("registerRuntimeScheme: the exec handler is not registered");
92
+ if (this.#reserved.has(tag))
93
+ throw new Error(`executor tag '${tag}' collides with a reserved built-in scheme — fail-hard (#240)`);
94
+ if (this.#runtimeSchemes.has(tag))
95
+ return; // idempotent — already this tag's own runtime scheme
96
+ if (this.#handlers.has(tag))
97
+ throw new Error(`executor tag '${tag}' collides with an already-claimed scheme '${tag}' — one name, one owner across the exec/scheme families (#240)`);
98
+ this.register(tag, new ExecOutputScheme(executor, exec));
99
+ this.#runtimeSchemes.add(tag);
100
+ }
96
101
  get(name) { return this.#handlers.get(name); }
97
102
  has(name) { return this.#handlers.has(name); }
98
103
  // True for schemes registered via discoverExternal — they receive the
@@ -1 +1 @@
1
- {"version":3,"file":"SchemeRegistry.js","sourceRoot":"","sources":["../../src/core/SchemeRegistry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SchemeRegistry.js","sourceRoot":"","sources":["../../src/core/SchemeRegistry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { PlurnkStatement } from "@plurnk/plurnk-grammar";
2
+ export default class StrikeRail {
3
+ #private;
4
+ static fingerprintTurn(ops: ReadonlyArray<PlurnkStatement>): string;
5
+ static detectCycle(history: ReadonlyArray<string>, minCycles: number, maxCyclePeriod: number): {
6
+ detected: false;
7
+ } | {
8
+ detected: true;
9
+ period: number;
10
+ cycles: number;
11
+ };
12
+ assess(loopId: number, turn: {
13
+ fingerprint: string;
14
+ statuses: ReadonlyArray<number>;
15
+ noOps: boolean;
16
+ budgetStruck: boolean;
17
+ steerStruck: boolean;
18
+ minCycles: number;
19
+ maxCyclePeriod: number;
20
+ maxStrikes: number;
21
+ }): {
22
+ cycleDetected: boolean;
23
+ thresholdCrossed: boolean;
24
+ };
25
+ delete(loopId: number): void;
26
+ }
27
+ //# sourceMappingURL=StrikeRail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StrikeRail.d.ts","sourceRoot":"","sources":["../../src/core/StrikeRail.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAc,MAAM,wBAAwB,CAAC;AAmE1E,MAAM,CAAC,OAAO,OAAO,UAAU;;IAG3B,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,aAAa,CAAC,eAAe,CAAC,GAAG,MAAM;IAQnE,MAAM,CAAC,WAAW,CACd,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,EAC9B,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,GACvB;QAAE,QAAQ,EAAE,KAAK,CAAA;KAAE,GAAG;QAAE,QAAQ,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IA+B3E,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE;QACzB,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QAChC,KAAK,EAAE,OAAO,CAAC;QACf,YAAY,EAAE,OAAO,CAAC;QACtB,WAAW,EAAE,OAAO,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,MAAM,CAAC;KACtB,GAAG;QAAE,aAAa,EAAE,OAAO,CAAC;QAAC,gBAAgB,EAAE,OAAO,CAAA;KAAE;IA8BzD,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAG/B"}
@@ -0,0 +1,147 @@
1
+ // Rail #38: action-entry statuses that DON'T accumulate strikes. Model adapted
2
+ // to a finding (not_found, op_not_supported); no penalty. Rummy parallel:
3
+ // SOFT_FAILURE_OUTCOMES = {"not_found", "unparsed"}.
4
+ const SOFT_FAILURE_STATUSES = new Set([404, 501]);
5
+ // Per-op fingerprint: op verb + target URI, plus an op-specific discriminator
6
+ // where the activity isn't fully captured by target alone:
7
+ // - EDIT/COPY/MOVE: body excluded — re-writing the same target with varied
8
+ // content IS cycling (the model is producing different versions of the
9
+ // same artifact instead of progressing).
10
+ // - FIND/READ/OPEN/FOLD: body IS the search/selection pattern; varied
11
+ // matchers on the same target ARE different activities (the model is
12
+ // exploring different queries, not repeating one).
13
+ const fingerprintOp = (stmt) => {
14
+ const path = stmt.target;
15
+ const matcherDiscriminator = () => {
16
+ // For matcher-bearing ops, the body's `raw` (matcher source) plus
17
+ // any lineMarker forms the activity discriminator.
18
+ const parts = [];
19
+ const body = stmt.body;
20
+ if (body !== null && typeof body === "object" && typeof body.raw === "string") {
21
+ parts.push(`body:${body.raw.slice(0, 64)}`);
22
+ }
23
+ const lm = stmt.lineMarker;
24
+ if (lm !== null && lm !== undefined)
25
+ parts.push(`L:${lm.marks.join(",")}`);
26
+ return parts.length > 0 ? `|${parts.join("|")}` : "";
27
+ };
28
+ if (path === null) {
29
+ // Path-less ops need an activity-defining discriminator other
30
+ // than `target`. Picked per op so the cycle detector reflects
31
+ // intent rather than syntax:
32
+ // - EXEC: the command body IS the activity. Without a body
33
+ // digest, varied shell commands (find / ls / wc) collapse to
34
+ // one fingerprint and the detector mislabels exploration
35
+ // as a loop.
36
+ // - SEND: the status code (signal) IS the activity. Different
37
+ // SEND[X] are different intentions; same SEND[X] with
38
+ // different message bodies is the same termination signal.
39
+ if (stmt.op === "EXEC") {
40
+ const body = typeof stmt.body === "string" ? stmt.body : "";
41
+ return `EXEC|(no-path)${body.length > 0 ? `|body:${body.slice(0, 64)}` : ""}`;
42
+ }
43
+ if (stmt.op === "SEND") {
44
+ const signal = typeof stmt.signal === "number" ? stmt.signal : "";
45
+ return `SEND|(no-path)|signal:${signal}`;
46
+ }
47
+ return `${stmt.op}|(no-path)`;
48
+ }
49
+ const base = path.kind === "url"
50
+ ? `${stmt.op}|${path.scheme}://${path.pathname}`
51
+ : `${stmt.op}|local:${path.raw}`;
52
+ if (stmt.op === "FIND" || stmt.op === "READ" || stmt.op === "OPEN" || stmt.op === "FOLD") {
53
+ return `${base}${matcherDiscriminator()}`;
54
+ }
55
+ return base;
56
+ };
57
+ // Rails #38 (strikes) + #39 (cycle detection): the per-loop failure-streak
58
+ // accounting that decides abandonment. Strike accounting is engine-internal
59
+ // bookkeeping. Per rummy precedent (plugins/error/error.js#verdict) and SPEC
60
+ // §telemetry policy: model sees errors that happened (parse_error,
61
+ // action_failure), never the engine's accounting about them (strike counts,
62
+ // cycle detection, sudden-death threshold). Surfacing internal state to the
63
+ // model creates a gamification surface — model optimizes for engine metrics
64
+ // rather than task progress.
65
+ export default class StrikeRail {
66
+ // Per-turn fingerprint: sorted set of per-op fingerprints, joined. Order
67
+ // within a turn doesn't matter — we want the SET of activities.
68
+ static fingerprintTurn(ops) {
69
+ return ops.map(fingerprintOp).toSorted().join(",");
70
+ }
71
+ // Rail #39 cycle detector. For each candidate period k in [1, maxCyclePeriod],
72
+ // check whether the last k*minCycles entries form minCycles repetitions of the
73
+ // same length-k pattern. O(maxCyclePeriod × minCycles × max k) ≈ tiny. Rummy
74
+ // parallel: src/plugins/error/error.js detectCycle.
75
+ static detectCycle(history, minCycles, maxCyclePeriod) {
76
+ for (let k = 1; k <= maxCyclePeriod; k++) {
77
+ const needed = k * minCycles;
78
+ if (history.length < needed)
79
+ continue;
80
+ const tail = history.slice(-needed);
81
+ const cycle = tail.slice(0, k);
82
+ let match = true;
83
+ outer: for (let rep = 0; rep < minCycles; rep++) {
84
+ for (let j = 0; j < k; j++) {
85
+ if (tail[rep * k + j] !== cycle[j]) {
86
+ match = false;
87
+ break outer;
88
+ }
89
+ }
90
+ }
91
+ if (match)
92
+ return { detected: true, period: k, cycles: minCycles };
93
+ }
94
+ return { detected: false };
95
+ }
96
+ // Rail #38 strike state per loop. `streak` = consecutive struck turns;
97
+ // resets on a clean turn. `turnErrors` is bumped by per-turn rails (cycle
98
+ // detection #39, grinder, steer) — read and reset at end of each turn.
99
+ // `history` holds per-turn fingerprints for rail #39 cycle detection.
100
+ #state = new Map();
101
+ // Per-turn strike accounting, run by runLoop after every turn. Three
102
+ // sources strike a turn:
103
+ // 1. recordedFailed — any action-entry at hard failure status
104
+ // (>= 400 and not in SOFT_FAILURE_STATUSES).
105
+ // 2. noOps — the turn emitted no ops at all (per #41).
106
+ // 3. turnErrors — bumped by per-turn rails (#39 cycle, grinder, steer).
107
+ // Struck → streak++; clean → streak = 0. Threshold → thresholdCrossed,
108
+ // and runLoop owns the abandonment.
109
+ assess(loopId, turn) {
110
+ // Rail #39: cycle detection. Push this turn's fingerprint to
111
+ // history, scan for repetition patterns. Detection bumps
112
+ // turnErrors so the strike system handles abandonment
113
+ // naturally — same internal-only role rummy gave it
114
+ // (plugins/error/error.js#verdict). Intentionally NOT a
115
+ // model-facing telemetry kind: model sees the strike pile-up
116
+ // (which IS the actionable signal); cycle is the engine's
117
+ // reason for treating the turn as a failure, not its own alert.
118
+ const state = this.#state.get(loopId) ?? { streak: 0, turnErrors: 0, history: [] };
119
+ state.history.push(turn.fingerprint);
120
+ const cycle = StrikeRail.detectCycle(state.history, turn.minCycles, turn.maxCyclePeriod);
121
+ if (cycle.detected)
122
+ state.turnErrors++;
123
+ // SPEC §grinder: a non-soft grinder fire counts toward the strike streak.
124
+ if (turn.budgetStruck)
125
+ state.turnErrors++; // a grinder fire bumps the strike streak — §grinder-strike-coupling
126
+ if (turn.steerStruck)
127
+ state.turnErrors++; // idle / premature-terminate steer struck — §send the terminal contract
128
+ const recordedFailed = turn.statuses.some((s) => s >= 400 && !SOFT_FAILURE_STATUSES.has(s));
129
+ const struck = turn.noOps || recordedFailed || state.turnErrors > 0;
130
+ let thresholdCrossed = false;
131
+ if (struck) {
132
+ state.streak++;
133
+ if (state.streak >= turn.maxStrikes)
134
+ thresholdCrossed = true;
135
+ }
136
+ else {
137
+ state.streak = 0;
138
+ }
139
+ state.turnErrors = 0;
140
+ this.#state.set(loopId, state);
141
+ return { cycleDetected: cycle.detected, thresholdCrossed };
142
+ }
143
+ delete(loopId) {
144
+ this.#state.delete(loopId);
145
+ }
146
+ }
147
+ //# sourceMappingURL=StrikeRail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StrikeRail.js","sourceRoot":"","sources":["../../src/core/StrikeRail.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { TelemetryEvent } from "@plurnk/plurnk-grammar";
2
+ import type { Db } from "./Db.ts";
3
+ import type { TelemetryEventNotify } from "./ChannelWrite.ts";
4
+ declare const ENGINE_ERRORS: Readonly<{
5
+ readonly budget_overflow: {
6
+ readonly status: 413;
7
+ readonly term: "Budget Overflow: newest log items automatically FOLDed";
8
+ };
9
+ readonly max_commands_exceeded: {
10
+ readonly status: 429;
11
+ readonly term: "Max Commands Exceeded";
12
+ };
13
+ readonly idle_turn: {
14
+ readonly status: 409;
15
+ readonly term: "Idle Turn";
16
+ };
17
+ }>;
18
+ export type EngineErrorKind = keyof typeof ENGINE_ERRORS;
19
+ export default class TelemetryChannel {
20
+ #private;
21
+ constructor({ db, notify }: {
22
+ db: Db;
23
+ notify?: TelemetryEventNotify;
24
+ });
25
+ push(sessionId: number, loopId: number, event: TelemetryEvent): void;
26
+ notify(sessionId: number, loopId: number, event: TelemetryEvent): void;
27
+ drain(loopId: number): object[];
28
+ delete(loopId: number): void;
29
+ mintEngineError(kind: EngineErrorKind, { runId, loopId, turnId, sequence }: {
30
+ runId: number;
31
+ loopId: number;
32
+ turnId: number;
33
+ sequence: number;
34
+ }): Promise<void>;
35
+ }
36
+ export {};
37
+ //# sourceMappingURL=TelemetryChannel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TelemetryChannel.d.ts","sourceRoot":"","sources":["../../src/core/TelemetryChannel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,EAAE,EAAc,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAM9D,QAAA,MAAM,aAAa;;;;;;;;;;;;;EAOR,CAAC;AACZ,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,aAAa,CAAC;AAKzD,MAAM,CAAC,OAAO,OAAO,gBAAgB;;gBAarB,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE;QAAE,EAAE,EAAE,EAAE,CAAC;QAAC,MAAM,CAAC,EAAE,oBAAoB,CAAA;KAAE;IAKrE,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI;IAYpE,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI;IAKtE,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAO/B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQtB,eAAe,CAAC,IAAI,EAAE,eAAe,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAaxK"}
@@ -0,0 +1,77 @@
1
+ // §telemetry — the uniform error channel. Every engine failure is a terse op='error'
2
+ // log row: a status code + the canonical term, no prose (the packet teaches recovery).
3
+ // Each surfaces as a LogCoordinate TelemetryEvent derived from log≥400 — one channel,
4
+ // no per-kind handling. {§telemetry-uniform-error-channel}
5
+ const ENGINE_ERRORS = Object.freeze({
6
+ budget_overflow: { status: 413, term: "Budget Overflow: newest log items automatically FOLDed" },
7
+ max_commands_exceeded: { status: 429, term: "Max Commands Exceeded" },
8
+ // premature-terminate is NOT a terse engine-error: it's a SEND op-result (409 + an actionable
9
+ // outcome, §send-premature-terminate) — the SEND row records the [200] attempt faithfully and
10
+ // auto-surfaces (status≥400) like any op failure, never an erasure to 102.
11
+ idle_turn: { status: 409, term: "Idle Turn" },
12
+ });
13
+ // The model-facing alert channel: a per-loop transient buffer of actionless failures
14
+ // pending surface in the NEXT packet's user.telemetry.errors[], plus the live client
15
+ // fan-out and the uniform op='error' log-row mint. SPEC §telemetry.
16
+ export default class TelemetryChannel {
17
+ #db;
18
+ // Per-loop transient buffer of actionless failures pending surface in the
19
+ // NEXT packet's user.telemetry.errors[]. Drained by PacketBuilder.buildTelemetryErrors.
20
+ // Map<loopId, TelemetryError[]>. SPEC §telemetry.
21
+ #buffer = new Map();
22
+ // Telemetry event fan-out: every TelemetryEvent pushed to the loop's
23
+ // buffer is also broadcast live to the connected client(s) on the
24
+ // session. Without this, the client sees `loop/terminated` with a
25
+ // status code but has no way to surface why the loop degraded.
26
+ // Per-grammar 0.17.0 protocol — see SPEC §telemetry.
27
+ #notify;
28
+ constructor({ db, notify }) {
29
+ this.#db = db;
30
+ this.#notify = notify;
31
+ }
32
+ push(sessionId, loopId, event) {
33
+ const existing = this.#buffer.get(loopId);
34
+ if (existing === undefined)
35
+ this.#buffer.set(loopId, [event]);
36
+ else
37
+ existing.push(event);
38
+ // Live fan-out: client sees the event the moment it lands in the
39
+ // model's buffer (not at the next packet build). Same envelope on
40
+ // both sides per the grammar 0.17.0 TelemetryEvent protocol.
41
+ this.#notify?.(sessionId, { loopId, event });
42
+ }
43
+ // Live fan-out ONLY, never buffered — for work with no loop to drain the
44
+ // buffer (e.g. session-scope derivation warming, loopId 0).
45
+ notify(sessionId, loopId, event) {
46
+ this.#notify?.(sessionId, { loopId, event });
47
+ }
48
+ // Telemetry drains as it's read into the packet — each event surfaces once. §telemetry-drain-on-read
49
+ drain(loopId) {
50
+ const buf = this.#buffer.get(loopId);
51
+ if (buf === undefined)
52
+ return [];
53
+ this.#buffer.delete(loopId);
54
+ return buf;
55
+ }
56
+ delete(loopId) {
57
+ this.#buffer.delete(loopId);
58
+ }
59
+ // Mint an engine failure as a uniform op='error' log row (§telemetry-uniform-error-channel):
60
+ // a terse status + canonical term keyed by `kind` (the packet teaches recovery, not the row),
61
+ // origin engine:rail. The errors section derives its LogCoordinate pointer from log≥400 — one
62
+ // channel, no per-kind handling.
63
+ async mintEngineError(kind, { runId, loopId, turnId, sequence }) {
64
+ const { status, term } = ENGINE_ERRORS[kind];
65
+ await this.#db.engine_insert_log_entry.get({
66
+ run_id: runId, loop_id: loopId, turn_id: turnId, sequence,
67
+ origin: "plurnk", source: "rail", op: "error", suffix: "", signal: null,
68
+ scheme: null, username: null, password: null, hostname: null, port: null,
69
+ pathname: null, params: null, fragment: null, lineMarker: null,
70
+ tx: "", mimetype_tx: "text/plain",
71
+ rx: JSON.stringify({ kind, message: term }),
72
+ mimetype_rx: "application/json",
73
+ status_rx: status, tokens: 0, state: "resolved", outcome: null, attrs: "{}",
74
+ });
75
+ }
76
+ }
77
+ //# sourceMappingURL=TelemetryChannel.js.map