opensquid 0.5.407 → 0.5.426

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 (154) hide show
  1. package/dist/cli.js +5 -4
  2. package/dist/cli.js.map +1 -1
  3. package/dist/functions/event.d.ts.map +1 -1
  4. package/dist/functions/event.js +30 -0
  5. package/dist/functions/event.js.map +1 -1
  6. package/dist/functions/handoff_session_start.d.ts.map +1 -1
  7. package/dist/functions/handoff_session_start.js +4 -6
  8. package/dist/functions/handoff_session_start.js.map +1 -1
  9. package/dist/functions/index.d.ts +4 -0
  10. package/dist/functions/index.d.ts.map +1 -1
  11. package/dist/functions/index.js +5 -0
  12. package/dist/functions/index.js.map +1 -1
  13. package/dist/functions/read_rubric.d.ts +27 -0
  14. package/dist/functions/read_rubric.d.ts.map +1 -0
  15. package/dist/functions/read_rubric.js +53 -0
  16. package/dist/functions/read_rubric.js.map +1 -0
  17. package/dist/functions/reset_scope_track_state.d.ts +20 -0
  18. package/dist/functions/reset_scope_track_state.d.ts.map +1 -0
  19. package/dist/functions/reset_scope_track_state.js +53 -0
  20. package/dist/functions/reset_scope_track_state.js.map +1 -0
  21. package/dist/functions/rubric_pre_inject.d.ts +22 -0
  22. package/dist/functions/rubric_pre_inject.d.ts.map +1 -0
  23. package/dist/functions/rubric_pre_inject.js +58 -0
  24. package/dist/functions/rubric_pre_inject.js.map +1 -0
  25. package/dist/functions/session_tool_history.d.ts +3 -3
  26. package/dist/functions/session_tool_history.js +1 -1
  27. package/dist/functions/session_tool_history.js.map +1 -1
  28. package/dist/functions/shell_parse.d.ts +41 -0
  29. package/dist/functions/shell_parse.d.ts.map +1 -0
  30. package/dist/functions/shell_parse.js +185 -0
  31. package/dist/functions/shell_parse.js.map +1 -0
  32. package/dist/functions/staged_docs_only.d.ts +23 -0
  33. package/dist/functions/staged_docs_only.d.ts.map +1 -0
  34. package/dist/functions/staged_docs_only.js +57 -0
  35. package/dist/functions/staged_docs_only.js.map +1 -0
  36. package/dist/mcp/server.js +14 -1
  37. package/dist/mcp/server.js.map +1 -1
  38. package/dist/mcp/tools/ralph.d.ts +21 -0
  39. package/dist/mcp/tools/ralph.d.ts.map +1 -0
  40. package/dist/mcp/tools/ralph.js +18 -0
  41. package/dist/mcp/tools/ralph.js.map +1 -0
  42. package/dist/mcp/tools/workgraph.d.ts +11 -0
  43. package/dist/mcp/tools/workgraph.d.ts.map +1 -1
  44. package/dist/mcp/tools/workgraph.js +7 -0
  45. package/dist/mcp/tools/workgraph.js.map +1 -1
  46. package/dist/rag/backend_factory.d.ts.map +1 -1
  47. package/dist/rag/backend_factory.js +4 -0
  48. package/dist/rag/backend_factory.js.map +1 -1
  49. package/dist/rag/backends/libsql_lexical.d.ts.map +1 -1
  50. package/dist/rag/backends/libsql_lexical.js +21 -5
  51. package/dist/rag/backends/libsql_lexical.js.map +1 -1
  52. package/dist/rag/backends/libsql_store.d.ts.map +1 -1
  53. package/dist/rag/backends/libsql_store.js +33 -6
  54. package/dist/rag/backends/libsql_store.js.map +1 -1
  55. package/dist/rag/backends/perfile_source.d.ts.map +1 -1
  56. package/dist/rag/backends/perfile_source.js +3 -0
  57. package/dist/rag/backends/perfile_source.js.map +1 -1
  58. package/dist/rag/memory/consolidate.d.ts +3 -2
  59. package/dist/rag/memory/consolidate.d.ts.map +1 -1
  60. package/dist/rag/memory/consolidate.js +7 -4
  61. package/dist/rag/memory/consolidate.js.map +1 -1
  62. package/dist/rag/types.d.ts +2 -0
  63. package/dist/rag/types.d.ts.map +1 -1
  64. package/dist/rag/types.js.map +1 -1
  65. package/dist/runtime/bootstrap.d.ts.map +1 -1
  66. package/dist/runtime/bootstrap.js +8 -0
  67. package/dist/runtime/bootstrap.js.map +1 -1
  68. package/dist/runtime/coding_flow_keys.d.ts +17 -0
  69. package/dist/runtime/coding_flow_keys.d.ts.map +1 -0
  70. package/dist/runtime/coding_flow_keys.js +21 -0
  71. package/dist/runtime/coding_flow_keys.js.map +1 -0
  72. package/dist/runtime/handoff/collect.d.ts.map +1 -1
  73. package/dist/runtime/handoff/collect.js +3 -1
  74. package/dist/runtime/handoff/collect.js.map +1 -1
  75. package/dist/runtime/hooks/session-start.js +5 -1
  76. package/dist/runtime/hooks/session-start.js.map +1 -1
  77. package/dist/runtime/hooks/session_id.d.ts +7 -0
  78. package/dist/runtime/hooks/session_id.d.ts.map +1 -1
  79. package/dist/runtime/hooks/session_id.js +30 -12
  80. package/dist/runtime/hooks/session_id.js.map +1 -1
  81. package/dist/runtime/protected_paths.d.ts +18 -0
  82. package/dist/runtime/protected_paths.d.ts.map +1 -0
  83. package/dist/runtime/protected_paths.js +18 -0
  84. package/dist/runtime/protected_paths.js.map +1 -0
  85. package/dist/runtime/ralph/decision_classifier.d.ts +18 -0
  86. package/dist/runtime/ralph/decision_classifier.d.ts.map +1 -0
  87. package/dist/runtime/ralph/decision_classifier.js +72 -0
  88. package/dist/runtime/ralph/decision_classifier.js.map +1 -0
  89. package/dist/runtime/ralph/escalate_lap.d.ts +31 -0
  90. package/dist/runtime/ralph/escalate_lap.d.ts.map +1 -0
  91. package/dist/runtime/ralph/escalate_lap.js +22 -0
  92. package/dist/runtime/ralph/escalate_lap.js.map +1 -0
  93. package/dist/runtime/ralph/escalator.d.ts +34 -0
  94. package/dist/runtime/ralph/escalator.d.ts.map +1 -0
  95. package/dist/runtime/ralph/escalator.js +19 -0
  96. package/dist/runtime/ralph/escalator.js.map +1 -0
  97. package/dist/runtime/ralph/lap_outcome.d.ts +43 -0
  98. package/dist/runtime/ralph/lap_outcome.d.ts.map +1 -0
  99. package/dist/runtime/ralph/lap_outcome.js +119 -0
  100. package/dist/runtime/ralph/lap_outcome.js.map +1 -0
  101. package/dist/runtime/ralph/orchestrator.d.ts +71 -0
  102. package/dist/runtime/ralph/orchestrator.d.ts.map +1 -0
  103. package/dist/runtime/ralph/orchestrator.js +74 -0
  104. package/dist/runtime/ralph/orchestrator.js.map +1 -0
  105. package/dist/runtime/ralph/ralph_template.d.ts +18 -0
  106. package/dist/runtime/ralph/ralph_template.d.ts.map +1 -0
  107. package/dist/runtime/ralph/ralph_template.js +61 -0
  108. package/dist/runtime/ralph/ralph_template.js.map +1 -0
  109. package/dist/runtime/ralph/supervisor.d.ts +30 -0
  110. package/dist/runtime/ralph/supervisor.d.ts.map +1 -0
  111. package/dist/runtime/ralph/supervisor.js +24 -0
  112. package/dist/runtime/ralph/supervisor.js.map +1 -0
  113. package/dist/runtime/session_state.d.ts +9 -1
  114. package/dist/runtime/session_state.d.ts.map +1 -1
  115. package/dist/runtime/session_state.js +25 -3
  116. package/dist/runtime/session_state.js.map +1 -1
  117. package/dist/runtime/wedge/compression_deps.d.ts.map +1 -1
  118. package/dist/runtime/wedge/compression_deps.js +9 -1
  119. package/dist/runtime/wedge/compression_deps.js.map +1 -1
  120. package/dist/setup/cli/gate.d.ts +7 -2
  121. package/dist/setup/cli/gate.d.ts.map +1 -1
  122. package/dist/setup/cli/gate.js +7 -3
  123. package/dist/setup/cli/gate.js.map +1 -1
  124. package/dist/setup/cli/ralph.d.ts +20 -0
  125. package/dist/setup/cli/ralph.d.ts.map +1 -0
  126. package/dist/setup/cli/ralph.js +168 -0
  127. package/dist/setup/cli/ralph.js.map +1 -0
  128. package/dist/setup/wizard/ralph_writer.d.ts +98 -0
  129. package/dist/setup/wizard/ralph_writer.d.ts.map +1 -0
  130. package/dist/setup/wizard/ralph_writer.js +114 -0
  131. package/dist/setup/wizard/ralph_writer.js.map +1 -0
  132. package/dist/workgraph/audience.d.ts +12 -0
  133. package/dist/workgraph/audience.d.ts.map +1 -0
  134. package/dist/workgraph/audience.js +10 -0
  135. package/dist/workgraph/audience.js.map +1 -0
  136. package/dist/workgraph/events.d.ts.map +1 -1
  137. package/dist/workgraph/events.js +34 -0
  138. package/dist/workgraph/events.js.map +1 -1
  139. package/dist/workgraph/store.d.ts.map +1 -1
  140. package/dist/workgraph/store.js +86 -12
  141. package/dist/workgraph/store.js.map +1 -1
  142. package/dist/workgraph/types.d.ts +33 -2
  143. package/dist/workgraph/types.d.ts.map +1 -1
  144. package/docs/rubric/author.md +17 -0
  145. package/docs/rubric/scope.md +16 -0
  146. package/package.json +3 -2
  147. package/packs/builtin/coding-flow/skills/entry-and-handoffs/skill.yaml +15 -0
  148. package/packs/builtin/coding-flow/skills/execute-gate/skill.yaml +9 -10
  149. package/packs/builtin/coding-flow/skills/scope-lifecycle/skill.yaml +72 -51
  150. package/packs/builtin/default-discipline/manifest.yaml +6 -3
  151. package/packs/builtin/default-discipline/skills/workflow/skill.yaml +19 -6
  152. package/packs/builtin/pack-architect/SKILL.md +10 -0
  153. package/packs/builtin/pack-architect/skills/skill-yaml-author-walkthrough/skill.yaml +7 -0
  154. package/packs/builtin/scope-architect/team.yaml +5 -2
@@ -70,12 +70,7 @@ export async function recordCurrentSession(sessionId, cwd) {
70
70
  // pointer and can't clobber this one. Skipped (no error) for a cwd that
71
71
  // isn't inside a uuid-bound project (`.opensquid/project.json` absent).
72
72
  if (cwd !== undefined && cwd !== '') {
73
- const uuid = await resolveProjectUuid({ cwd });
74
- if (uuid !== null) {
75
- const scoped = projectCurrentSessionPath(uuid);
76
- await mkdir(dirname(scoped), { recursive: true });
77
- await writeFile(scoped, sessionId, 'utf-8');
78
- }
73
+ await writeSessionPointer(sessionId, cwd, process.env);
79
74
  }
80
75
  }
81
76
  catch {
@@ -102,6 +97,32 @@ export async function readProjectCurrentSession(projectUuid) {
102
97
  return null;
103
98
  }
104
99
  }
100
+ /** wg-16803ed82901: the dir to start the project-uuid walk from for SESSION-POINTER
101
+ * purposes — the authoritative project root `CLAUDE_PROJECT_DIR` when set, else the
102
+ * local cwd. Internal: the ONLY place the pointer's start dir is decided, so the
103
+ * read and write sides can never diverge (the MCP keys on CLAUDE_PROJECT_DIR while a
104
+ * session's working cwd may be a sub-repo with its own project card). */
105
+ function pointerUuidStart(cwd, env) {
106
+ const pd = env.CLAUDE_PROJECT_DIR;
107
+ return pd !== undefined && pd !== '' ? pd : cwd;
108
+ }
109
+ /** Read the project-scoped live-session id, keyed the ONE canonical way. The single
110
+ * chokepoint every reader (resolveMcpSessionId, the handoff CLI, handoff_session_start)
111
+ * routes through — no site resolves the pointer uuid itself. */
112
+ export async function readSessionPointer(cwd, env = process.env) {
113
+ const uuid = await resolveProjectUuid({ cwd: pointerUuidStart(cwd, env), env });
114
+ return uuid === null ? null : readProjectCurrentSession(uuid);
115
+ }
116
+ /** Write the project-scoped live-session id, keyed the SAME canonical way as the read.
117
+ * Best-effort is the caller's contract (recordCurrentSession's try/catch). */
118
+ export async function writeSessionPointer(sessionId, cwd, env = process.env) {
119
+ const uuid = await resolveProjectUuid({ cwd: pointerUuidStart(cwd, env), env });
120
+ if (uuid !== null) {
121
+ const scoped = projectCurrentSessionPath(uuid);
122
+ await mkdir(dirname(scoped), { recursive: true });
123
+ await writeFile(scoped, sessionId, 'utf-8');
124
+ }
125
+ }
105
126
  /**
106
127
  * FU.7 — does `sessions/<id>/` exist? The existence of the per-session dir
107
128
  * (created by the session's own hooks when they first write state) is the
@@ -174,12 +195,9 @@ export async function resolveMcpSessionId() {
174
195
  return ccEnv;
175
196
  const projectDir = env.CLAUDE_PROJECT_DIR;
176
197
  if (projectDir !== undefined && projectDir.length > 0) {
177
- const uuid = await resolveProjectUuid({ cwd: projectDir, env });
178
- if (uuid !== null) {
179
- const scoped = await readProjectCurrentSession(uuid);
180
- if (scoped !== null)
181
- return scoped;
182
- }
198
+ const scoped = await readSessionPointer(projectDir, env);
199
+ if (scoped !== null)
200
+ return scoped;
183
201
  }
184
202
  return readCurrentSession();
185
203
  }
@@ -1 +1 @@
1
- {"version":3,"file":"session_id.js","sourceRoot":"","sources":["../../../src/runtime/hooks/session_id.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session_id.js","sourceRoot":"","sources":["../../../src/runtime/hooks/session_id.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The single writable home for the "is this change docs-only (non-code)?" predicate.
3
+ *
4
+ * Shared by the EXECUTE-gate boundary (`src/setup/cli/gate.ts`) and the in-session commit
5
+ * nudge (via the `staged_docs_only` primitive, `src/functions/staged_docs_only.ts`) so the
6
+ * two enforcement points can never diverge. A pure leaf — zero imports — so the hot
7
+ * function-registry layer can import it without dragging in the gate's CLI/runtime chain.
8
+ *
9
+ * Imported by: src/setup/cli/gate.ts, src/functions/staged_docs_only.ts.
10
+ */
11
+ /** The code prefixes the coding-flow protects. A change touching NONE of these is "docs-only"
12
+ * (non-code: README, banner, docs/, LICENSE, CI config…). Keep in sync with the
13
+ * scope-lifecycle write-gate substrings — the drift pin in gate.test.ts enforces it. */
14
+ export declare const PROTECTED_PREFIXES: readonly ["src/", "packs/", "test/"];
15
+ /** True iff every changed file is OUTSIDE the protected (code) prefixes. Empty set → `false`
16
+ * (fail closed: "nothing proves this docs-only"). Paths are git repo-relative. */
17
+ export declare const isDocsOnly: (files: string[]) => boolean;
18
+ //# sourceMappingURL=protected_paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protected_paths.d.ts","sourceRoot":"","sources":["../../src/runtime/protected_paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;yFAEyF;AACzF,eAAO,MAAM,kBAAkB,sCAAuC,CAAC;AAEvE;mFACmF;AACnF,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,EAAE,KAAG,OAC6C,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The single writable home for the "is this change docs-only (non-code)?" predicate.
3
+ *
4
+ * Shared by the EXECUTE-gate boundary (`src/setup/cli/gate.ts`) and the in-session commit
5
+ * nudge (via the `staged_docs_only` primitive, `src/functions/staged_docs_only.ts`) so the
6
+ * two enforcement points can never diverge. A pure leaf — zero imports — so the hot
7
+ * function-registry layer can import it without dragging in the gate's CLI/runtime chain.
8
+ *
9
+ * Imported by: src/setup/cli/gate.ts, src/functions/staged_docs_only.ts.
10
+ */
11
+ /** The code prefixes the coding-flow protects. A change touching NONE of these is "docs-only"
12
+ * (non-code: README, banner, docs/, LICENSE, CI config…). Keep in sync with the
13
+ * scope-lifecycle write-gate substrings — the drift pin in gate.test.ts enforces it. */
14
+ export const PROTECTED_PREFIXES = ['src/', 'packs/', 'test/'];
15
+ /** True iff every changed file is OUTSIDE the protected (code) prefixes. Empty set → `false`
16
+ * (fail closed: "nothing proves this docs-only"). Paths are git repo-relative. */
17
+ export const isDocsOnly = (files) => files.length > 0 && files.every((f) => !PROTECTED_PREFIXES.some((p) => f.startsWith(p)));
18
+ //# sourceMappingURL=protected_paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protected_paths.js","sourceRoot":"","sources":["../../src/runtime/protected_paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;yFAEyF;AACzF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAU,CAAC;AAEvE;mFACmF;AACnF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAe,EAAW,EAAE,CACrD,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ export type DecisionVerdict = 'DECIDE' | 'ESCALATE' | 'DEFER';
2
+ export interface DecisionClassification {
3
+ verdict: DecisionVerdict;
4
+ confidence: number;
5
+ source: 'heuristic';
6
+ matched: string[];
7
+ }
8
+ /**
9
+ * Classify a decision. ESCALATE wins over DECIDE when both fire (a destructive boundary in a
10
+ * cosmetically-worded change is still a boundary). No signal → DEFER (agent decides, Inv 3 → DECIDE).
11
+ */
12
+ export declare function classifyDecision(decision: string): DecisionClassification;
13
+ /**
14
+ * Record a misclassification as a session drift event (the residual-shrink path). `expected` is the
15
+ * verdict that turned out correct (e.g. the agent escalated something the heuristic called DECIDE).
16
+ */
17
+ export declare function recordMisclassification(sessionId: string, expected: DecisionVerdict, got: DecisionVerdict, decision: string, nowIso: string): Promise<void>;
18
+ //# sourceMappingURL=decision_classifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision_classifier.d.ts","sourceRoot":"","sources":["../../../src/runtime/ralph/decision_classifier.ts"],"names":[],"mappings":"AAoBA,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;AAE9D,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,eAAe,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AA+BD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,sBAAsB,CAQzE;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,eAAe,EACzB,GAAG,EAAE,eAAe,EACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAQf"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * GR.2 — the execution-time DECIDE-vs-ESCALATE classifier (deterministic-first).
3
+ *
4
+ * When a lap hits a decision, the question is: do the locked principles SETTLE it (DECIDE and proceed,
5
+ * per [[feedback-no-questions-after-scoping]]) or is it a genuine fork / irreversible boundary that
6
+ * needs the human (ESCALATE, per Inv 8)? This module is the cheap, deterministic FIRST layer — it fires
7
+ * only on high-confidence signals and otherwise returns DEFER, meaning "no cheap signal → the in-lap
8
+ * agent's own judgment decides" (the lap is already an LLM running RALPH.md; a separate `llm_classify`
9
+ * call would be a redundant second model invocation that also needs the flows executor context — the
10
+ * simpler-correct design defers ambiguous cases to the agent that already holds the full context).
11
+ *
12
+ * Inv 3 bias: DEFER resolves to DECIDE unless the agent itself raises a typed HUMAN_REQUIRED. A
13
+ * misclassification (an escalation that was principle-settleable, or a barreled-through genuine fork)
14
+ * is recorded as a drift event → the residual-shrink path (the classifier earns trust through the
15
+ * existing lesson channel, never assumed correct).
16
+ *
17
+ * Imports from: ../drift_catalog.js.
18
+ */
19
+ import { appendSessionDriftEvent } from '../drift_catalog.js';
20
+ // Irreversible / outward-facing / human-only boundaries → ESCALATE. These ENCODE the "irreversible
21
+ // boundary" principle as deterministic signals (the unambiguous cases the agent must never decide).
22
+ const ESCALATE_SIGNALS = [
23
+ /\bnpm\s+publish\b/i,
24
+ /\bpublish\s+(?:the\s+)?(?:package|release|npm)\b/i,
25
+ /\botp\b/i,
26
+ /\bforce[-\s]?push\b/i,
27
+ /\b--force(?:-with-lease)?\b/i,
28
+ /\bdelete\s+(?:the\s+)?branch\b/i,
29
+ /\bdrop\s+(?:table|database)\b/i,
30
+ /\brm\s+-rf\b/i,
31
+ /\bdeploy\s+to\s+prod(?:uction)?\b/i,
32
+ /\bgenuine(?:ly)?\s+new\s+product\b/i,
33
+ /\bwhich\s+(?:product|ux|business)\s+(?:direction|trade-?off)\b/i,
34
+ ];
35
+ // Principle-settleable surface decisions → DECIDE (the Simplicity/style principles settle these).
36
+ const DECIDE_SIGNALS = [
37
+ /\b(?:rename|naming|name)\b/i,
38
+ /\b(?:format|prettier|lint|whitespace|indent)\b/i,
39
+ /\b(?:typo|comment|docstring|wording)\b/i,
40
+ /\b(?:file\s+location|which\s+directory|where\s+to\s+put)\b/i,
41
+ /\b(?:refactor|extract|inline)\b/i,
42
+ ];
43
+ function firstMatches(text, signals) {
44
+ return signals.filter((re) => re.test(text)).map((re) => re.source);
45
+ }
46
+ /**
47
+ * Classify a decision. ESCALATE wins over DECIDE when both fire (a destructive boundary in a
48
+ * cosmetically-worded change is still a boundary). No signal → DEFER (agent decides, Inv 3 → DECIDE).
49
+ */
50
+ export function classifyDecision(decision) {
51
+ const esc = firstMatches(decision, ESCALATE_SIGNALS);
52
+ if (esc.length > 0)
53
+ return { verdict: 'ESCALATE', confidence: 1, source: 'heuristic', matched: esc };
54
+ const dec = firstMatches(decision, DECIDE_SIGNALS);
55
+ if (dec.length > 0)
56
+ return { verdict: 'DECIDE', confidence: 1, source: 'heuristic', matched: dec };
57
+ return { verdict: 'DEFER', confidence: 0, source: 'heuristic', matched: [] };
58
+ }
59
+ /**
60
+ * Record a misclassification as a session drift event (the residual-shrink path). `expected` is the
61
+ * verdict that turned out correct (e.g. the agent escalated something the heuristic called DECIDE).
62
+ */
63
+ export async function recordMisclassification(sessionId, expected, got, decision, nowIso) {
64
+ await appendSessionDriftEvent(sessionId, {
65
+ timestamp: nowIso,
66
+ pack: '<session>',
67
+ ruleId: 'decision-classifier',
68
+ level: 'surface',
69
+ message: `MISCLASSIFIED decide-vs-escalate: expected ${expected}, got ${got} — "${decision.slice(0, 120)}"`,
70
+ });
71
+ }
72
+ //# sourceMappingURL=decision_classifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision_classifier.js","sourceRoot":"","sources":["../../../src/runtime/ralph/decision_classifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAW9D,mGAAmG;AACnG,oGAAoG;AACpG,MAAM,gBAAgB,GAAsB;IAC1C,oBAAoB;IACpB,mDAAmD;IACnD,UAAU;IACV,sBAAsB;IACtB,8BAA8B;IAC9B,iCAAiC;IACjC,gCAAgC;IAChC,eAAe;IACf,oCAAoC;IACpC,qCAAqC;IACrC,iEAAiE;CAClE,CAAC;AAEF,kGAAkG;AAClG,MAAM,cAAc,GAAsB;IACxC,6BAA6B;IAC7B,iDAAiD;IACjD,yCAAyC;IACzC,6DAA6D;IAC7D,kCAAkC;CACnC,CAAC;AAEF,SAAS,YAAY,CAAC,IAAY,EAAE,OAA0B;IAC5D,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;AACtE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;IACrD,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;QAChB,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;IACnF,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IACnD,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;QAChB,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;IACjF,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;AAC/E,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,SAAiB,EACjB,QAAyB,EACzB,GAAoB,EACpB,QAAgB,EAChB,MAAc;IAEd,MAAM,uBAAuB,CAAC,SAAS,EAAE;QACvC,SAAS,EAAE,MAAM;QACjB,IAAI,EAAE,WAAW;QACjB,MAAM,EAAE,qBAAqB;QAC7B,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,8CAA8C,QAAQ,SAAS,GAAG,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG;KAC5G,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * GR.3 — the UNDROPPABLE lap escalation. When a lap returns HUMAN_REQUIRED (or the supervisor exhausts
3
+ * to UNRECOVERABLE_WEDGE), the orchestrator escalates the typed reason to the human — and a delivery
4
+ * FAILURE is fatal, never swallowed (Inv 6: no silent death). The actual transport is the existing
5
+ * critical-tier path (`escalateSeverity` → NotificationRouter multicast); GR.4 injects an adapter so
6
+ * this module stays decoupled from the notification stack and unit-testable.
7
+ *
8
+ * Imported by: src/runtime/ralph/orchestrator.ts (GR.4).
9
+ */
10
+ import type { HumanRequiredReason } from './lap_outcome.js';
11
+ /** The injected transport. GR.4 wires this to `escalateSeverity` with the user's routing + router. */
12
+ export type LapEscalator = (msg: {
13
+ reason: HumanRequiredReason;
14
+ item?: string;
15
+ payload?: unknown;
16
+ text: string;
17
+ }) => Promise<{
18
+ escalated: boolean;
19
+ reason?: string;
20
+ }>;
21
+ export declare class EscalationUndeliverableError extends Error {
22
+ readonly humanRequiredReason: HumanRequiredReason;
23
+ readonly fallthrough: string | undefined;
24
+ constructor(humanRequiredReason: HumanRequiredReason, fallthrough: string | undefined);
25
+ }
26
+ export declare function escalateLap(reason: HumanRequiredReason, opts: {
27
+ item?: string;
28
+ payload?: unknown;
29
+ escalate: LapEscalator;
30
+ }): Promise<void>;
31
+ //# sourceMappingURL=escalate_lap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escalate_lap.d.ts","sourceRoot":"","sources":["../../../src/runtime/ralph/escalate_lap.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAE5D,sGAAsG;AACtG,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE;IAC/B,MAAM,EAAE,mBAAmB,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd,KAAK,OAAO,CAAC;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEvD,qBAAa,4BAA6B,SAAQ,KAAK;aAEnC,mBAAmB,EAAE,mBAAmB;aACxC,WAAW,EAAE,MAAM,GAAG,SAAS;gBAD/B,mBAAmB,EAAE,mBAAmB,EACxC,WAAW,EAAE,MAAM,GAAG,SAAS;CAOlD;AAED,wBAAsB,WAAW,CAC/B,MAAM,EAAE,mBAAmB,EAC3B,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,GACjE,OAAO,CAAC,IAAI,CAAC,CASf"}
@@ -0,0 +1,22 @@
1
+ export class EscalationUndeliverableError extends Error {
2
+ humanRequiredReason;
3
+ fallthrough;
4
+ constructor(humanRequiredReason, fallthrough) {
5
+ super(`gated-ralph escalation UNDELIVERABLE for ${humanRequiredReason}: ${fallthrough ?? 'no channel'}`);
6
+ this.humanRequiredReason = humanRequiredReason;
7
+ this.fallthrough = fallthrough;
8
+ this.name = 'EscalationUndeliverableError';
9
+ }
10
+ }
11
+ export async function escalateLap(reason, opts) {
12
+ const text = `🦑 HUMAN_REQUIRED(${reason})${opts.item === undefined ? '' : ` [${opts.item}]`}`;
13
+ const res = await opts.escalate({
14
+ reason,
15
+ text,
16
+ ...(opts.item === undefined ? {} : { item: opts.item }),
17
+ ...(opts.payload === undefined ? {} : { payload: opts.payload }),
18
+ });
19
+ if (!res.escalated)
20
+ throw new EscalationUndeliverableError(reason, res.reason); // never silently drop
21
+ }
22
+ //# sourceMappingURL=escalate_lap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escalate_lap.js","sourceRoot":"","sources":["../../../src/runtime/ralph/escalate_lap.ts"],"names":[],"mappings":"AAmBA,MAAM,OAAO,4BAA6B,SAAQ,KAAK;IAEnC;IACA;IAFlB,YACkB,mBAAwC,EACxC,WAA+B;QAE/C,KAAK,CACH,4CAA4C,mBAAmB,KAAK,WAAW,IAAI,YAAY,EAAE,CAClG,CAAC;QALc,wBAAmB,GAAnB,mBAAmB,CAAqB;QACxC,gBAAW,GAAX,WAAW,CAAoB;QAK/C,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAC;IAC7C,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAA2B,EAC3B,IAAkE;IAElE,MAAM,IAAI,GAAG,qBAAqB,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;IAC/F,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC;QAC9B,MAAM;QACN,IAAI;QACJ,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QACvD,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;KACjE,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,SAAS;QAAE,MAAM,IAAI,4BAA4B,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,sBAAsB;AACxG,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * GR.4 — a chat-daemon-backed `LapEscalator` (the gated-ralph escalation transport).
3
+ *
4
+ * When a lap returns HUMAN_REQUIRED (or the supervisor exhausts to UNRECOVERABLE_WEDGE), the orchestrator
5
+ * escalates the typed reason to the HUMAN. The human is on chat (Telegram), so the real escalation path is
6
+ * the live chat-daemon — the SAME UDS `send` the `chat_send` MCP tool uses. Chosen over `escalateSeverity`
7
+ * for GR.4-first because the critical-tier NotificationRouter has no runtime assembly yet; the
8
+ * escalateSeverity critical-tier is a future enhancement (the escalator is injected, so swapping it is local).
9
+ *
10
+ * The transport (`send`) is INJECTED so this stays unit-testable without a running daemon; the CLI wires
11
+ * the real daemon UDS client. UNDROPPABLE (Inv 6): a delivery failure (or a throw) → `{escalated:false}`,
12
+ * and `escalateLap` (GR.3) then THROWS — the loop never silently drops an escalation.
13
+ *
14
+ * Imports from: ./escalate_lap.js (the LapEscalator contract).
15
+ */
16
+ import type { LapEscalator } from './escalate_lap.js';
17
+ /** The injected chat transport — the CLI wires this to the chat-daemon UDS `send`. */
18
+ export type ChatSend = (params: {
19
+ channel: string;
20
+ text: string;
21
+ }) => Promise<{
22
+ ok: boolean;
23
+ reason?: string;
24
+ }>;
25
+ /**
26
+ * Build a `LapEscalator` that delivers the lap's typed `text` to `channel` via the injected chat `send`.
27
+ * Never throws (the contract reports delivery via `escalated`); a transport error is reported, not swallowed
28
+ * — `escalateLap` turns a `false` into the undroppable throw.
29
+ */
30
+ export declare function chatEscalator(deps: {
31
+ send: ChatSend;
32
+ channel: string;
33
+ }): LapEscalator;
34
+ //# sourceMappingURL=escalator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escalator.d.ts","sourceRoot":"","sources":["../../../src/runtime/ralph/escalator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,sFAAsF;AACtF,MAAM,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd,KAAK,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEhD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,YAAY,CAWrF"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Build a `LapEscalator` that delivers the lap's typed `text` to `channel` via the injected chat `send`.
3
+ * Never throws (the contract reports delivery via `escalated`); a transport error is reported, not swallowed
4
+ * — `escalateLap` turns a `false` into the undroppable throw.
5
+ */
6
+ export function chatEscalator(deps) {
7
+ return async (msg) => {
8
+ try {
9
+ const res = await deps.send({ channel: deps.channel, text: msg.text });
10
+ return res.ok
11
+ ? { escalated: true }
12
+ : { escalated: false, reason: res.reason ?? 'send failed' };
13
+ }
14
+ catch (e) {
15
+ return { escalated: false, reason: e instanceof Error ? e.message : String(e) };
16
+ }
17
+ };
18
+ }
19
+ //# sourceMappingURL=escalator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escalator.js","sourceRoot":"","sources":["../../../src/runtime/ralph/escalator.ts"],"names":[],"mappings":"AAuBA;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAyC;IACrE,OAAO,KAAK,EAAE,GAAG,EAAE,EAAE;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;YACvE,OAAO,GAAG,CAAC,EAAE;gBACX,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE;gBACrB,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,aAAa,EAAE,CAAC;QAChE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAClF,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * GR.2 — the typed-exit contract for a gated-ralph lap (Inv 5: ONE typed exit).
3
+ *
4
+ * A lap is a headless `claude -p … --output-format json` run of `RALPH.md`. Its envelope is the
5
+ * empirically-verified shape `{ result, is_error, subtype, total_cost_usd, … }` (verified 2026-06-13).
6
+ * The lap signals its outcome by emitting a single greppable line in `result`:
7
+ *
8
+ * RALPH-EXIT: {"kind":"HUMAN_REQUIRED","reason":"SCOPE_FORK","payload":{…}}
9
+ *
10
+ * `parseLapOutcome` is a TOTAL mapping of every envelope shape to a `LapOutcome` — it never throws and
11
+ * never returns a false `SHIPPED`: an unparseable envelope or `is_error` becomes `CRASH`; a clean
12
+ * envelope with no tag becomes `SHIPPED`. The orchestrator (GR.4) switches on the result.
13
+ *
14
+ * Imported by: src/runtime/ralph/orchestrator.ts (GR.4), src/runtime/ralph/supervisor.ts (GR.3).
15
+ */
16
+ /** The only escalation vocabulary — every human-required exit is one of these (Inv 5/8). */
17
+ export type HumanRequiredReason = 'IRREVERSIBLE_BOUNDARY' | 'SCOPE_FORK' | 'UNRECOVERABLE_WEDGE' | 'BUDGET' | 'RATE_BUDGET' | 'BOARD_EMPTY';
18
+ export type LapOutcome = {
19
+ kind: 'SHIPPED';
20
+ } | {
21
+ kind: 'HUMAN_REQUIRED';
22
+ reason: HumanRequiredReason;
23
+ item?: string;
24
+ payload?: unknown;
25
+ } | {
26
+ kind: 'WEDGE';
27
+ } | {
28
+ kind: 'TIMEOUT';
29
+ } | {
30
+ kind: 'CRASH';
31
+ };
32
+ /**
33
+ * Scan the lap's free-text result for the LAST `RALPH-EXIT: {json}` line and validate it into a
34
+ * `LapOutcome`. Returns null when there is no well-formed tag (caller defaults to SHIPPED on a clean
35
+ * exit). Defensive by construction — a malformed tag is treated as "no tag".
36
+ */
37
+ export declare function extractTypedExit(resultText: string): LapOutcome | null;
38
+ /** Parse the headless JSON envelope into a total `LapOutcome` + the lap's cost. Never throws. */
39
+ export declare function parseLapOutcome(stdout: string): {
40
+ outcome: LapOutcome;
41
+ costUsd: number;
42
+ };
43
+ //# sourceMappingURL=lap_outcome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lap_outcome.d.ts","sourceRoot":"","sources":["../../../src/runtime/ralph/lap_outcome.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,4FAA4F;AAC5F,MAAM,MAAM,mBAAmB,GAC3B,uBAAuB,GACvB,YAAY,GACZ,qBAAqB,GACrB,QAAQ,GACR,aAAa,GACb,aAAa,CAAC;AAElB,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,mBAAmB,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GACzF;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAgBtB;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAkCtE;AAED,iGAAiG;AACjG,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAcxF"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * GR.2 — the typed-exit contract for a gated-ralph lap (Inv 5: ONE typed exit).
3
+ *
4
+ * A lap is a headless `claude -p … --output-format json` run of `RALPH.md`. Its envelope is the
5
+ * empirically-verified shape `{ result, is_error, subtype, total_cost_usd, … }` (verified 2026-06-13).
6
+ * The lap signals its outcome by emitting a single greppable line in `result`:
7
+ *
8
+ * RALPH-EXIT: {"kind":"HUMAN_REQUIRED","reason":"SCOPE_FORK","payload":{…}}
9
+ *
10
+ * `parseLapOutcome` is a TOTAL mapping of every envelope shape to a `LapOutcome` — it never throws and
11
+ * never returns a false `SHIPPED`: an unparseable envelope or `is_error` becomes `CRASH`; a clean
12
+ * envelope with no tag becomes `SHIPPED`. The orchestrator (GR.4) switches on the result.
13
+ *
14
+ * Imported by: src/runtime/ralph/orchestrator.ts (GR.4), src/runtime/ralph/supervisor.ts (GR.3).
15
+ */
16
+ const HUMAN_REQUIRED_REASONS = [
17
+ 'IRREVERSIBLE_BOUNDARY',
18
+ 'SCOPE_FORK',
19
+ 'UNRECOVERABLE_WEDGE',
20
+ 'BUDGET',
21
+ 'RATE_BUDGET',
22
+ 'BOARD_EMPTY',
23
+ ];
24
+ const isReason = (v) => typeof v === 'string' && HUMAN_REQUIRED_REASONS.includes(v);
25
+ const TAG = 'RALPH-EXIT:';
26
+ /**
27
+ * Scan the lap's free-text result for the LAST `RALPH-EXIT: {json}` line and validate it into a
28
+ * `LapOutcome`. Returns null when there is no well-formed tag (caller defaults to SHIPPED on a clean
29
+ * exit). Defensive by construction — a malformed tag is treated as "no tag".
30
+ */
31
+ export function extractTypedExit(resultText) {
32
+ const idx = resultText.lastIndexOf(TAG);
33
+ if (idx === -1)
34
+ return null;
35
+ const after = resultText.slice(idx + TAG.length).trimStart();
36
+ const json = sliceFirstJsonObject(after);
37
+ if (json === null)
38
+ return null;
39
+ let obj;
40
+ try {
41
+ obj = JSON.parse(json);
42
+ }
43
+ catch {
44
+ return null;
45
+ }
46
+ if (obj === null || typeof obj !== 'object')
47
+ return null;
48
+ const rec = obj;
49
+ switch (rec.kind) {
50
+ case 'SHIPPED':
51
+ return { kind: 'SHIPPED' };
52
+ case 'WEDGE':
53
+ return { kind: 'WEDGE' };
54
+ case 'TIMEOUT':
55
+ return { kind: 'TIMEOUT' };
56
+ case 'CRASH':
57
+ return { kind: 'CRASH' };
58
+ case 'HUMAN_REQUIRED':
59
+ if (!isReason(rec.reason))
60
+ return null; // a HUMAN_REQUIRED without a valid reason is malformed
61
+ return {
62
+ kind: 'HUMAN_REQUIRED',
63
+ reason: rec.reason,
64
+ ...(typeof rec.item === 'string' ? { item: rec.item } : {}),
65
+ ...(rec.payload === undefined ? {} : { payload: rec.payload }),
66
+ };
67
+ default:
68
+ return null;
69
+ }
70
+ }
71
+ /** Parse the headless JSON envelope into a total `LapOutcome` + the lap's cost. Never throws. */
72
+ export function parseLapOutcome(stdout) {
73
+ let env;
74
+ try {
75
+ const parsed = JSON.parse(stdout);
76
+ if (parsed === null || typeof parsed !== 'object')
77
+ return { outcome: { kind: 'CRASH' }, costUsd: 0 };
78
+ env = parsed;
79
+ }
80
+ catch {
81
+ return { outcome: { kind: 'CRASH' }, costUsd: 0 }; // unparseable envelope = CRASH, never SHIPPED
82
+ }
83
+ const costUsd = typeof env.total_cost_usd === 'number' ? env.total_cost_usd : 0;
84
+ if (env.is_error === true)
85
+ return { outcome: { kind: 'CRASH' }, costUsd };
86
+ const tagged = extractTypedExit(typeof env.result === 'string' ? env.result : '');
87
+ return { outcome: tagged ?? { kind: 'SHIPPED' }, costUsd }; // clean exit, no tag = SHIPPED
88
+ }
89
+ /** Return the first balanced `{…}` JSON object substring starting at `s[0]`, or null. */
90
+ function sliceFirstJsonObject(s) {
91
+ if (!s.startsWith('{'))
92
+ return null;
93
+ let depth = 0;
94
+ let inStr = false;
95
+ let esc = false;
96
+ for (let i = 0; i < s.length; i++) {
97
+ const c = s[i];
98
+ if (inStr) {
99
+ if (esc)
100
+ esc = false;
101
+ else if (c === '\\')
102
+ esc = true;
103
+ else if (c === '"')
104
+ inStr = false;
105
+ continue;
106
+ }
107
+ if (c === '"')
108
+ inStr = true;
109
+ else if (c === '{')
110
+ depth++;
111
+ else if (c === '}') {
112
+ depth--;
113
+ if (depth === 0)
114
+ return s.slice(0, i + 1);
115
+ }
116
+ }
117
+ return null;
118
+ }
119
+ //# sourceMappingURL=lap_outcome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lap_outcome.js","sourceRoot":"","sources":["../../../src/runtime/ralph/lap_outcome.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * GR.4 — the gated-ralph orchestrator: a thin, non-LLM loop that composes GR.1–3.
3
+ *
4
+ * One pass: read the oldest ready item (GR.1 `listReady`) → atomically claim it (GR.1 CAS) → run a
5
+ * supervised lap (GR.3 `superviseLap` over an injected lap-runner that wraps `claude -p RALPH.md` +
6
+ * GR.2 `parseLapOutcome`) → act on the typed `LapOutcome` (GR.2) → repeat until BOARD_EMPTY or a
7
+ * stopping escalation. No new state store (claim/wedge are work-graph ops); no new gate logic (the lap
8
+ * is gated by the same coding-flow); ONE uniform escalation (GR.3 `escalateLap`).
9
+ *
10
+ * Dependencies are INJECTED (`RalphDeps`) so the loop is pure composition and unit-testable without the
11
+ * notification stack or a real `claude` subprocess — the CLI (`ralph.ts`) wires the real store, the
12
+ * `claude -p` lap-runner, and `escalateSeverity`.
13
+ *
14
+ * The S1 spike PROVED spawn-a-lap is safe (a nested `--dangerously-skip-permissions` lap's ungated
15
+ * commit was blocked by the gate), so this loop spawns laps directly rather than via Alternative F.
16
+ */
17
+ import type { Issue, WorkGraphStore, ClaimAudience } from '../../workgraph/types.js';
18
+ import type { HumanRequiredReason } from './lap_outcome.js';
19
+ import type { LapResult, SuperviseOpts } from './supervisor.js';
20
+ import { type LapEscalator } from './escalate_lap.js';
21
+ import type { DecisionVerdict } from './decision_classifier.js';
22
+ export interface RalphConfig {
23
+ /** Auth mode from CONFIG (Inv 11; no runtime auto-detect). API → dollar budget; subscription → W. */
24
+ authMode: 'api' | 'subscription';
25
+ /** API dollar bound — the running sum of the verified `total_cost_usd` (Inv 11). API mode only. */
26
+ maxBudgetUsd: number;
27
+ /** TTL for the per-item claim (GR.1). */
28
+ claimTtlSec: number;
29
+ /** Stop after one item (the `--once` flag). */
30
+ once: boolean;
31
+ /** GR.3 supervisor opts (retry cap, backoff, heartbeat). */
32
+ supervise: SuperviseOpts;
33
+ }
34
+ /** Why the loop stopped. NB: the per-item residual reasons (IRREVERSIBLE_BOUNDARY / SCOPE_FORK /
35
+ * UNRECOVERABLE_WEDGE) never STOP the loop — they park the item and the loop takes the next. Only the
36
+ * RESOURCE pauses + an explicit `--once` end the run. */
37
+ export type RalphStop = 'BOARD_EMPTY' | 'BUDGET' | 'RATE_BUDGET' | 'once';
38
+ export interface RalphResult {
39
+ stopped: RalphStop;
40
+ spent: number;
41
+ closed: string[];
42
+ parked: {
43
+ id: string;
44
+ reason: HumanRequiredReason;
45
+ }[];
46
+ }
47
+ export interface RalphDeps {
48
+ wg: WorkGraphStore;
49
+ /** Env-derived claim audience (GR.1 — never caller input). */
50
+ claimAudience: () => ClaimAudience;
51
+ /** Run ONE lap for an item → its typed outcome + cost. The CLI wraps `claude -p RALPH.md` + parseLapOutcome. */
52
+ runLap: (item: Issue) => Promise<LapResult>;
53
+ /** The undroppable escalation transport (GR.3) — the CLI wires `escalateSeverity`. */
54
+ escalate: LapEscalator;
55
+ }
56
+ export declare function runRalphLoop(cfg: RalphConfig, deps: RalphDeps): Promise<RalphResult>;
57
+ /** GR.2's recordMisclassification, injected (kept testable / decoupled). */
58
+ export type RecordMisclassification = (sessionId: string, expected: DecisionVerdict, got: DecisionVerdict, decision: string, nowIso: string) => Promise<void>;
59
+ /**
60
+ * `opensquid loop resolve <itemId> --misclassified` — the human-override INPUT (post-hoc residual-shrink
61
+ * path; NOT the hot loop). The human marks a parked escalation as principle-settleable: we record the
62
+ * misclassification (the heuristic said ESCALATE, the correct verdict was DECIDE) and un-wedge the item so
63
+ * it re-enters `ready` for another lap. The SOLE caller of GR.2's recordMisclassification.
64
+ */
65
+ export declare function resolveParked(itemId: string, deps: {
66
+ wg: WorkGraphStore;
67
+ recordMisclassification: RecordMisclassification;
68
+ sessionId: string;
69
+ nowIso: string;
70
+ }): Promise<void>;
71
+ //# sourceMappingURL=orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../../src/runtime/ralph/orchestrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACrF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhE,OAAO,EAAe,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAEhE,MAAM,WAAW,WAAW;IAC1B,qGAAqG;IACrG,QAAQ,EAAE,KAAK,GAAG,cAAc,CAAC;IACjC,mGAAmG;IACnG,YAAY,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,IAAI,EAAE,OAAO,CAAC;IACd,4DAA4D;IAC5D,SAAS,EAAE,aAAa,CAAC;CAC1B;AAED;;yDAEyD;AACzD,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,QAAQ,GAAG,aAAa,GAAG,MAAM,CAAC;AAE1E,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,SAAS,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,mBAAmB,CAAA;KAAE,EAAE,CAAC;CACvD;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,cAAc,CAAC;IACnB,8DAA8D;IAC9D,aAAa,EAAE,MAAM,aAAa,CAAC;IACnC,gHAAgH;IAChH,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IAC5C,sFAAsF;IACtF,QAAQ,EAAE,YAAY,CAAC;CACxB;AAOD,wBAAsB,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CA0D1F;AAED,4EAA4E;AAC5E,MAAM,MAAM,uBAAuB,GAAG,CACpC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,eAAe,EACzB,GAAG,EAAE,eAAe,EACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,KACX,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE;IACJ,EAAE,EAAE,cAAc,CAAC;IACnB,uBAAuB,EAAE,uBAAuB,CAAC;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,GACA,OAAO,CAAC,IAAI,CAAC,CAMf"}