@telora/daemon 0.20.21 → 0.20.32

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 (115) hide show
  1. package/build-info.json +4 -3
  2. package/dist/audit-phase.d.ts +43 -6
  3. package/dist/audit-phase.d.ts.map +1 -1
  4. package/dist/audit-phase.js +124 -23
  5. package/dist/audit-phase.js.map +1 -1
  6. package/dist/auto-update.d.ts +87 -0
  7. package/dist/auto-update.d.ts.map +1 -1
  8. package/dist/auto-update.js +142 -8
  9. package/dist/auto-update.js.map +1 -1
  10. package/dist/cascade-restatement.d.ts +13 -147
  11. package/dist/cascade-restatement.d.ts.map +1 -1
  12. package/dist/cascade-restatement.js +13 -429
  13. package/dist/cascade-restatement.js.map +1 -1
  14. package/dist/focus-engine.d.ts.map +1 -1
  15. package/dist/focus-engine.js +15 -0
  16. package/dist/focus-engine.js.map +1 -1
  17. package/dist/focus-loop-registry.d.ts.map +1 -1
  18. package/dist/focus-loop-registry.js +43 -90
  19. package/dist/focus-loop-registry.js.map +1 -1
  20. package/dist/focus-loop.d.ts +0 -2
  21. package/dist/focus-loop.d.ts.map +1 -1
  22. package/dist/focus-loop.js +33 -25
  23. package/dist/focus-loop.js.map +1 -1
  24. package/dist/focus-phase.d.ts +26 -0
  25. package/dist/focus-phase.d.ts.map +1 -1
  26. package/dist/focus-phase.js +38 -0
  27. package/dist/focus-phase.js.map +1 -1
  28. package/dist/focus-prompt-builder.d.ts.map +1 -1
  29. package/dist/focus-prompt-builder.js +5 -1
  30. package/dist/focus-prompt-builder.js.map +1 -1
  31. package/dist/listener.d.ts.map +1 -1
  32. package/dist/listener.js +40 -9
  33. package/dist/listener.js.map +1 -1
  34. package/dist/loops/llm-client.d.ts.map +1 -1
  35. package/dist/loops/llm-client.js +17 -4
  36. package/dist/loops/llm-client.js.map +1 -1
  37. package/dist/prompt-listing.d.ts +25 -0
  38. package/dist/prompt-listing.d.ts.map +1 -1
  39. package/dist/prompt-listing.js +61 -0
  40. package/dist/prompt-listing.js.map +1 -1
  41. package/dist/queries/audit-runs.d.ts +56 -2
  42. package/dist/queries/audit-runs.d.ts.map +1 -1
  43. package/dist/queries/audit-runs.js +40 -0
  44. package/dist/queries/audit-runs.js.map +1 -1
  45. package/dist/queries/deliveries.d.ts +27 -0
  46. package/dist/queries/deliveries.d.ts.map +1 -1
  47. package/dist/queries/deliveries.js.map +1 -1
  48. package/dist/queries/focuses.d.ts +0 -9
  49. package/dist/queries/focuses.d.ts.map +1 -1
  50. package/dist/queries/focuses.js +0 -14
  51. package/dist/queries/focuses.js.map +1 -1
  52. package/dist/resolvers/index.d.ts +1 -1
  53. package/dist/resolvers/index.d.ts.map +1 -1
  54. package/dist/resolvers/index.js +1 -1
  55. package/dist/resolvers/index.js.map +1 -1
  56. package/dist/resolvers/shared/audit.d.ts +5 -0
  57. package/dist/resolvers/shared/audit.d.ts.map +1 -1
  58. package/dist/resolvers/shared/audit.js +8 -3
  59. package/dist/resolvers/shared/audit.js.map +1 -1
  60. package/dist/resolvers/shared/git-diff.d.ts +13 -0
  61. package/dist/resolvers/shared/git-diff.d.ts.map +1 -1
  62. package/dist/resolvers/shared/git-diff.js +30 -0
  63. package/dist/resolvers/shared/git-diff.js.map +1 -1
  64. package/dist/security-scan-engine.d.ts +9 -1
  65. package/dist/security-scan-engine.d.ts.map +1 -1
  66. package/dist/security-scan-engine.js +25 -2
  67. package/dist/security-scan-engine.js.map +1 -1
  68. package/dist/spawn/review-role-fallback.d.ts +74 -0
  69. package/dist/spawn/review-role-fallback.d.ts.map +1 -0
  70. package/dist/spawn/review-role-fallback.js +62 -0
  71. package/dist/spawn/review-role-fallback.js.map +1 -0
  72. package/dist/staleness-sensor.d.ts +153 -0
  73. package/dist/staleness-sensor.d.ts.map +1 -0
  74. package/dist/staleness-sensor.js +308 -0
  75. package/dist/staleness-sensor.js.map +1 -0
  76. package/dist/unified-shell.d.ts.map +1 -1
  77. package/dist/unified-shell.js +11 -0
  78. package/dist/unified-shell.js.map +1 -1
  79. package/dist/verification-engine.d.ts +17 -1
  80. package/dist/verification-engine.d.ts.map +1 -1
  81. package/dist/verification-engine.js +143 -104
  82. package/dist/verification-engine.js.map +1 -1
  83. package/dist/verification-feedback.d.ts +68 -1
  84. package/dist/verification-feedback.d.ts.map +1 -1
  85. package/dist/verification-feedback.js +175 -0
  86. package/dist/verification-feedback.js.map +1 -1
  87. package/dist/verify-reconciliation.d.ts +16 -1
  88. package/dist/verify-reconciliation.d.ts.map +1 -1
  89. package/dist/verify-reconciliation.js +18 -2
  90. package/dist/verify-reconciliation.js.map +1 -1
  91. package/dist/verify-restatement.d.ts +7 -0
  92. package/dist/verify-restatement.d.ts.map +1 -1
  93. package/dist/verify-restatement.js +1 -0
  94. package/dist/verify-restatement.js.map +1 -1
  95. package/dist/version-check.d.ts +6 -0
  96. package/dist/version-check.d.ts.map +1 -1
  97. package/dist/version-check.js +1 -1
  98. package/dist/version-check.js.map +1 -1
  99. package/package.json +2 -2
  100. package/dist/drift-ratify-loop.d.ts +0 -68
  101. package/dist/drift-ratify-loop.d.ts.map +0 -1
  102. package/dist/drift-ratify-loop.js +0 -161
  103. package/dist/drift-ratify-loop.js.map +0 -1
  104. package/dist/negative-branch.d.ts +0 -136
  105. package/dist/negative-branch.d.ts.map +0 -1
  106. package/dist/negative-branch.js +0 -241
  107. package/dist/negative-branch.js.map +0 -1
  108. package/dist/shortfall-disposition-config.d.ts +0 -34
  109. package/dist/shortfall-disposition-config.d.ts.map +0 -1
  110. package/dist/shortfall-disposition-config.js +0 -46
  111. package/dist/shortfall-disposition-config.js.map +0 -1
  112. package/dist/shortfall-disposition-loop.d.ts +0 -86
  113. package/dist/shortfall-disposition-loop.d.ts.map +0 -1
  114. package/dist/shortfall-disposition-loop.js +0 -309
  115. package/dist/shortfall-disposition-loop.js.map +0 -1
@@ -1,161 +0,0 @@
1
- /**
2
- * Periodic drift auto-ratification tick.
3
- *
4
- * Lists `proposed` drift proposals per product, runs each through the
5
- * fail-closed policy in `drift-ratify-policy.ts`, and ratifies the ones the
6
- * daemon is sanctioned to ratify unattended. Proposals the policy routes to a
7
- * review session (`review_dispose`) or refuses to classify (`hold`) are left
8
- * in `proposed`, untouched.
9
- *
10
- * WHAT THIS CLOSES. Drift proposals pooled in `proposed` faster than a human
11
- * could ratify them, so the reality tree lagged observed reality and every
12
- * consumer of the graph (audit assembly, propose_injections, focus.context)
13
- * computed against a stale intent model. The ledger is unchanged -- this only
14
- * changes WHO ratifies. Ratified proposals still reach the graph exclusively
15
- * via the existing realign_crt phase (`applyRatifiedProposals`), which this
16
- * module does not touch.
17
- *
18
- * WHAT THIS MUST NEVER DO. Ratify an inward shortfall. That is the machine
19
- * rewriting a claim its own work failed to meet. The policy module owns that
20
- * decision; this tick owns only list -> classify -> ratify-the-safe-ones, and
21
- * deliberately contains no safe-kind rules of its own. If you find yourself
22
- * adding kind logic here, it belongs in drift-ratify-policy.ts.
23
- *
24
- * ACTOR STAMP. The tick calls `crt_drift_proposal_ratify` with no session id.
25
- * The edge handler resolves the actor from the caller's credential kind, so a
26
- * tracker-authenticated daemon call is recorded as `ratified_by_kind='system'`
27
- * with `ratified_by=NULL` automatically. Passing a session id would instead
28
- * stamp `review_session` -- that is the review-disposition path, not this one.
29
- *
30
- * Activation: opt-out via TELORA_DRIFT_RATIFY_LOOP=0. See `shouldRunLoop()` in
31
- * focus-engine.ts.
32
- *
33
- * @module drift-ratify-loop
34
- */
35
- import { loadEnvConfig } from '@telora/daemon-core';
36
- import { callApi as defaultCallApi } from './queries/shared.js';
37
- import { classifyDriftProposal } from './drift-ratify-policy.js';
38
- import { createLogger } from './log.js';
39
- const log = createLogger({ module: 'drift-ratify-loop' });
40
- /**
41
- * Per-product backoff for list failures, so a persistent server-side failure
42
- * does not retry-storm every tick. Module-level so the window survives across
43
- * `runDriftRatifyTick` calls within the daemon process. Keyed productId ->
44
- * earliest next-attempt epoch ms. Mirrors the drift-eval loop's window
45
- * (drift-eval-loop.ts:74) and complements the isolated 'drift' circuit breaker
46
- * in queries/shared.ts, which fails fast once the breaker opens.
47
- */
48
- const listBackoffUntil = new Map();
49
- /**
50
- * Resolve the per-product list-failure backoff window (ms).
51
- *
52
- * Deliberately REUSES TELORA_DRIFT_LIST_BACKOFF_MS rather than introducing a
53
- * knob of its own. The knob's meaning -- how long to back off a product after a
54
- * drift-list failure -- is exactly this loop's need, and both loops fail the
55
- * same way for the same reasons, so one operator dial covering both is coherent
56
- * rather than a conflation. It also keeps this loop free of any dependency on a
57
- * @telora/daemon-core republish: daemon-core is registry-installed, so a new
58
- * knob added to its source would be invisible to this package until it is
59
- * published and reinstalled. Injectable via deps for tests.
60
- */
61
- function defaultListBackoffMs() {
62
- return loadEnvConfig().TELORA_DRIFT_LIST_BACKOFF_MS;
63
- }
64
- /** Test-only: clear the per-product list-failure backoff state. */
65
- export function __resetDriftRatifyBackoffForTesting() {
66
- listBackoffUntil.clear();
67
- }
68
- function defaultDeps() {
69
- return {
70
- callApi: defaultCallApi,
71
- now: () => Date.now(),
72
- listBackoffMs: defaultListBackoffMs(),
73
- };
74
- }
75
- /**
76
- * Run one auto-ratification tick across every product in the daemon config.
77
- *
78
- * Per-proposal failures are counted and skipped, never aborting the batch --
79
- * one unratifiable proposal must not strand the rest of the stream (mirrors
80
- * `applyRatifiedProposals`, realign-apply.ts:403-416).
81
- *
82
- * Returns counters useful for log lines and tests.
83
- */
84
- export async function runDriftRatifyTick(config, depOverrides = {}) {
85
- const deps = { ...defaultDeps(), ...depOverrides };
86
- const counts = {
87
- productsScanned: 0,
88
- productsSkipped: 0,
89
- proposalsExamined: 0,
90
- ratified: 0,
91
- leftForReview: 0,
92
- held: 0,
93
- errors: 0,
94
- };
95
- for (const product of config.products) {
96
- counts.productsScanned += 1;
97
- // Skip a product still inside its list-failure backoff window.
98
- const nowMs = deps.now();
99
- const backoffUntil = listBackoffUntil.get(product.id) ?? 0;
100
- if (nowMs < backoffUntil) {
101
- counts.productsSkipped += 1;
102
- continue;
103
- }
104
- let proposals;
105
- try {
106
- // NOTE: crt_drift_proposal_list cannot filter on proposed_metadata
107
- // (drift-proposals.ts:78-119 supports focusId/productId/realityTreeId/
108
- // status only), so the shortfall split is decided client-side by the
109
- // policy below -- not by the query.
110
- const list = await deps.callApi('crt_drift_proposal_list', {
111
- productId: product.id,
112
- status: 'proposed',
113
- });
114
- proposals = list.items ?? [];
115
- // Success clears any prior backoff for this product.
116
- listBackoffUntil.delete(product.id);
117
- }
118
- catch (err) {
119
- counts.errors += 1;
120
- listBackoffUntil.set(product.id, nowMs + deps.listBackoffMs);
121
- log.warn(`[drift-ratify-loop] list failed for product ${product.id} (backing off ${deps.listBackoffMs}ms):`, err.message);
122
- continue;
123
- }
124
- for (const proposal of proposals) {
125
- counts.proposalsExamined += 1;
126
- const { disposition, reason } = classifyDriftProposal({
127
- proposalKind: proposal.proposalKind,
128
- proposedMetadata: proposal.proposedMetadata,
129
- });
130
- if (disposition === 'review_dispose') {
131
- // The bar-lowering channel. Left in `proposed` for an independent
132
- // review session; this tick must not touch it.
133
- counts.leftForReview += 1;
134
- continue;
135
- }
136
- if (disposition === 'hold') {
137
- // Fail-closed: unknown kind, malformed metadata, or an internally
138
- // inconsistent row. Stays `proposed` so a human sees it.
139
- counts.held += 1;
140
- log.info(`[drift-ratify-loop] holding proposal ${proposal.id} (kind=${proposal.proposalKind}, reason=${reason})`);
141
- continue;
142
- }
143
- try {
144
- // No session id: the edge handler stamps ratified_by_kind='system' from
145
- // the tracker credential. Ratified proposals reach the graph via the
146
- // existing realign_crt phase; nothing here applies them.
147
- await deps.callApi('crt_drift_proposal_ratify', { proposalId: proposal.id });
148
- counts.ratified += 1;
149
- }
150
- catch (err) {
151
- counts.errors += 1;
152
- log.warn(`[drift-ratify-loop] ratify failed for proposal ${proposal.id} (${reason}):`, err.message);
153
- }
154
- }
155
- }
156
- if (counts.proposalsExamined > 0 || counts.errors > 0 || counts.productsSkipped > 0) {
157
- log.info(`[drift-ratify-loop] tick: products=${counts.productsScanned} skipped=${counts.productsSkipped} examined=${counts.proposalsExamined} ratified=${counts.ratified} forReview=${counts.leftForReview} held=${counts.held} errors=${counts.errors}`);
158
- }
159
- return counts;
160
- }
161
- //# sourceMappingURL=drift-ratify-loop.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"drift-ratify-loop.js","sourceRoot":"","sources":["../src/drift-ratify-loop.ts"],"names":[],"mappings":"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"}
@@ -1,136 +0,0 @@
1
- /**
2
- * Negative-branch (negative branch reservation) generation helper.
3
- *
4
- * The INVERSE of `de-restatement.ts`. Where de-restatement turns a UDE into the
5
- * positive desired effect it becomes once an injection resolves it, this asks
6
- * the opposite question: what NEW undesired effects might this injection ITSELF
7
- * introduce? In Goldratt's Thinking Processes this is a "negative branch
8
- * reservation" -- a side effect the injection drags in that the clean recolor
9
- * never surfaces.
10
- *
11
- * Reuses the same model-invocation pattern as `de-restatement.ts` -- spawning
12
- * the `claude` CLI in print mode -- so there is NO new client or secret wiring.
13
- * A clean injection yields ZERO candidates (the model emits "NONE" -> []).
14
- *
15
- * The generated candidates are persisted as `crt_drift_proposals`
16
- * (`proposal_kind='add_node'`) carrying `sourceInjectionId` + `isNegativeBranch`
17
- * so a human ratifies/dismisses them: ratify -> the UDE is created and wired to
18
- * the injection (see realign-apply `handleAddNode`); dismiss -> no residue.
19
- *
20
- * @module negative-branch
21
- */
22
- import { type ChildProcess } from 'node:child_process';
23
- export interface NegativeBranchInputs {
24
- /** The injection whose side effects we are probing. */
25
- injectionStatement: string;
26
- /** Optional UDE statements the injection targets, for context. */
27
- targetUdeStatements?: string[];
28
- }
29
- interface SpawnOpts {
30
- stdio: ['pipe', 'pipe', 'pipe'];
31
- }
32
- export interface NegativeBranchOptions {
33
- /** Path to the `claude` CLI binary (default: 'claude'). */
34
- claudeBin?: string;
35
- /** Timeout in ms; defaults to 2 minutes. */
36
- timeoutMs?: number;
37
- /** Override spawn for tests. Defaults to node:child_process spawn. */
38
- spawnFn?: (cmd: string, args: string[], opts: SpawnOpts) => ChildProcess;
39
- /**
40
- * Override the entire model invocation for tests -- bypasses spawning the
41
- * CLI. Receives the system prompt and user message, returns the raw model
42
- * text. When omitted, the default spawns the `claude` CLI in print mode.
43
- */
44
- invokeModel?: (systemPrompt: string, userMessage: string) => Promise<string>;
45
- }
46
- export declare const NEGATIVE_BRANCH_SYSTEM_PROMPT = "You author Goldratt \"negative branch reservations\" for a reality tree: the NEW undesirable effects that an injection might itself introduce.\n\nAn injection resolves one problem but can drag in fresh side effects. Your job is to surface those candidate new undesired effects (UDEs) so a human can decide whether they are real.\n\nRules:\n- Output ONE candidate undesired effect per line. No numbering, no bullets, no preamble, no commentary, no quotes.\n- Each line is a single concrete negative outcome the injection could cause -- a genuinely NEW problem, not a restatement of the problem the injection solves.\n- Be conservative: only list effects with a plausible causal link to the injection. Do NOT pad the list.\n- If the injection introduces no plausible new undesired effect, output exactly: NONE";
47
- /** Exposed as a function to mirror `de-restatement`'s shape. */
48
- export declare function buildNegativeBranchSystemPrompt(): string;
49
- /** Build the user message describing the injection (and any targeted UDEs). */
50
- export declare function buildNegativeBranchUserMessage(inputs: NegativeBranchInputs): string;
51
- /**
52
- * Parse raw model output into a list of candidate UDE statements.
53
- *
54
- * One candidate per line, trimmed, empties dropped. A lone "NONE" (case
55
- * insensitive, optionally with surrounding punctuation) yields an empty list.
56
- * Strips a leading bullet/number if the model added one despite the prompt.
57
- */
58
- export declare function parseNegativeBranchCandidates(raw: string): string[];
59
- /**
60
- * Build the argv for the claude CLI invocation. Exposed for tests.
61
- *
62
- * NOTE: must NOT include `--bare` -- that flag makes the CLI skip credential
63
- * loading, print "Not logged in" to stdout, and exit 1 (the negative-branch
64
- * pass died silently before it ran).
65
- */
66
- export declare function buildNegativeBranchCliArgs(systemPrompt: string): string[];
67
- /**
68
- * Generate candidate negative-branch UDE statements for an injection.
69
- *
70
- * Returns 0-N candidates. A clean injection (model outputs "NONE") yields [].
71
- * Throws only on model-invocation failure; callers catch and skip so a single
72
- * failure never aborts the surrounding loop.
73
- */
74
- export declare function generateNegativeBranches(inputs: NegativeBranchInputs, opts?: NegativeBranchOptions): Promise<string[]>;
75
- type CallApi = <T>(action: string, params?: Record<string, unknown>) => Promise<T>;
76
- export interface ProposeNegativeBranchesInputs {
77
- /** The injection node these negative branches hang off. */
78
- injectionNodeId: string;
79
- /** The injection statement (the probe input). */
80
- injectionStatement: string;
81
- /** Reality tree the proposals belong to (required by the create action). */
82
- realityTreeId: string;
83
- /** Focus context for the proposal (optional but recommended). */
84
- focusId?: string | null;
85
- /** UDE statements the injection targets, for generation context. */
86
- targetUdeStatements?: string[];
87
- }
88
- export interface ProposeNegativeBranchesDeps {
89
- callApi?: CallApi;
90
- /** Override generation for tests. Defaults to `generateNegativeBranches`. */
91
- generate?: (inputs: NegativeBranchInputs, opts?: NegativeBranchOptions) => Promise<string[]>;
92
- /** Options forwarded to the default generator (model/spawn overrides). */
93
- generateOptions?: NegativeBranchOptions;
94
- /**
95
- * Injectable clock for the durable pass marker. Defaults to
96
- * `() => new Date().toISOString()`. Tests pass a fixed value so the stamped
97
- * timestamp is deterministic. Kept as a thunk (not a bare value) mirroring the
98
- * module's other injectable-deps style. The clock is read AFTER generation +
99
- * proposal creation complete and just BEFORE the stamp write -- i.e. the
100
- * timestamp marks when the pass finished its work, immediately prior to
101
- * persisting the marker (it cannot be read after the write resolves, since the
102
- * value being written is what the write persists).
103
- */
104
- now?: () => string;
105
- }
106
- export interface ProposeNegativeBranchesResult {
107
- /** Candidate statements the model produced. */
108
- candidates: string[];
109
- /** Drift-proposal ids successfully created (one per candidate). */
110
- proposalIds: string[];
111
- /** Per-candidate creation errors (creation failures do not abort the rest). */
112
- errors: string[];
113
- /**
114
- * The ISO timestamp stamped onto the injection's
115
- * `negative_branch_pass_ran_at` marker, or null if the stamp write failed.
116
- * The pass having RUN (this being non-null) is what gates presentability --
117
- * NOT whether `candidates` is empty. An empty candidate set with a set marker
118
- * is the honest "ran clean" answer.
119
- */
120
- passRanAt: string | null;
121
- }
122
- /**
123
- * Run generation for an injection, then persist each candidate as a
124
- * ratify-able `add_node` drift proposal wired (via `sourceInjectionId`) to the
125
- * injection that introduces it. Idempotency / dedupe is a human concern --
126
- * proposals are surfaced, not auto-applied.
127
- *
128
- * A clean injection produces no candidates and creates no proposals -- but the
129
- * pass still COMPLETED, so the injection's `negative_branch_pass_ran_at` marker
130
- * is stamped regardless of candidate count (as long as generation did not
131
- * throw). That durable marker, not the candidate count, is what later gates
132
- * tree presentability: "ran clean" must be distinguishable from "never ran".
133
- */
134
- export declare function proposeNegativeBranchesForInjection(inputs: ProposeNegativeBranchesInputs, deps?: ProposeNegativeBranchesDeps): Promise<ProposeNegativeBranchesResult>;
135
- export {};
136
- //# sourceMappingURL=negative-branch.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"negative-branch.d.ts","sourceRoot":"","sources":["../src/negative-branch.ts"],"names":[],"mappings":"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"}
@@ -1,241 +0,0 @@
1
- /**
2
- * Negative-branch (negative branch reservation) generation helper.
3
- *
4
- * The INVERSE of `de-restatement.ts`. Where de-restatement turns a UDE into the
5
- * positive desired effect it becomes once an injection resolves it, this asks
6
- * the opposite question: what NEW undesired effects might this injection ITSELF
7
- * introduce? In Goldratt's Thinking Processes this is a "negative branch
8
- * reservation" -- a side effect the injection drags in that the clean recolor
9
- * never surfaces.
10
- *
11
- * Reuses the same model-invocation pattern as `de-restatement.ts` -- spawning
12
- * the `claude` CLI in print mode -- so there is NO new client or secret wiring.
13
- * A clean injection yields ZERO candidates (the model emits "NONE" -> []).
14
- *
15
- * The generated candidates are persisted as `crt_drift_proposals`
16
- * (`proposal_kind='add_node'`) carrying `sourceInjectionId` + `isNegativeBranch`
17
- * so a human ratifies/dismisses them: ratify -> the UDE is created and wired to
18
- * the injection (see realign-apply `handleAddNode`); dismiss -> no residue.
19
- *
20
- * @module negative-branch
21
- */
22
- import { spawn } from 'node:child_process';
23
- import { callApi as defaultCallApi } from './queries/shared.js';
24
- import { trackChildProcess } from './spawner/worker-registry.js';
25
- const DEFAULT_TIMEOUT_MS = 2 * 60 * 1000;
26
- export const NEGATIVE_BRANCH_SYSTEM_PROMPT = `You author Goldratt "negative branch reservations" for a reality tree: the NEW undesirable effects that an injection might itself introduce.
27
-
28
- An injection resolves one problem but can drag in fresh side effects. Your job is to surface those candidate new undesired effects (UDEs) so a human can decide whether they are real.
29
-
30
- Rules:
31
- - Output ONE candidate undesired effect per line. No numbering, no bullets, no preamble, no commentary, no quotes.
32
- - Each line is a single concrete negative outcome the injection could cause -- a genuinely NEW problem, not a restatement of the problem the injection solves.
33
- - Be conservative: only list effects with a plausible causal link to the injection. Do NOT pad the list.
34
- - If the injection introduces no plausible new undesired effect, output exactly: NONE`;
35
- /** Exposed as a function to mirror `de-restatement`'s shape. */
36
- export function buildNegativeBranchSystemPrompt() {
37
- return NEGATIVE_BRANCH_SYSTEM_PROMPT;
38
- }
39
- /** Build the user message describing the injection (and any targeted UDEs). */
40
- export function buildNegativeBranchUserMessage(inputs) {
41
- const parts = [`Injection:\n${inputs.injectionStatement}`];
42
- const targets = (inputs.targetUdeStatements ?? []).filter((s) => s && s.trim() !== '');
43
- if (targets.length > 0) {
44
- parts.push(`Undesired effect(s) this injection resolves:\n${targets.map((s) => `- ${s}`).join('\n')}`);
45
- }
46
- parts.push('List the candidate NEW undesired effects this injection might itself introduce, one per line. If there are none, output exactly: NONE');
47
- return parts.join('\n\n');
48
- }
49
- /**
50
- * Parse raw model output into a list of candidate UDE statements.
51
- *
52
- * One candidate per line, trimmed, empties dropped. A lone "NONE" (case
53
- * insensitive, optionally with surrounding punctuation) yields an empty list.
54
- * Strips a leading bullet/number if the model added one despite the prompt.
55
- */
56
- export function parseNegativeBranchCandidates(raw) {
57
- let s = raw.trim();
58
- // Strip code fences if the model wrapped the answer.
59
- s = s.replace(/```[a-zA-Z]*\s*/g, '').replace(/```/g, '').trim();
60
- if (s === '')
61
- return [];
62
- const lines = s.split('\n');
63
- const out = [];
64
- for (const rawLine of lines) {
65
- let line = rawLine.trim();
66
- if (line === '')
67
- continue;
68
- // Drop a leading bullet ("- ", "* ") or "1. " numbering.
69
- line = line.replace(/^[-*]\s+/, '').replace(/^\d+[.)]\s+/, '').trim();
70
- // Strip a single layer of surrounding quotes/backticks.
71
- line = line.replace(/^["'`]+/, '').replace(/["'`]+$/, '').trim();
72
- if (line === '')
73
- continue;
74
- // A standalone NONE sentinel means "no negative branches".
75
- if (/^none[.!]?$/i.test(line))
76
- continue;
77
- out.push(line);
78
- }
79
- return out;
80
- }
81
- /**
82
- * Build the argv for the claude CLI invocation. Exposed for tests.
83
- *
84
- * NOTE: must NOT include `--bare` -- that flag makes the CLI skip credential
85
- * loading, print "Not logged in" to stdout, and exit 1 (the negative-branch
86
- * pass died silently before it ran).
87
- */
88
- export function buildNegativeBranchCliArgs(systemPrompt) {
89
- return [
90
- '--print',
91
- '--output-format', 'text',
92
- '--no-session-persistence',
93
- '--system-prompt', systemPrompt,
94
- ];
95
- }
96
- /** Default model invocation: spawn the `claude` CLI in print mode and return stdout. */
97
- function invokeClaudeCli(systemPrompt, userMessage, opts) {
98
- const claudeBin = opts.claudeBin ?? 'claude';
99
- const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
100
- const spawnFn = opts.spawnFn ?? ((cmd, args, sopts) => spawn(cmd, args, sopts));
101
- const args = buildNegativeBranchCliArgs(systemPrompt);
102
- return new Promise((resolve, reject) => {
103
- let child;
104
- try {
105
- child = spawnFn(claudeBin, args, { stdio: ['pipe', 'pipe', 'pipe'] });
106
- }
107
- catch (err) {
108
- reject(new Error(`negative-branch spawn failed: ${err.message}`));
109
- return;
110
- }
111
- // Register so a graceful stop reaps this one-shot if it is still running.
112
- trackChildProcess(child, 'negative-branch');
113
- let stdout = '';
114
- let stderr = '';
115
- child.stdout?.on('data', (chunk) => { stdout += chunk.toString('utf8'); });
116
- child.stderr?.on('data', (chunk) => { stderr += chunk.toString('utf8'); });
117
- const timer = setTimeout(() => {
118
- try {
119
- child.kill('SIGKILL');
120
- }
121
- catch { /* ignore */ }
122
- }, timeoutMs);
123
- child.on('error', (err) => {
124
- clearTimeout(timer);
125
- reject(new Error(`negative-branch spawn error: ${err.message}`));
126
- });
127
- child.on('close', (code) => {
128
- clearTimeout(timer);
129
- if (code !== 0) {
130
- reject(new Error(`negative-branch exited ${code}: ${stderr.slice(-2000)}`));
131
- return;
132
- }
133
- resolve(stdout);
134
- });
135
- try {
136
- child.stdin?.write(userMessage);
137
- child.stdin?.end();
138
- }
139
- catch (err) {
140
- clearTimeout(timer);
141
- reject(new Error(`negative-branch stdin write failed: ${err.message}`));
142
- }
143
- });
144
- }
145
- /**
146
- * Generate candidate negative-branch UDE statements for an injection.
147
- *
148
- * Returns 0-N candidates. A clean injection (model outputs "NONE") yields [].
149
- * Throws only on model-invocation failure; callers catch and skip so a single
150
- * failure never aborts the surrounding loop.
151
- */
152
- export async function generateNegativeBranches(inputs, opts = {}) {
153
- const systemPrompt = buildNegativeBranchSystemPrompt();
154
- const userMessage = buildNegativeBranchUserMessage(inputs);
155
- const invoke = opts.invokeModel ?? ((sys, msg) => invokeClaudeCli(sys, msg, opts));
156
- const raw = await invoke(systemPrompt, userMessage);
157
- return parseNegativeBranchCandidates(raw);
158
- }
159
- /**
160
- * Run generation for an injection, then persist each candidate as a
161
- * ratify-able `add_node` drift proposal wired (via `sourceInjectionId`) to the
162
- * injection that introduces it. Idempotency / dedupe is a human concern --
163
- * proposals are surfaced, not auto-applied.
164
- *
165
- * A clean injection produces no candidates and creates no proposals -- but the
166
- * pass still COMPLETED, so the injection's `negative_branch_pass_ran_at` marker
167
- * is stamped regardless of candidate count (as long as generation did not
168
- * throw). That durable marker, not the candidate count, is what later gates
169
- * tree presentability: "ran clean" must be distinguishable from "never ran".
170
- */
171
- export async function proposeNegativeBranchesForInjection(inputs, deps = {}) {
172
- const callApi = deps.callApi ?? defaultCallApi;
173
- const generate = deps.generate ?? generateNegativeBranches;
174
- const now = deps.now ?? (() => new Date().toISOString());
175
- // If generation throws, the pass did NOT complete -- the caller catches and
176
- // the marker stays null so the injection remains a surfaced doubt (no stamp).
177
- const candidates = await generate({
178
- injectionStatement: inputs.injectionStatement,
179
- targetUdeStatements: inputs.targetUdeStatements,
180
- }, deps.generateOptions);
181
- const proposalIds = [];
182
- const errors = [];
183
- for (const candidate of candidates) {
184
- const params = {
185
- realityTreeId: inputs.realityTreeId,
186
- proposalKind: 'add_node',
187
- observedState: 'injection introduces a new undesired effect',
188
- proposedCorrection: candidate,
189
- proposedMetadata: {
190
- statement: candidate,
191
- nodeType: 'undesired_effect',
192
- viewScope: 'frt_only',
193
- sourceInjectionId: inputs.injectionNodeId,
194
- isNegativeBranch: true,
195
- },
196
- };
197
- if (inputs.focusId)
198
- params.focusId = inputs.focusId;
199
- try {
200
- const res = await callApi('crt_drift_proposal_create', params);
201
- const id = res?.proposal?.id;
202
- if (typeof id === 'string')
203
- proposalIds.push(id);
204
- }
205
- catch (err) {
206
- errors.push(`negative-branch proposal create failed: ${err.message}`);
207
- }
208
- }
209
- // Generation completed (did not throw) -- stamp the durable per-injection
210
- // marker so a clean (zero-candidate) pass leaves a trace. This is the whole
211
- // point: presentability gates on a pass having RUN, never on the branch set
212
- // being non-empty. Stamping is best-effort -- a write failure leaves the
213
- // marker null (the injection re-runs next tick) but never aborts the result.
214
- //
215
- // RESIDUAL (documented, tolerated): the "RUN" signal is "generate() did not
216
- // throw", so a DEGRADED model call that returns an empty body would be
217
- // recorded as a clean pass (zero candidates, marker stamped) even though it
218
- // surfaced nothing real. We accept this for two reasons: (1) the dominant
219
- // silent-failure mode -- the `--bare` flag printing "Not logged in" and
220
- // exiting 1 -- was removed (see buildNegativeBranchCliArgs), so a non-zero
221
- // exit now throws and correctly leaves the marker null; and (2) a genuinely
222
- // empty negative-branch set is the LEGITIMATE clean case this marker exists to
223
- // record, and "did the model degrade vs honestly find nothing" is not
224
- // mechanically separable here without a check that could itself be confidently
225
- // wrong -- the negative-branch signal is deliberately advisory, not a hard
226
- // gate, so a rare false-clean costs an advisory hint, never a blocked tree.
227
- let passRanAt = null;
228
- const stampedAt = now();
229
- try {
230
- await callApi('reality_tree_node_update', {
231
- nodeId: inputs.injectionNodeId,
232
- negativeBranchPassRanAt: stampedAt,
233
- });
234
- passRanAt = stampedAt;
235
- }
236
- catch (err) {
237
- errors.push(`negative-branch pass-marker stamp failed: ${err.message}`);
238
- }
239
- return { candidates, proposalIds, errors, passRanAt };
240
- }
241
- //# sourceMappingURL=negative-branch.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"negative-branch.js","sourceRoot":"","sources":["../src/negative-branch.ts"],"names":[],"mappings":"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"}
@@ -1,34 +0,0 @@
1
- /**
2
- * Threshold for the shortfall-disposition attempt bound.
3
- *
4
- * The CANONICAL declaration (Zod schema, ENV_VAR_METADATA entry, default,
5
- * description) lives in packages/daemon-core/src/env-config.ts, exactly like the
6
- * stall-detector thresholds in stall-detector-config.ts.
7
- *
8
- * It is read RAW here rather than through loadEnvConfig() for one reason:
9
- * @telora/daemon-core is REGISTRY-INSTALLED, not a workspace symlink, so
10
- * packages/daemon compiles and runs against the PUBLISHED dist. A field added to
11
- * daemon-core's source is invisible to loadEnvConfig() here until a publish
12
- * lands and the pin moves. This is the same registry-lag workaround
13
- * stall-detectors.ts documents for escalation kinds.
14
- *
15
- * The raw read is allowlisted in scripts/lint-config.json under "env-reads"
16
- * with that reason. WHEN daemon-core >0.2.69 IS PUBLISHED AND PINNED: delete the
17
- * allowlist entry and change this to
18
- * `loadEnvConfig().TELORA_SHORTFALL_DISPOSITION_ATTEMPT_CAP`.
19
- *
20
- * @module shortfall-disposition-config
21
- */
22
- /**
23
- * Max scoped disposition passes armed per focus before the daemon stops arming
24
- * and escalates instead.
25
- *
26
- * Invalid values (non-numeric, <= 0) fall back to the default rather than
27
- * disabling the bound: a zero or negative cap would escalate immediately on
28
- * every held focus, and a NaN would compare false forever and never escalate --
29
- * the permanent silent wait this bound exists to prevent. Once daemon-core is
30
- * republished, Zod's positiveInt does this validation at startup and fails loud,
31
- * which is strictly better; this is the interim.
32
- */
33
- export declare function resolveShortfallDispositionAttemptCap(env?: NodeJS.ProcessEnv): number;
34
- //# sourceMappingURL=shortfall-disposition-config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"shortfall-disposition-config.d.ts","sourceRoot":"","sources":["../src/shortfall-disposition-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAKH;;;;;;;;;;GAUG;AACH,wBAAgB,qCAAqC,CACnD,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,CAUR"}
@@ -1,46 +0,0 @@
1
- /**
2
- * Threshold for the shortfall-disposition attempt bound.
3
- *
4
- * The CANONICAL declaration (Zod schema, ENV_VAR_METADATA entry, default,
5
- * description) lives in packages/daemon-core/src/env-config.ts, exactly like the
6
- * stall-detector thresholds in stall-detector-config.ts.
7
- *
8
- * It is read RAW here rather than through loadEnvConfig() for one reason:
9
- * @telora/daemon-core is REGISTRY-INSTALLED, not a workspace symlink, so
10
- * packages/daemon compiles and runs against the PUBLISHED dist. A field added to
11
- * daemon-core's source is invisible to loadEnvConfig() here until a publish
12
- * lands and the pin moves. This is the same registry-lag workaround
13
- * stall-detectors.ts documents for escalation kinds.
14
- *
15
- * The raw read is allowlisted in scripts/lint-config.json under "env-reads"
16
- * with that reason. WHEN daemon-core >0.2.69 IS PUBLISHED AND PINNED: delete the
17
- * allowlist entry and change this to
18
- * `loadEnvConfig().TELORA_SHORTFALL_DISPOSITION_ATTEMPT_CAP`.
19
- *
20
- * @module shortfall-disposition-config
21
- */
22
- /** Must match the daemon-core default so the two cannot silently disagree. */
23
- const DEFAULT_SHORTFALL_DISPOSITION_ATTEMPT_CAP = 3;
24
- /**
25
- * Max scoped disposition passes armed per focus before the daemon stops arming
26
- * and escalates instead.
27
- *
28
- * Invalid values (non-numeric, <= 0) fall back to the default rather than
29
- * disabling the bound: a zero or negative cap would escalate immediately on
30
- * every held focus, and a NaN would compare false forever and never escalate --
31
- * the permanent silent wait this bound exists to prevent. Once daemon-core is
32
- * republished, Zod's positiveInt does this validation at startup and fails loud,
33
- * which is strictly better; this is the interim.
34
- */
35
- export function resolveShortfallDispositionAttemptCap(env = process.env) {
36
- const raw = env.TELORA_SHORTFALL_DISPOSITION_ATTEMPT_CAP;
37
- if (raw === undefined || raw.trim() === '') {
38
- return DEFAULT_SHORTFALL_DISPOSITION_ATTEMPT_CAP;
39
- }
40
- const parsed = Number(raw);
41
- if (!Number.isFinite(parsed) || !Number.isInteger(parsed) || parsed <= 0) {
42
- return DEFAULT_SHORTFALL_DISPOSITION_ATTEMPT_CAP;
43
- }
44
- return parsed;
45
- }
46
- //# sourceMappingURL=shortfall-disposition-config.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"shortfall-disposition-config.js","sourceRoot":"","sources":["../src/shortfall-disposition-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,8EAA8E;AAC9E,MAAM,yCAAyC,GAAG,CAAC,CAAC;AAEpD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,qCAAqC,CACnD,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,GAAG,GAAG,GAAG,CAAC,wCAAwC,CAAC;IACzD,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAC3C,OAAO,yCAAyC,CAAC;IACnD,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QACzE,OAAO,yCAAyC,CAAC;IACnD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}