@getrift/rift 0.1.0-beta.18 → 0.1.0-beta.19

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 (98) hide show
  1. package/dist/src/capture/auto-repair.d.ts +110 -0
  2. package/dist/src/capture/auto-repair.d.ts.map +1 -0
  3. package/dist/src/capture/auto-repair.js +269 -0
  4. package/dist/src/capture/auto-repair.js.map +1 -0
  5. package/dist/src/capture/codex-cli-triage-provider.d.ts.map +1 -1
  6. package/dist/src/capture/codex-cli-triage-provider.js +4 -3
  7. package/dist/src/capture/codex-cli-triage-provider.js.map +1 -1
  8. package/dist/src/capture/recover-quarantine.d.ts +11 -0
  9. package/dist/src/capture/recover-quarantine.d.ts.map +1 -1
  10. package/dist/src/capture/recover-quarantine.js +30 -4
  11. package/dist/src/capture/recover-quarantine.js.map +1 -1
  12. package/dist/src/cli/commands/capture-recover.d.ts.map +1 -1
  13. package/dist/src/cli/commands/capture-recover.js +7 -0
  14. package/dist/src/cli/commands/capture-recover.js.map +1 -1
  15. package/dist/src/cli/commands/capture.d.ts.map +1 -1
  16. package/dist/src/cli/commands/capture.js +48 -1
  17. package/dist/src/cli/commands/capture.js.map +1 -1
  18. package/dist/src/cli/commands/feedback.d.ts +12 -0
  19. package/dist/src/cli/commands/feedback.d.ts.map +1 -1
  20. package/dist/src/cli/commands/feedback.js +84 -2
  21. package/dist/src/cli/commands/feedback.js.map +1 -1
  22. package/dist/src/cli/commands/onboard.d.ts +33 -2
  23. package/dist/src/cli/commands/onboard.d.ts.map +1 -1
  24. package/dist/src/cli/commands/onboard.js +243 -35
  25. package/dist/src/cli/commands/onboard.js.map +1 -1
  26. package/dist/src/cli/feedback/feedback-config.d.ts +43 -0
  27. package/dist/src/cli/feedback/feedback-config.d.ts.map +1 -1
  28. package/dist/src/cli/feedback/feedback-config.js +125 -4
  29. package/dist/src/cli/feedback/feedback-config.js.map +1 -1
  30. package/dist/src/cli/feedback/invite.d.ts +17 -0
  31. package/dist/src/cli/feedback/invite.d.ts.map +1 -0
  32. package/dist/src/cli/feedback/invite.js +67 -0
  33. package/dist/src/cli/feedback/invite.js.map +1 -0
  34. package/dist/src/cli/feedback/relay-secret-store.d.ts +32 -0
  35. package/dist/src/cli/feedback/relay-secret-store.d.ts.map +1 -0
  36. package/dist/src/cli/feedback/relay-secret-store.js +137 -0
  37. package/dist/src/cli/feedback/relay-secret-store.js.map +1 -0
  38. package/dist/src/cli/http-client.d.ts +17 -4
  39. package/dist/src/cli/http-client.d.ts.map +1 -1
  40. package/dist/src/cli/http-client.js +18 -7
  41. package/dist/src/cli/http-client.js.map +1 -1
  42. package/dist/src/cli/status/friend-header.d.ts.map +1 -1
  43. package/dist/src/cli/status/friend-header.js +63 -20
  44. package/dist/src/cli/status/friend-header.js.map +1 -1
  45. package/dist/src/config/schema.d.ts +79 -0
  46. package/dist/src/config/schema.d.ts.map +1 -1
  47. package/dist/src/config/schema.js +44 -0
  48. package/dist/src/config/schema.js.map +1 -1
  49. package/dist/src/diagnostics/codex-preflight.d.ts +33 -0
  50. package/dist/src/diagnostics/codex-preflight.d.ts.map +1 -0
  51. package/dist/src/diagnostics/codex-preflight.js +63 -0
  52. package/dist/src/diagnostics/codex-preflight.js.map +1 -0
  53. package/dist/src/diagnostics/doctor.d.ts +1 -1
  54. package/dist/src/diagnostics/doctor.d.ts.map +1 -1
  55. package/dist/src/diagnostics/doctor.js +69 -20
  56. package/dist/src/diagnostics/doctor.js.map +1 -1
  57. package/dist/src/diagnostics/repair-prompt.d.ts.map +1 -1
  58. package/dist/src/diagnostics/repair-prompt.js +10 -1
  59. package/dist/src/diagnostics/repair-prompt.js.map +1 -1
  60. package/dist/src/jobs/handlers/save.d.ts.map +1 -1
  61. package/dist/src/jobs/handlers/save.js +5 -4
  62. package/dist/src/jobs/handlers/save.js.map +1 -1
  63. package/dist/src/jobs/worker-entry.d.ts.map +1 -1
  64. package/dist/src/jobs/worker-entry.js +20 -7
  65. package/dist/src/jobs/worker-entry.js.map +1 -1
  66. package/dist/src/jobs/worker-process.d.ts +11 -0
  67. package/dist/src/jobs/worker-process.d.ts.map +1 -1
  68. package/dist/src/jobs/worker-process.js +37 -4
  69. package/dist/src/jobs/worker-process.js.map +1 -1
  70. package/dist/src/main.js +122 -42
  71. package/dist/src/main.js.map +1 -1
  72. package/dist/src/observability/onboarding-metric.d.ts +16 -0
  73. package/dist/src/observability/onboarding-metric.d.ts.map +1 -1
  74. package/dist/src/observability/onboarding-metric.js +8 -1
  75. package/dist/src/observability/onboarding-metric.js.map +1 -1
  76. package/dist/src/providers/codex-cli-metadata-extraction.d.ts +1 -0
  77. package/dist/src/providers/codex-cli-metadata-extraction.d.ts.map +1 -1
  78. package/dist/src/providers/codex-cli-metadata-extraction.js +6 -2
  79. package/dist/src/providers/codex-cli-metadata-extraction.js.map +1 -1
  80. package/dist/src/providers/codex-cli-model.d.ts +61 -0
  81. package/dist/src/providers/codex-cli-model.d.ts.map +1 -0
  82. package/dist/src/providers/codex-cli-model.js +194 -0
  83. package/dist/src/providers/codex-cli-model.js.map +1 -0
  84. package/dist/src/providers/codex-cli-runner.d.ts +16 -0
  85. package/dist/src/providers/codex-cli-runner.d.ts.map +1 -1
  86. package/dist/src/providers/codex-cli-runner.js +67 -12
  87. package/dist/src/providers/codex-cli-runner.js.map +1 -1
  88. package/dist/src/providers/conversation-generation.d.ts.map +1 -1
  89. package/dist/src/providers/conversation-generation.js +26 -13
  90. package/dist/src/providers/conversation-generation.js.map +1 -1
  91. package/dist/src/server/app.d.ts.map +1 -1
  92. package/dist/src/server/app.js +12 -8
  93. package/dist/src/server/app.js.map +1 -1
  94. package/dist/src/server/routes/friend-status.d.ts +37 -0
  95. package/dist/src/server/routes/friend-status.d.ts.map +1 -1
  96. package/dist/src/server/routes/friend-status.js +43 -9
  97. package/dist/src/server/routes/friend-status.js.map +1 -1
  98. package/package.json +1 -1
@@ -0,0 +1,110 @@
1
+ import { z } from "zod";
2
+ import { type RecoverQuarantineDeps, type RecoveryReport } from "./recover-quarantine.js";
3
+ /**
4
+ * How many times a single parked session (at one fingerprint) is auto-retried
5
+ * before Rift stops and asks the user to run the manual repair. Low on purpose:
6
+ * the daemon retries roughly once per capture tick (hourly), so three attempts
7
+ * spans a few hours before declaring "could not save automatically", and the
8
+ * manual `rift doctor repair` path is always available regardless of budget.
9
+ */
10
+ export declare const MAX_AUTO_REPAIR_ATTEMPTS = 3;
11
+ /**
12
+ * How long to stop attempting auto-repair after a pass fails ONLY because
13
+ * saving was down (Voyage revoked/outage — the save handler needs a valid
14
+ * Voyage key). This is an infrastructure backoff, distinct from the
15
+ * per-session retry budget: a save outage is not any one session's fault, so
16
+ * it must not exhaust a session (see `applyBudgetFromReport`), but it also
17
+ * shouldn't make the daemon re-summarize every parked session via Codex on
18
+ * every hourly tick for the whole outage. The cooldown bounds that cost to one
19
+ * pass per window; it is cleared early the moment a save succeeds. Sized to a
20
+ * few default capture ticks (interval default is 1h).
21
+ */
22
+ export declare const SAVE_FAILURE_COOLDOWN_MS: number;
23
+ declare const RepairBudgetSchema: z.ZodObject<{
24
+ sessions: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
25
+ /** Failed auto-repair attempts for this session+fingerprint. */
26
+ attempts: z.ZodNumber;
27
+ last_attempt_at: z.ZodString;
28
+ last_error: z.ZodOptional<z.ZodString>;
29
+ }, "strip", z.ZodTypeAny, {
30
+ attempts: number;
31
+ last_attempt_at: string;
32
+ last_error?: string | undefined;
33
+ }, {
34
+ attempts: number;
35
+ last_attempt_at: string;
36
+ last_error?: string | undefined;
37
+ }>>>;
38
+ /**
39
+ * ISO timestamp until which auto-repair backs off because saving recently
40
+ * failed (infrastructure, not a session fault). Absent when not cooling down.
41
+ */
42
+ save_blocked_until: z.ZodOptional<z.ZodString>;
43
+ }, "strip", z.ZodTypeAny, {
44
+ sessions: Record<string, {
45
+ attempts: number;
46
+ last_attempt_at: string;
47
+ last_error?: string | undefined;
48
+ }>;
49
+ save_blocked_until?: string | undefined;
50
+ }, {
51
+ sessions?: Record<string, {
52
+ attempts: number;
53
+ last_attempt_at: string;
54
+ last_error?: string | undefined;
55
+ }> | undefined;
56
+ save_blocked_until?: string | undefined;
57
+ }>;
58
+ export type RepairBudget = z.infer<typeof RepairBudgetSchema>;
59
+ export declare function loadRepairBudget(dataDir: string): RepairBudget;
60
+ export declare function saveRepairBudget(dataDir: string, budget: RepairBudget): Promise<void>;
61
+ /**
62
+ * Clear the global save-infra cooldown. Call this whenever ANY daemon save
63
+ * succeeds — a normal capture save proves the Voyage/save path is healthy
64
+ * again, which `maybeRunAutoRepair` can't observe on its own (it returns early
65
+ * while cooled down, so it never reaches a save to learn saving works). Without
66
+ * this, recovery would idle for up to the full cooldown window after an outage
67
+ * clears. Cheap and best-effort: a no-op (no write) when no cooldown is set.
68
+ */
69
+ export declare function clearSaveFailureCooldown(dataDir: string): Promise<void>;
70
+ export interface ParkedClassification {
71
+ /** Total distinct parked sessions still un-recovered (state of the world). */
72
+ parked: number;
73
+ /** Parked sessions Rift is still auto-attempting (budget not exhausted). */
74
+ repairing: number;
75
+ /** Parked sessions whose retry budget is exhausted — need a manual save. */
76
+ failed: number;
77
+ }
78
+ /**
79
+ * Split the parked-oversized sessions into "Rift is still saving these" vs.
80
+ * "Rift gave up and the user must save these manually", using the retry
81
+ * budget. Drives the honest friend-facing status copy. Pure read — no IO
82
+ * beyond loading the quarantine records, recovery state, and budget.
83
+ */
84
+ export declare function classifyParkedOversizedSessions(deps: Pick<RecoverQuarantineDeps, "dataDir" | "quarantineDir">, maxAttempts?: number): ParkedClassification;
85
+ /** Test-only: whether a background repair is currently running. */
86
+ export declare function isAutoRepairInFlight(): boolean;
87
+ export interface MaybeRunAutoRepairDeps {
88
+ /**
89
+ * Everything `runRecoverQuarantine` needs EXCEPT `skipSession` (this module
90
+ * supplies the budget gate). Provide the real Codex summarizer + a daemon
91
+ * `saveFn`; `dryRun` is never set here (auto-repair always saves).
92
+ */
93
+ recover: Omit<RecoverQuarantineDeps, "skipSession" | "dryRun">;
94
+ /** Bounded retry ceiling; defaults to MAX_AUTO_REPAIR_ATTEMPTS. */
95
+ maxAttempts?: number;
96
+ /** Optional progress logger (daemon wires this to stderr). */
97
+ log?: (message: string) => void;
98
+ }
99
+ /**
100
+ * Run a background recovery pass over parked oversized sessions, if any are
101
+ * still within their retry budget and no repair is already running.
102
+ *
103
+ * Returns the recovery report, or null when nothing was attempted (already
104
+ * running, or no repairable sessions). Updates the retry budget from the
105
+ * report: a recovered session's budget entry is cleared, a failed session's
106
+ * attempt count is incremented (and exhausts after `maxAttempts`).
107
+ */
108
+ export declare function maybeRunAutoRepair(deps: MaybeRunAutoRepairDeps): Promise<RecoveryReport | null>;
109
+ export {};
110
+ //# sourceMappingURL=auto-repair.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-repair.d.ts","sourceRoot":"","sources":["../../../src/capture/auto-repair.ts"],"names":[],"mappings":"AA8BA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAGL,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAEjC;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,QAAqB,CAAC;AAW3D,QAAA,MAAM,kBAAkB;;QANtB,gEAAgE;;;;;;;;;;;;;IAQhE;;;OAGG;;;;;;;;;;;;;;;;EAEH,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAO9D,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAW9D;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,IAAI,CAAC,CAGf;AAED;;;;;;;GAOG;AACH,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAS7E;AAED,MAAM,WAAW,oBAAoB;IACnC,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,SAAS,GAAG,eAAe,CAAC,EAC9D,WAAW,GAAE,MAAiC,GAC7C,oBAAoB,CActB;AAUD,mEAAmE;AACnE,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED,MAAM,WAAW,sBAAsB;IACrC;;;;OAIG;IACH,OAAO,EAAE,IAAI,CAAC,qBAAqB,EAAE,aAAa,GAAG,QAAQ,CAAC,CAAC;IAC/D,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8DAA8D;IAC9D,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CA8DhC"}
@@ -0,0 +1,269 @@
1
+ /**
2
+ * Background self-repair for oversized Codex CLI sessions.
3
+ *
4
+ * Auto-capture parks sessions larger than `capture.codex_cli.max_session_bytes`
5
+ * in `data/quarantine/` rather than failing (see `auto-capture.ts`). Recovery
6
+ * — chunked summarize + one `/save` per session — already exists in
7
+ * `recover-quarantine.ts` and is reachable manually via
8
+ * `rift doctor repair capture-large-sessions`.
9
+ *
10
+ * This module makes that recovery happen ON ITS OWN so a friend never has to
11
+ * run the repair command. The daemon calls `maybeRunAutoRepair` after each
12
+ * capture run; it:
13
+ *
14
+ * 1. Reuses `runRecoverQuarantine` verbatim (no second recovery path), so
15
+ * idempotency and regrown-session replacement are preserved.
16
+ * 2. Bounds work with a per-session retry budget persisted to
17
+ * `data/quarantine-repair-budget.json`. A session that fails
18
+ * `MAX_AUTO_REPAIR_ATTEMPTS` times is no longer auto-attempted — it is
19
+ * surfaced to the user as a manual-fallback warning instead of being
20
+ * retried forever. The budget is keyed by `<sessionId>:<fingerprint>`,
21
+ * so a session that grows (new fingerprint) gets a fresh budget, exactly
22
+ * as recovery treats it as new work.
23
+ * 3. Never runs two repairs at once (a module-level in-flight guard), so an
24
+ * overlapping capture tick cannot launch a duplicate concurrent repair.
25
+ *
26
+ * The recovery itself is long (one Codex CLI call per chunk per session), so
27
+ * the daemon fires this without awaiting it — status/doctor reads stay fast.
28
+ */
29
+ import fs from "node:fs";
30
+ import path from "node:path";
31
+ import { z } from "zod";
32
+ import { atomicWrite } from "../storage/atomic.js";
33
+ import { listParkedOversizedSessions, runRecoverQuarantine, } from "./recover-quarantine.js";
34
+ /**
35
+ * How many times a single parked session (at one fingerprint) is auto-retried
36
+ * before Rift stops and asks the user to run the manual repair. Low on purpose:
37
+ * the daemon retries roughly once per capture tick (hourly), so three attempts
38
+ * spans a few hours before declaring "could not save automatically", and the
39
+ * manual `rift doctor repair` path is always available regardless of budget.
40
+ */
41
+ export const MAX_AUTO_REPAIR_ATTEMPTS = 3;
42
+ /**
43
+ * How long to stop attempting auto-repair after a pass fails ONLY because
44
+ * saving was down (Voyage revoked/outage — the save handler needs a valid
45
+ * Voyage key). This is an infrastructure backoff, distinct from the
46
+ * per-session retry budget: a save outage is not any one session's fault, so
47
+ * it must not exhaust a session (see `applyBudgetFromReport`), but it also
48
+ * shouldn't make the daemon re-summarize every parked session via Codex on
49
+ * every hourly tick for the whole outage. The cooldown bounds that cost to one
50
+ * pass per window; it is cleared early the moment a save succeeds. Sized to a
51
+ * few default capture ticks (interval default is 1h).
52
+ */
53
+ export const SAVE_FAILURE_COOLDOWN_MS = 6 * 60 * 60 * 1000;
54
+ const REPAIR_BUDGET_FILE = "quarantine-repair-budget.json";
55
+ const RepairBudgetEntrySchema = z.object({
56
+ /** Failed auto-repair attempts for this session+fingerprint. */
57
+ attempts: z.number().int().nonnegative(),
58
+ last_attempt_at: z.string(),
59
+ last_error: z.string().optional(),
60
+ });
61
+ const RepairBudgetSchema = z.object({
62
+ sessions: z.record(z.string(), RepairBudgetEntrySchema).default({}),
63
+ /**
64
+ * ISO timestamp until which auto-repair backs off because saving recently
65
+ * failed (infrastructure, not a session fault). Absent when not cooling down.
66
+ */
67
+ save_blocked_until: z.string().optional(),
68
+ });
69
+ /** Budget key — fingerprint-scoped so a regrown session retries fresh. */
70
+ function budgetKey(sessionId, fingerprint) {
71
+ return `${sessionId}:${fingerprint}`;
72
+ }
73
+ export function loadRepairBudget(dataDir) {
74
+ const file = path.join(dataDir, REPAIR_BUDGET_FILE);
75
+ if (!fs.existsSync(file))
76
+ return { sessions: {} };
77
+ let raw;
78
+ try {
79
+ raw = JSON.parse(fs.readFileSync(file, "utf-8"));
80
+ }
81
+ catch {
82
+ return { sessions: {} };
83
+ }
84
+ const parsed = RepairBudgetSchema.safeParse(raw);
85
+ return parsed.success ? parsed.data : { sessions: {} };
86
+ }
87
+ export async function saveRepairBudget(dataDir, budget) {
88
+ const file = path.join(dataDir, REPAIR_BUDGET_FILE);
89
+ await atomicWrite(file, JSON.stringify(budget, null, 2));
90
+ }
91
+ /**
92
+ * Clear the global save-infra cooldown. Call this whenever ANY daemon save
93
+ * succeeds — a normal capture save proves the Voyage/save path is healthy
94
+ * again, which `maybeRunAutoRepair` can't observe on its own (it returns early
95
+ * while cooled down, so it never reaches a save to learn saving works). Without
96
+ * this, recovery would idle for up to the full cooldown window after an outage
97
+ * clears. Cheap and best-effort: a no-op (no write) when no cooldown is set.
98
+ */
99
+ export async function clearSaveFailureCooldown(dataDir) {
100
+ const budget = loadRepairBudget(dataDir);
101
+ if (budget.save_blocked_until === undefined)
102
+ return;
103
+ delete budget.save_blocked_until;
104
+ try {
105
+ await saveRepairBudget(dataDir, budget);
106
+ }
107
+ catch {
108
+ // best-effort
109
+ }
110
+ }
111
+ /**
112
+ * Split the parked-oversized sessions into "Rift is still saving these" vs.
113
+ * "Rift gave up and the user must save these manually", using the retry
114
+ * budget. Drives the honest friend-facing status copy. Pure read — no IO
115
+ * beyond loading the quarantine records, recovery state, and budget.
116
+ */
117
+ export function classifyParkedOversizedSessions(deps, maxAttempts = MAX_AUTO_REPAIR_ATTEMPTS) {
118
+ const parkedRecords = listParkedOversizedSessions(deps);
119
+ if (parkedRecords.length === 0) {
120
+ return { parked: 0, repairing: 0, failed: 0 };
121
+ }
122
+ const budget = loadRepairBudget(deps.dataDir);
123
+ let repairing = 0;
124
+ let failed = 0;
125
+ for (const record of parkedRecords) {
126
+ const entry = budget.sessions[budgetKey(record.session_id, record.fingerprint)];
127
+ if (entry && entry.attempts >= maxAttempts)
128
+ failed += 1;
129
+ else
130
+ repairing += 1;
131
+ }
132
+ return { parked: parkedRecords.length, repairing, failed };
133
+ }
134
+ /**
135
+ * Module-level in-flight guard. A daemon is a single process, so a boolean
136
+ * flag is enough to ensure a long-running repair started by one capture tick
137
+ * is never duplicated by the next tick (or by the startup run overlapping the
138
+ * first interval). Reset in `finally` so a thrown repair doesn't wedge it.
139
+ */
140
+ let repairInFlight = false;
141
+ /** Test-only: whether a background repair is currently running. */
142
+ export function isAutoRepairInFlight() {
143
+ return repairInFlight;
144
+ }
145
+ /**
146
+ * Run a background recovery pass over parked oversized sessions, if any are
147
+ * still within their retry budget and no repair is already running.
148
+ *
149
+ * Returns the recovery report, or null when nothing was attempted (already
150
+ * running, or no repairable sessions). Updates the retry budget from the
151
+ * report: a recovered session's budget entry is cleared, a failed session's
152
+ * attempt count is incremented (and exhausts after `maxAttempts`).
153
+ */
154
+ export async function maybeRunAutoRepair(deps) {
155
+ const log = deps.log ?? (() => { });
156
+ const maxAttempts = deps.maxAttempts ?? MAX_AUTO_REPAIR_ATTEMPTS;
157
+ const dataDir = deps.recover.dataDir;
158
+ if (repairInFlight) {
159
+ log("auto-repair: a repair is already running — skipping this tick");
160
+ return null;
161
+ }
162
+ const budget = loadRepairBudget(dataDir);
163
+ // Infrastructure backoff: a recent pass failed only because saving was down
164
+ // (Voyage). Don't re-summarize via Codex until the cooldown expires — a save
165
+ // outage that re-runs every tick is pure wasted cost. Cleared early when a
166
+ // save succeeds (see applyBudgetFromReport).
167
+ const nowMs = (deps.recover.now ? deps.recover.now() : new Date()).getTime();
168
+ const blockedUntilMs = budget.save_blocked_until
169
+ ? Date.parse(budget.save_blocked_until)
170
+ : NaN;
171
+ if (!Number.isNaN(blockedUntilMs) && nowMs < blockedUntilMs) {
172
+ log(`auto-repair: saving recently failed — backing off until ${budget.save_blocked_until}`);
173
+ return null;
174
+ }
175
+ // Only attempt sessions still within budget. Exhausted ones are surfaced as
176
+ // a manual-fallback warning, not retried. Pass `deps.recover` so a caller
177
+ // that overrides `quarantineDir` is honored here too (not just inside
178
+ // `runRecoverQuarantine`), keeping the precheck and the recovery in sync.
179
+ const repairable = listParkedOversizedSessions(deps.recover).filter((record) => (budget.sessions[budgetKey(record.session_id, record.fingerprint)]?.attempts ?? 0) <
180
+ maxAttempts);
181
+ if (repairable.length === 0)
182
+ return null;
183
+ const repairableKeys = new Set(repairable.map((record) => budgetKey(record.session_id, record.fingerprint)));
184
+ repairInFlight = true;
185
+ log(`auto-repair: recovering ${repairable.length} parked Codex session${repairable.length === 1 ? "" : "s"} in the background`);
186
+ try {
187
+ const report = await runRecoverQuarantine({
188
+ ...deps.recover,
189
+ skipSession: (record) => !repairableKeys.has(budgetKey(record.session_id, record.fingerprint)),
190
+ });
191
+ await applyBudgetFromReport(dataDir, report, deps.recover.now);
192
+ log(`auto-repair: ${report.recovered} recovered, ${report.failed + report.missing_source} could not be saved`);
193
+ return report;
194
+ }
195
+ finally {
196
+ repairInFlight = false;
197
+ }
198
+ }
199
+ /**
200
+ * Fold a recovery report into the retry budget: clear successes, increment
201
+ * failures. Re-reads the budget under the in-flight guard so it overlays the
202
+ * freshest on-disk value. Best-effort persistence — a budget write failure
203
+ * just means a session may get one extra attempt next tick, never a crash.
204
+ */
205
+ async function applyBudgetFromReport(dataDir, report, now) {
206
+ const budget = loadRepairBudget(dataDir);
207
+ const nowDate = now ? now() : new Date();
208
+ const nowIso = nowDate.toISOString();
209
+ let changed = false;
210
+ for (const result of report.results) {
211
+ const key = budgetKey(result.session_id, result.fingerprint);
212
+ if (result.outcome === "recovered") {
213
+ if (budget.sessions[key]) {
214
+ delete budget.sessions[key];
215
+ changed = true;
216
+ }
217
+ continue;
218
+ }
219
+ // Only SESSION-LOCAL failures count against the budget: a chunk that won't
220
+ // summarize, or a session that parses to nothing. These are intrinsic to
221
+ // this session — retrying forever won't help, so cap them.
222
+ //
223
+ // A `save_failed` is deliberately NOT budgeted: the save path needs Voyage
224
+ // (the queue's save handler throws "save requires VOYAGE_API_KEY"), so a
225
+ // missing/revoked key or a Voyage outage makes EVERY session's save fail —
226
+ // an infrastructure problem, not the session's fault. Budgeting it would
227
+ // exhaust a session during the outage and then refuse to self-repair once
228
+ // the key is fixed, breaking the whole point of background recovery. Left
229
+ // un-budgeted, the session stays "repairing" and is retried on the next
230
+ // tick, so it self-heals the moment saving works again. (`missing_source`
231
+ // never reaches here — `listParkedOversizedSessions` already excludes a
232
+ // session whose jsonl is gone, so it's neither attempted nor classified.)
233
+ if (result.outcome === "failed" &&
234
+ (result.reason === "summarize_failed" || result.reason === "empty_session")) {
235
+ const prior = budget.sessions[key];
236
+ budget.sessions[key] = {
237
+ attempts: (prior?.attempts ?? 0) + 1,
238
+ last_attempt_at: nowIso,
239
+ ...(result.error ? { last_error: result.error } : {}),
240
+ };
241
+ changed = true;
242
+ }
243
+ }
244
+ // Global save-infra cooldown. A save success proves the path works → clear
245
+ // any cooldown immediately. Otherwise, if this pass failed only because
246
+ // saving was down, start (or refresh) the backoff so we don't re-summarize
247
+ // every tick during a Voyage outage.
248
+ const anyRecovered = report.results.some((r) => r.outcome === "recovered");
249
+ const anySaveFailed = report.results.some((r) => r.outcome === "failed" && r.reason === "save_failed");
250
+ if (anyRecovered) {
251
+ if (budget.save_blocked_until !== undefined) {
252
+ delete budget.save_blocked_until;
253
+ changed = true;
254
+ }
255
+ }
256
+ else if (anySaveFailed) {
257
+ budget.save_blocked_until = new Date(nowDate.getTime() + SAVE_FAILURE_COOLDOWN_MS).toISOString();
258
+ changed = true;
259
+ }
260
+ if (changed) {
261
+ try {
262
+ await saveRepairBudget(dataDir, budget);
263
+ }
264
+ catch {
265
+ // best-effort
266
+ }
267
+ }
268
+ }
269
+ //# sourceMappingURL=auto-repair.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-repair.js","sourceRoot":"","sources":["../../../src/capture/auto-repair.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"codex-cli-triage-provider.d.ts","sourceRoot":"","sources":["../../../src/capture/codex-cli-triage-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAC;AAK9B,OAAO,KAAK,EACV,2BAA2B,EAC3B,UAAU,EACX,MAAM,mBAAmB,CAAC;AAkD3B,qBAAa,sBAAuB,YAAW,2BAA2B;IAEtE,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,GAAE;QACxB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;KACf;IAGR,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM;IAIzC,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAKjD,cAAc,CAClB,KAAK,EAAE,WAAW,GACjB,OAAO,CAAC;QAAE,MAAM,EAAE,YAAY,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,CAAC;YA+BxC,SAAS;CAmCxB"}
1
+ {"version":3,"file":"codex-cli-triage-provider.d.ts","sourceRoot":"","sources":["../../../src/capture/codex-cli-triage-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,YAAY,EAClB,MAAM,sBAAsB,CAAC;AAK9B,OAAO,KAAK,EACV,2BAA2B,EAC3B,UAAU,EACX,MAAM,mBAAmB,CAAC;AAiD3B,qBAAa,sBAAuB,YAAW,2BAA2B;IAEtE,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,GAAE;QACxB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;KACf;IAGR,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM;IAIzC,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAKjD,cAAc,CAClB,KAAK,EAAE,WAAW,GACjB,OAAO,CAAC;QAAE,MAAM,EAAE,YAAY,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,CAAC;YA+BxC,SAAS;CAoCxB"}
@@ -1,6 +1,6 @@
1
1
  import { TRIAGE_VERSION, } from "./triage-provider.js";
2
2
  import { scoreHistoricalTriage, } from "./triage-lane.js";
3
- import { CODEX_CLI_OVERRIDE_MODEL, CODEX_CLI_OVERRIDE_PROVIDER, } from "../providers/operator-overrides.js";
3
+ import { CODEX_CLI_OVERRIDE_PROVIDER } from "../providers/operator-overrides.js";
4
4
  import { runCodexCliJson } from "../providers/codex-cli-runner.js";
5
5
  const TRIAGE_PROMPT = `You are a triage classifier for a personal knowledge base. Given a conversation between a user and an AI assistant, decide whether it should be saved to long-term memory.
6
6
 
@@ -67,7 +67,7 @@ export class CodexCliTriageProvider {
67
67
  summary: parsed.summary,
68
68
  topics: parsed.topics,
69
69
  rationale: parsed.rationale,
70
- model: CODEX_CLI_OVERRIDE_MODEL,
70
+ model: parsed.model,
71
71
  provider: CODEX_CLI_OVERRIDE_PROVIDER,
72
72
  version: TRIAGE_VERSION,
73
73
  score_breakdown: scoring.debug.score_breakdown,
@@ -78,7 +78,7 @@ export class CodexCliTriageProvider {
78
78
  }
79
79
  async runPrompt(input) {
80
80
  const prompt = `${TRIAGE_PROMPT}${input.content}`;
81
- const { output } = await runCodexCliJson({
81
+ const { output, model } = await runCodexCliJson({
82
82
  prompt,
83
83
  schema: TRIAGE_OUTPUT_SCHEMA,
84
84
  ...(this.options.cwd ? { cwd: this.options.cwd } : {}),
@@ -103,6 +103,7 @@ export class CodexCliTriageProvider {
103
103
  summary: String(output.summary ?? ""),
104
104
  topics: Array.isArray(output.topics) ? output.topics.map(String) : [],
105
105
  rationale: String(output.rationale ?? ""),
106
+ model,
106
107
  };
107
108
  }
108
109
  }
@@ -1 +1 @@
1
- {"version":3,"file":"codex-cli-triage-provider.js","sourceRoot":"","sources":["../../../src/capture/codex-cli-triage-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAGf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,qBAAqB,GAEtB,MAAM,kBAAkB,CAAC;AAK1B,OAAO,EACL,wBAAwB,EACxB,2BAA2B,GAC5B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAEnE,MAAM,aAAa,GAAG;;;;;;;;;;CAUrB,CAAC;AAEF,MAAM,oBAAoB,GAAG;IAC3B,IAAI,EAAE,QAAQ;IACd,oBAAoB,EAAE,KAAK;IAC3B,QAAQ,EAAE,CAAC,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAC;IACtE,UAAU,EAAE;QACV,QAAQ,EAAE;YACR,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;SACpC;QACD,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,CAAC;SACX;QACD,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC3B,MAAM,EAAE;YACN,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;SAC1B;QACD,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;KAC9B;CACO,CAAC;AAUX,MAAM,OAAO,sBAAsB;IAEd;IADnB,YACmB,UAGb,EAAE;QAHW,YAAO,GAAP,OAAO,CAGlB;IACL,CAAC;IAEJ,kBAAkB,CAAC,MAAmB;QACpC,OAAO,CAAC,CAAC;IACX,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAkB;QAC7B,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QACpD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,cAAc,CAClB,KAAkB;QAElB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,qBAAqB,CAAC;YACpC,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAClD,CAAC,CAAC;QAEH,OAAO;YACL,MAAM,EAAE;gBACN,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,KAAK,EAAE,wBAAwB;gBAC/B,QAAQ,EAAE,2BAA2B;gBACrC,OAAO,EAAE,cAAc;gBACvB,eAAe,EAAE,OAAO,CAAC,KAAK,CAAC,eAAe;gBAC9C,KAAK,EAAE,OAAO,CAAC,KAAK;aACrB;YACD,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE;SACjB,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,SAAS,CAAC,KAAkB;QACxC,MAAM,MAAM,GAAG,GAAG,aAAa,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;QAClD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,eAAe,CAAoB;YAC1D,MAAM;YACN,MAAM,EAAE,oBAAoB;YAC5B,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtD,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS;gBACxB,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE;gBACvC,CAAC,CAAC,EAAE,CAAC;SACR,CAAC,CAAC;QAEH,IACE,MAAM,CAAC,QAAQ,KAAK,MAAM;YAC1B,MAAM,CAAC,QAAQ,KAAK,SAAS;YAC7B,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAC5B,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,+CAA+C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC5F,CAAC;QACD,IACE,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ;YACrC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC;YAC/B,MAAM,CAAC,UAAU,GAAG,CAAC;YACrB,MAAM,CAAC,UAAU,GAAG,CAAC,EACrB,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,iDAAiD,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAChG,CAAC;QAED,OAAO;YACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC;YACrC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;YACrE,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;SAC1C,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"codex-cli-triage-provider.js","sourceRoot":"","sources":["../../../src/capture/codex-cli-triage-provider.ts"],"names":[],"mappings":"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"}
@@ -186,6 +186,16 @@ export interface RecoverQuarantineDeps {
186
186
  dryRun?: boolean;
187
187
  /** Optional clock for deterministic tests. */
188
188
  now?: () => Date;
189
+ /**
190
+ * Optional per-session gate. When it returns true for a grouped record,
191
+ * that session is skipped entirely — not attempted, not summarized, not
192
+ * added to the report. The background auto-repair caller uses this to
193
+ * exclude sessions whose bounded retry budget is exhausted, so a
194
+ * permanently-failing session cannot be retried forever. The manual
195
+ * `rift doctor repair capture-large-sessions` path passes no gate, so its
196
+ * behavior (including regrown-session replacement) is unchanged.
197
+ */
198
+ skipSession?: (record: QuarantineRecord) => boolean;
189
199
  }
190
200
  /**
191
201
  * Read all Codex-CLI quarantine records under the configured directory.
@@ -222,6 +232,7 @@ export declare function saveRecoveryState(deps: Pick<RecoverQuarantineDeps, "dat
222
232
  * surface a "run recovery" advisory that can never clear — recovery cannot
223
233
  * recover a file that's gone.
224
234
  */
235
+ export declare function listParkedOversizedSessions(deps: Pick<RecoverQuarantineDeps, "dataDir" | "quarantineDir">): QuarantineRecord[];
225
236
  export declare function countParkedOversizedSessions(deps: Pick<RecoverQuarantineDeps, "dataDir" | "quarantineDir">): number;
226
237
  /**
227
238
  * Split parser-emitted Codex content into byte-budgeted chunks at turn
@@ -1 +1 @@
1
- {"version":3,"file":"recover-quarantine.d.ts","sourceRoot":"","sources":["../../../src/capture/recover-quarantine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"recover-quarantine.d.ts","sourceRoot":"","sources":["../../../src/capture/recover-quarantine.ts"],"names":[],"mappings":"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"}
@@ -55,6 +55,20 @@ const QuarantineRecordSchema = z.object({
55
55
  reason: z.string(),
56
56
  quarantined_at: z.string(),
57
57
  });
58
+ // The save/ingest *failure* path quarantines into the SAME `data/quarantine/`
59
+ // dir under the SAME `{source}_{timestamp}_{hash}.json` naming, so its records
60
+ // land in our glob. They are valid records of a different kind (a save/parse
61
+ // failure, shaped `{ payload | conversation_id, error, quarantined_at }`), not
62
+ // oversized-session recovery records — the discriminator is the `error` field,
63
+ // which oversized-session records never carry. We skip them SILENTLY (logging
64
+ // them as "malformed" every recovery pass spams the daemon log). Genuinely
65
+ // broken JSON / unknown shapes still log. A durable fix is to namespace the two
66
+ // quarantine kinds into separate dirs/prefixes so they can't collide — tracked
67
+ // as a follow-up; this is the low-risk loader-side guard.
68
+ const ForeignFailureQuarantineSchema = z.object({
69
+ error: z.string(),
70
+ quarantined_at: z.string(),
71
+ });
58
72
  const RecoveredEntrySchema = z.object({
59
73
  recovered_at: z.string(),
60
74
  fingerprint: z.string(),
@@ -101,6 +115,10 @@ export function loadQuarantineRecords(deps) {
101
115
  }
102
116
  const result = QuarantineRecordSchema.safeParse(parsed);
103
117
  if (!result.success) {
118
+ // A save/ingest failure record sharing this dir+naming is valid, just
119
+ // not ours — skip it without the per-pass "malformed" noise.
120
+ if (ForeignFailureQuarantineSchema.safeParse(parsed).success)
121
+ continue;
104
122
  process.stderr.write(`recover-quarantine: skipping malformed record ${entry.name}\n`);
105
123
  continue;
106
124
  }
@@ -168,12 +186,12 @@ export async function saveRecoveryState(deps, state) {
168
186
  * surface a "run recovery" advisory that can never clear — recovery cannot
169
187
  * recover a file that's gone.
170
188
  */
171
- export function countParkedOversizedSessions(deps) {
189
+ export function listParkedOversizedSessions(deps) {
172
190
  const grouped = groupBySession(loadQuarantineRecords(deps));
173
191
  if (grouped.length === 0)
174
- return 0;
192
+ return [];
175
193
  const state = loadRecoveryState(deps);
176
- let parked = 0;
194
+ const parked = [];
177
195
  for (const record of grouped) {
178
196
  const prior = state.recovered[recoveryKey(record.session_id)];
179
197
  const covered = prior !== undefined && prior.fingerprint === record.fingerprint;
@@ -181,10 +199,13 @@ export function countParkedOversizedSessions(deps) {
181
199
  continue;
182
200
  if (!fs.existsSync(record.session_path))
183
201
  continue;
184
- parked += 1;
202
+ parked.push(record);
185
203
  }
186
204
  return parked;
187
205
  }
206
+ export function countParkedOversizedSessions(deps) {
207
+ return listParkedOversizedSessions(deps).length;
208
+ }
188
209
  /**
189
210
  * Split parser-emitted Codex content into byte-budgeted chunks at turn
190
211
  * boundaries. The parser format is `User: …\n\nAssistant: …\n\n…`, so
@@ -282,6 +303,11 @@ export async function runRecoverQuarantine(deps) {
282
303
  };
283
304
  for (const record of grouped) {
284
305
  const key = recoveryKey(record.session_id);
306
+ // Caller-supplied gate (background auto-repair excludes budget-exhausted
307
+ // sessions). Skipped sessions are entirely invisible to the report so a
308
+ // gated-out session never inflates skipped/failed counts.
309
+ if (deps.skipSession?.(record))
310
+ continue;
285
311
  // Skip only when the stored fingerprint matches the latest grouped
286
312
  // fingerprint. A different fingerprint means the session has grown
287
313
  // (or otherwise mutated) since the last recovery, so we re-recover