@intentic/sandbox-contract 1.330.0 → 1.331.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/contracts/accounts.contract.d.ts +4 -0
  2. package/dist/contracts/accounts.contract.d.ts.map +1 -1
  3. package/dist/contracts/agent.contract.d.ts +1 -0
  4. package/dist/contracts/agent.contract.d.ts.map +1 -1
  5. package/dist/contracts/runner.contract.d.ts +3 -0
  6. package/dist/contracts/runner.contract.d.ts.map +1 -1
  7. package/dist/contracts/settings.contract.d.ts +2 -0
  8. package/dist/contracts/settings.contract.d.ts.map +1 -1
  9. package/dist/contracts/system.contract.d.ts +3 -0
  10. package/dist/contracts/system.contract.d.ts.map +1 -1
  11. package/dist/contracts/translator.contract.d.ts +4 -0
  12. package/dist/contracts/translator.contract.d.ts.map +1 -1
  13. package/dist/events/agent-events.d.ts +1 -0
  14. package/dist/events/agent-events.d.ts.map +1 -1
  15. package/dist/events/system-events.d.ts +2 -0
  16. package/dist/events/system-events.d.ts.map +1 -1
  17. package/dist/index.d.ts +14 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/models/model-roles.d.ts +8 -0
  20. package/dist/models/model-roles.d.ts.map +1 -1
  21. package/dist/models/model-roles.js +8 -0
  22. package/dist/models/model-roles.js.map +1 -1
  23. package/dist/models/plan-pools.d.ts +2 -0
  24. package/dist/models/plan-pools.d.ts.map +1 -1
  25. package/dist/models/plan-pools.js +23 -7
  26. package/dist/models/plan-pools.js.map +1 -1
  27. package/dist/schemas/agent.d.ts +3 -0
  28. package/dist/schemas/agent.d.ts.map +1 -1
  29. package/dist/schemas/environment.d.ts +30 -0
  30. package/dist/schemas/environment.d.ts.map +1 -1
  31. package/dist/schemas/environment.js +13 -0
  32. package/dist/schemas/environment.js.map +1 -1
  33. package/dist/schemas/providers/plan-limits.d.ts +7 -0
  34. package/dist/schemas/providers/plan-limits.d.ts.map +1 -1
  35. package/dist/schemas/providers/plan-limits.js +5 -1
  36. package/dist/schemas/providers/plan-limits.js.map +1 -1
  37. package/dist/schemas/providers/provider-oauth.d.ts +4 -0
  38. package/dist/schemas/providers/provider-oauth.d.ts.map +1 -1
  39. package/dist/schemas/settings-history.d.ts +6 -1
  40. package/dist/schemas/settings-history.d.ts.map +1 -1
  41. package/dist/schemas/settings-history.js +4 -1
  42. package/dist/schemas/settings-history.js.map +1 -1
  43. package/dist/schemas/settings.d.ts +2 -0
  44. package/dist/schemas/settings.d.ts.map +1 -1
  45. package/dist/state/definition.d.ts +4 -4
  46. package/package.json +5 -5
  47. package/src/models/model-roles.ts +8 -0
  48. package/src/models/plan-pools.test.ts +27 -0
  49. package/src/models/plan-pools.ts +38 -10
  50. package/src/schemas/environment.ts +25 -0
  51. package/src/schemas/providers/plan-limits.ts +9 -1
  52. package/src/schemas/settings-history.ts +15 -1
  53. package/src/schemas/settings.test.ts +25 -0
@@ -244,6 +244,7 @@ export declare const SandboxSettingsSchema: z.ZodObject<{
244
244
  "maintenance-chore": "maintenance-chore";
245
245
  "model-router": "model-router";
246
246
  "pipeline-fix": "pipeline-fix";
247
+ "refactor-run": "refactor-run";
247
248
  "safety-judge": "safety-judge";
248
249
  "session-title": "session-title";
249
250
  }> & z.core.$partial, z.ZodArray<z.ZodObject<{
@@ -424,6 +425,7 @@ export declare const SandboxSettingsWriteSchema: z.ZodObject<{
424
425
  "maintenance-chore": "maintenance-chore";
425
426
  "model-router": "model-router";
426
427
  "pipeline-fix": "pipeline-fix";
428
+ "refactor-run": "refactor-run";
427
429
  "safety-judge": "safety-judge";
428
430
  "session-title": "session-title";
429
431
  }> & z.core.$partial, z.ZodArray<z.ZodObject<{
@@ -1 +1 @@
1
- {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/schemas/settings.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/schemas/settings.ts"],"names":[],"mappings":"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"}
@@ -423,7 +423,7 @@ export declare const SandboxDefinitionSchema: z.ZodObject<{
423
423
  fieldNotesHoldout: number;
424
424
  outputCleaners: string;
425
425
  outputHoldout: number;
426
- modelRoles: Partial<Record<"acceptance-run" | "approval-queue" | "commit-message" | "deployment-fix" | "documentation-run" | "extension-review" | "loop-iteration" | "loop-verdict" | "maintenance-chore" | "model-router" | "pipeline-fix" | "safety-judge" | "session-title", {
426
+ modelRoles: Partial<Record<"acceptance-run" | "approval-queue" | "commit-message" | "deployment-fix" | "documentation-run" | "extension-review" | "loop-iteration" | "loop-verdict" | "maintenance-chore" | "model-router" | "pipeline-fix" | "refactor-run" | "safety-judge" | "session-title", {
427
427
  provider: string;
428
428
  model: string;
429
429
  effort?: string | undefined;
@@ -514,7 +514,7 @@ export declare const SandboxDefinitionSchema: z.ZodObject<{
514
514
  fieldNotesHoldout: number;
515
515
  outputCleaners: string;
516
516
  outputHoldout: number;
517
- modelRoles: Partial<Record<"acceptance-run" | "approval-queue" | "commit-message" | "deployment-fix" | "documentation-run" | "extension-review" | "loop-iteration" | "loop-verdict" | "maintenance-chore" | "model-router" | "pipeline-fix" | "safety-judge" | "session-title", {
517
+ modelRoles: Partial<Record<"acceptance-run" | "approval-queue" | "commit-message" | "deployment-fix" | "documentation-run" | "extension-review" | "loop-iteration" | "loop-verdict" | "maintenance-chore" | "model-router" | "pipeline-fix" | "refactor-run" | "safety-judge" | "session-title", {
518
518
  provider: string;
519
519
  model: string;
520
520
  effort?: string | undefined;
@@ -1040,7 +1040,7 @@ export declare const BundleManifestSchema: z.ZodObject<{
1040
1040
  fieldNotesHoldout: number;
1041
1041
  outputCleaners: string;
1042
1042
  outputHoldout: number;
1043
- modelRoles: Partial<Record<"acceptance-run" | "approval-queue" | "commit-message" | "deployment-fix" | "documentation-run" | "extension-review" | "loop-iteration" | "loop-verdict" | "maintenance-chore" | "model-router" | "pipeline-fix" | "safety-judge" | "session-title", {
1043
+ modelRoles: Partial<Record<"acceptance-run" | "approval-queue" | "commit-message" | "deployment-fix" | "documentation-run" | "extension-review" | "loop-iteration" | "loop-verdict" | "maintenance-chore" | "model-router" | "pipeline-fix" | "refactor-run" | "safety-judge" | "session-title", {
1044
1044
  provider: string;
1045
1045
  model: string;
1046
1046
  effort?: string | undefined;
@@ -1131,7 +1131,7 @@ export declare const BundleManifestSchema: z.ZodObject<{
1131
1131
  fieldNotesHoldout: number;
1132
1132
  outputCleaners: string;
1133
1133
  outputHoldout: number;
1134
- modelRoles: Partial<Record<"acceptance-run" | "approval-queue" | "commit-message" | "deployment-fix" | "documentation-run" | "extension-review" | "loop-iteration" | "loop-verdict" | "maintenance-chore" | "model-router" | "pipeline-fix" | "safety-judge" | "session-title", {
1134
+ modelRoles: Partial<Record<"acceptance-run" | "approval-queue" | "commit-message" | "deployment-fix" | "documentation-run" | "extension-review" | "loop-iteration" | "loop-verdict" | "maintenance-chore" | "model-router" | "pipeline-fix" | "refactor-run" | "safety-judge" | "session-title", {
1135
1135
  provider: string;
1136
1136
  model: string;
1137
1137
  effort?: string | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentic/sandbox-contract",
3
- "version": "1.330.0",
3
+ "version": "1.331.0",
4
4
  "description": "oRPC wire contract for the intentic sandbox daemon, shared by the daemon and its browser client",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -306,10 +306,10 @@
306
306
  }
307
307
  },
308
308
  "dependencies": {
309
- "@intentic/base": "1.330.0",
310
- "@intentic/constants": "1.330.0",
311
- "@intentic/extension-manifest": "1.330.0",
312
- "@intentic/registry": "1.330.0",
309
+ "@intentic/base": "1.331.0",
310
+ "@intentic/constants": "1.331.0",
311
+ "@intentic/extension-manifest": "1.331.0",
312
+ "@intentic/registry": "1.331.0",
313
313
  "@orpc/contract": "1.15.4",
314
314
  "tslib": "2.8.1",
315
315
  "zod": "4.6.5"
@@ -92,6 +92,14 @@ export const MODEL_ROLES = [
92
92
  trigger: "pressed",
93
93
  icon: "wrench",
94
94
  },
95
+ {
96
+ id: "refactor-run",
97
+ label: "Refactors",
98
+ blurb: "The agent started from a hotspot or key module on a repository's Health tab.",
99
+ kind: "run",
100
+ trigger: "pressed",
101
+ icon: "hammer",
102
+ },
95
103
  {
96
104
  id: "documentation-run",
97
105
  label: "Documentation runs",
@@ -132,6 +132,22 @@ test("spent is the contract's one line: 99.5% still has room, 100% is spent unti
132
132
  expect(headroomState(CLAUDE, { id: "claude-opus-4-6" })).toEqual({ kind: "spent" });
133
133
  });
134
134
 
135
+ // Anthropic reports whole percents: an account read at 100 kept serving turns for hours, so that reading is the line,
136
+ // not proof. Only the provider's refusal makes such a pool spent.
137
+ test("a pool read at 100 in whole percents is at the line with no room, until a refusal proves it empty", () => {
138
+ const week = window({ kind: "seven_day", utilization: 100, resetsAt: 900, rounded: true });
139
+ const atLine = usage(window({ kind: "five_hour", utilization: 75, rounded: true }), week);
140
+ expect(headroomState(atLine)).toEqual({ kind: "ready", room: 0 });
141
+ expect(headroomState(atLine, { id: "claude-opus-5-5" })).toEqual({ kind: "ready", room: 0 });
142
+ // A precise 100 is still spent.
143
+ expect(headroomState(usage(window({ kind: "seven_day", utilization: 100, resetsAt: 900 })))).toEqual({ kind: "spent", reopensAt: 900 });
144
+ // The provider refused it: spent until the pool reopens, and a reading still at the line does not answer that.
145
+ const facts = { account: "a", usage: { ...atLine, measuredAt: 2_000 } };
146
+ const refused = refusal({ kind: "limit", account: "a" });
147
+ expect(refusalVerdict(refused, [facts])).toBe("standing");
148
+ expect(serviceStates([facts], refused).get("a")).toEqual({ kind: "spent", reopensAt: 900 });
149
+ });
150
+
135
151
  test("with no model named, an account is spent only when no model can run on it", () => {
136
152
  // A full Opus slice leaves every other model the room of the fullest pool still open.
137
153
  expect(headroomState(CLAUDE)).toEqual({ kind: "ready", room: 70 });
@@ -243,3 +259,14 @@ test("an unnamed turn takes the most room, then an unmeasured account, then a sp
243
259
  expect(roomiestAccount([entry("seatless", blocked), entry("unread", { kind: "unknown" })])).toBeUndefined();
244
260
  expect(roomiestAccount([entry("low", { kind: "ready", room: 5 }), entry("high", { kind: "ready", room: 60 })])?.id).toBe("high");
245
261
  });
262
+
263
+ test("an account at the line is tried after an unmeasured one and before a spent one, and never a move's destination", () => {
264
+ const entry = (id: string, state: AccountState) => ({ id, state });
265
+ const atLine: AccountState = { kind: "ready", room: 0 };
266
+ expect(preferredAccount([entry("line", atLine), entry("low", { kind: "ready", room: 2 })])?.id).toBe("low");
267
+ expect(preferredAccount([entry("line", atLine), entry("unread", { kind: "unknown" })])?.id).toBe("unread");
268
+ expect(preferredAccount([entry("spent", { kind: "spent" }), entry("line", atLine)])?.id).toBe("line");
269
+ // A move lands only on proven room: two accounts at the line would otherwise hand a refused turn back and forth.
270
+ expect(roomiestAccount([entry("line", atLine), entry("spent", { kind: "spent" })])).toBeUndefined();
271
+ expect(roomiestAccount([entry("line", atLine), entry("low", { kind: "ready", room: 2 })])?.id).toBe("low");
272
+ });
@@ -8,6 +8,18 @@ import type { AccountState, AccountUsage, ProviderRefusal, UsageWindow, WindowGa
8
8
  // anything short of it still has room.
9
9
  export const SPENT_UTILIZATION = 100;
10
10
 
11
+ // Whether a reading proves its pool empty. A pool read at the line by a provider that rounds to whole percents
12
+ // (`rounded`) does not: Anthropic reports 99.5% as 100 and keeps serving turns on it, so treating that as spent strands
13
+ // the last of an allowance (and turns a plain send into one scheduled for the reset). Such a pool is at the line, with
14
+ // no room to rank by; only the provider's refusal (pinnedFull) proves it empty.
15
+ export const provenFull = (window: UsageWindow): boolean => window.utilization >= SPENT_UTILIZATION && window.rounded !== true;
16
+
17
+ // A pool a standing limit refusal shows full: at the line, and proven so whatever the provider's rounding.
18
+ export const pinnedFull = (window: UsageWindow): UsageWindow => {
19
+ const { rounded: _rounded, ...pool } = window;
20
+ return { ...pool, utilization: Math.max(window.utilization, SPENT_UTILIZATION) };
21
+ };
22
+
11
23
  export interface ModelRef {
12
24
  // Wire model id.
13
25
  readonly id: string;
@@ -210,15 +222,15 @@ export const headroomState = (usage: AccountUsage | undefined, model?: ModelRef)
210
222
  if (windows.length === 0) {
211
223
  return { kind: "unknown" };
212
224
  }
213
- const full = windows.filter((window) => window.utilization >= SPENT_UTILIZATION);
214
- const open = windows.filter((window) => window.utilization < SPENT_UTILIZATION);
225
+ const full = windows.filter(provenFull);
226
+ const open = windows.filter((window) => !provenFull(window));
215
227
  if (model !== undefined || full.some((window) => window.gates === "all") || open.length === 0) {
216
228
  const holding = model !== undefined ? full : full.some((window) => window.gates === "all") ? full.filter((window) => window.gates === "all") : full;
217
229
  if (holding.length > 0) {
218
230
  return spent(reopening(holding, model === undefined && !holding.some((window) => window.gates === "all")));
219
231
  }
220
232
  }
221
- return { kind: "ready", room: SPENT_UTILIZATION - Math.max(...open.map((window) => window.utilization)) };
233
+ return { kind: "ready", room: Math.max(0, SPENT_UTILIZATION - Math.max(...open.map((window) => window.utilization))) };
222
234
  };
223
235
 
224
236
  // A standing limit refusal reads its pool as full, since a polled reading freezes the moment a pool actually empties: the
@@ -231,7 +243,7 @@ const refusedPool = (usage: AccountUsage | undefined, refusal: ProviderRefusal,
231
243
  const sameModel = refusal.model === undefined || model === undefined || refusal.model === model.id;
232
244
  return sameModel ? spent(refusal.resetsAt) : headroomState(usage, model);
233
245
  }
234
- const pinned = usage.windows.map((window) => (window === binding ? { ...window, utilization: Math.max(window.utilization, SPENT_UTILIZATION) } : window));
246
+ const pinned = usage.windows.map((window) => (window === binding ? pinnedFull(window) : window));
235
247
  const state = headroomState({ ...usage, windows: pinned }, model);
236
248
  // The provider's own "try again at" is when it reopens, over whatever the polled pool last said.
237
249
  return state.kind === "spent" && refusal.resetsAt !== undefined ? spent(refusal.resetsAt) : state;
@@ -287,19 +299,35 @@ export const serviceStates = (
287
299
  );
288
300
  };
289
301
 
290
- // Worst last: proven room, no reading either way, known spent, and nothing a turn can run on.
291
- const PREFERENCE: Record<AccountState["kind"], number> = { ready: 0, unknown: 1, spent: 2, blocked: 3 };
302
+ // Worst last: proven room, no reading either way, a pool at the line (it may hold a sliver, or nothing), known spent,
303
+ // and nothing a turn can run on.
304
+ const preference = (state: AccountState): number => {
305
+ switch (state.kind) {
306
+ case "ready":
307
+ return state.room > 0 ? 0 : 2;
308
+ case "unknown":
309
+ return 1;
310
+ case "spent":
311
+ return 3;
312
+ case "blocked":
313
+ return 4;
314
+ }
315
+ };
292
316
 
293
- /** The account an unnamed turn runs on: ready by most room, then unmeasured, then spent, blocked only when that is all there is. Ties keep the caller's order. */
317
+ /** The account an unnamed turn runs on: ready by most room, then unmeasured, then at the line, then spent, blocked only when that is all there is. Ties keep the caller's order. */
294
318
  export const preferredAccount = <T extends { readonly state: AccountState }>(entries: readonly T[]): T | undefined =>
295
319
  entries.reduce<T | undefined>((best, next) => {
296
320
  if (best === undefined) {
297
321
  return next;
298
322
  }
299
- const tier = PREFERENCE[next.state.kind] - PREFERENCE[best.state.kind];
323
+ const tier = preference(next.state) - preference(best.state);
300
324
  return tier < 0 || (tier === 0 && next.state.kind === "ready" && best.state.kind === "ready" && next.state.room > best.state.room) ? next : best;
301
325
  }, undefined);
302
326
 
303
- /** The roomiest account with proven room, or none: what a move off a refused account may land on. Ties keep the caller's order. */
327
+ /**
328
+ * The roomiest account with proven room, or none: what a move off a refused account may land on. Ties keep the caller's
329
+ * order. An account at the line is left out: a move there could be refused in turn, and with one refusal remembered per
330
+ * provider, two such accounts would hand the turn back and forth.
331
+ */
304
332
  export const roomiestAccount = <T extends { readonly state: AccountState }>(entries: readonly T[]): T | undefined =>
305
- preferredAccount(entries.filter((entry) => entry.state.kind === "ready"));
333
+ preferredAccount(entries.filter((entry) => entry.state.kind === "ready" && entry.state.room > 0));
@@ -45,12 +45,37 @@ export type RuntimeInstall = z.infer<typeof RuntimeInstallSchema>;
45
45
  // (`environment propose`) clears its tool's entries.
46
46
  export const SettledDraftSchema = z.object({ tool: z.string(), hash: z.string(), at: z.number() });
47
47
  export type SettledDraft = z.infer<typeof SettledDraftSchema>;
48
+ // One overlay the daemon composed, by the hash a rebuild is stamped with, and the custom-section blocks it carried (each
49
+ // by name and the hash of its trimmed steps). Kept so "is this tool in the image" is answered against the overlay the
50
+ // running container was actually built from, which is rarely the newest one composed: every approval, capability change
51
+ // and daemon update composes again, and a rebuild builds whatever was newest when it started.
52
+ export const EnvironmentCompositionSchema = z.object({
53
+ hash: z.string(),
54
+ at: z.number(),
55
+ blocks: z.array(z.object({ name: z.string(), hash: z.string() })),
56
+ });
57
+ export type EnvironmentComposition = z.infer<typeof EnvironmentCompositionSchema>;
58
+ // A draft the daemon wrote on its own (a recurring runtime install, a cache-rule revision of an approved block), by the
59
+ // name its file carries and the hash of its steps. A draft that later vanishes with no answer on record was thrown away
60
+ // by hand (the Changes panel's discard, a git clean): that is read as a no, rather than writing it back on the next
61
+ // sweep. `install` is the ledger entry an auto-draft came from, which a no declines.
62
+ export const EnvironmentOfferSchema = z.object({
63
+ tool: z.string(),
64
+ hash: z.string(),
65
+ at: z.number(),
66
+ install: z.string().optional(),
67
+ });
68
+ export type EnvironmentOffer = z.infer<typeof EnvironmentOfferSchema>;
48
69
  export const RuntimeInstallsFileSchema = z.object({
49
70
  installs: z.array(RuntimeInstallSchema),
50
71
  // The last drift snapshot, persisted so a daemon restart does not blank the card until the next sweep.
51
72
  drift: EnvironmentDriftSchema.optional(),
52
73
  // Drafts already answered, newest last and capped; absent on a ledger written before removal existed.
53
74
  settled: z.array(SettledDraftSchema).optional(),
75
+ // Overlays composed, oldest first and capped; absent on a ledger written before they were kept.
76
+ compositions: z.array(EnvironmentCompositionSchema).optional(),
77
+ // Drafts the daemon wrote that nobody has answered yet; absent on a ledger written before they were kept.
78
+ offered: z.array(EnvironmentOfferSchema).optional(),
54
79
  });
55
80
  export type RuntimeInstallsFile = z.infer<typeof RuntimeInstallsFileSchema>;
56
81
  // Ledger entry as the Environment card shows it: recurrence joined with whether it's present in the live container
@@ -23,6 +23,12 @@ export const UsageWindowSchema = z.object({
23
23
  utilization: z.number(), // 0-100
24
24
  resetsAt: z.number().optional(),
25
25
  gates: WindowGatesSchema,
26
+ rounded: z
27
+ .boolean()
28
+ .optional()
29
+ .describe(
30
+ "The provider rounds this figure to a whole percent (Anthropic does), so a reading of 100 may be 99.5 and the pool can still serve. Such a pool reads as at the line, not spent: only the provider's refusal proves it empty.",
31
+ ),
26
32
  });
27
33
  export type UsageWindow = z.infer<typeof UsageWindowSchema>;
28
34
  // A failed re-read, whatever the cause: a 429 park, a 403 asking for verification, a 5xx, a timeout. Recorded as the fact
@@ -59,7 +65,9 @@ export const AccountStateSchema = z.discriminatedUnion("kind", [
59
65
  kind: z.literal("ready"),
60
66
  room: z
61
67
  .number()
62
- .describe("How much of the fullest pool that gates the turn is left, in percent (above 0, up to 100). Pickers take the most room."),
68
+ .describe(
69
+ "How much of the fullest pool that gates the turn is left, in percent (0 up to 100). Pickers take the most room. 0 is a rounded pool read at 100: at the line, tried after an unmeasured account, never a limit move's destination.",
70
+ ),
63
71
  }),
64
72
  z.object({
65
73
  kind: z.literal("spent"),
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- import { at, drop, dropAll, fold, isJsonObject, mapValue, retype } from "../documents/conversions.js";
2
+ import { at, drop, dropAll, fold, isJsonObject, type JsonObject, mapValue, retype, transform } from "../documents/conversions.js";
3
3
  import type { KeepWarmSettings, RuleSchema } from "./settings.js";
4
4
 
5
5
  // The conversions the settings shape has had, oldest first: what brings any earlier release's settings to
@@ -63,6 +63,19 @@ const keepWarmObject = fold("folds keepWarm, keepWarmHours, keepWarmMinTokens an
63
63
  },
64
64
  });
65
65
 
66
+ // The Refactors job (2026-10-09): a refactor started from a repository's Health tab used to name no job and opened on
67
+ // whatever model the composer last held. A file from before it inherits the Maintenance chores list, the job nearest in
68
+ // kind, so the owner's choice for work they start carries over instead of the new job opening empty. Only while the key
69
+ // is absent: an owner who later empties it stores [], which this leaves alone.
70
+ type RolesWithChores = JsonObject & { readonly "maintenance-chore": readonly unknown[] };
71
+ const holdsChoresWithoutRefactors = (roles: JsonObject): roles is RolesWithChores =>
72
+ !Object.hasOwn(roles, "refactor-run") && Array.isArray(roles["maintenance-chore"]) && roles["maintenance-chore"].length > 0;
73
+ const refactorsFromChores = transform(
74
+ "gives the new Refactors job the Maintenance chores list",
75
+ holdsChoresWithoutRefactors,
76
+ (roles): JsonObject => ({ ...roles, "refactor-run": roles["maintenance-chore"] }),
77
+ );
78
+
66
79
  export const SETTINGS_HISTORY = [
67
80
  // Every setting a release since 2026-08-10 had and this one does not (read off the contract lock's history):
68
81
  // retired, so passthrough stops carrying them, a definition naming one still applies, and no later setting may
@@ -112,4 +125,5 @@ export const SETTINGS_HISTORY = [
112
125
  at("modelRoles", drop("pre-push-fix")),
113
126
  // The short guidance form (2026-10-06): it lost its A/B to the full one, which every turn now gets.
114
127
  ...dropAll(["leanGuidance", "leanGuidanceHoldout"]),
128
+ at("modelRoles", refactorsFromChores),
115
129
  ] as const;
@@ -129,3 +129,28 @@ describe(`the retired pre-push fix role`, () => {
129
129
  expect(convertDocument(SETTINGS_HISTORY, `object`, { modelRoles: { "pipeline-fix": [pin] } }, true).changes).toEqual([]);
130
130
  });
131
131
  });
132
+
133
+ // The Refactors job arrived on 2026-10-09; a file from before it carries the owner's Maintenance chores list over, so a
134
+ // refactor started from Health opens on a model they chose rather than on an empty job.
135
+ describe(`the new Refactors job`, () => {
136
+ const opus = { provider: `claude`, model: `claude-opus-5-5` };
137
+ const sol = { provider: `codex`, model: `gpt-sol-6.1` };
138
+
139
+ test(`takes the Maintenance chores list in a file from before it, and every other list stays`, () => {
140
+ const stored = { modelRoles: { "maintenance-chore": [opus, sol], "pipeline-fix": [sol] } };
141
+ const converted = convertDocument(SETTINGS_HISTORY, `object`, stored, true);
142
+ expect(converted.value).toEqual({ modelRoles: { "maintenance-chore": [opus, sol], "pipeline-fix": [sol], "refactor-run": [opus, sol] } });
143
+ expect(SandboxSettingsSchema.parse(converted.value).modelRoles[`refactor-run`]).toEqual([opus, sol]);
144
+ });
145
+
146
+ test(`leaves a list the owner set, even an emptied one, and a file with no chores list`, () => {
147
+ for (const modelRoles of [
148
+ { "maintenance-chore": [opus], "refactor-run": [sol] },
149
+ { "maintenance-chore": [opus], "refactor-run": [] },
150
+ { "pipeline-fix": [opus] },
151
+ { "maintenance-chore": [] },
152
+ ]) {
153
+ expect(convertDocument(SETTINGS_HISTORY, `object`, { modelRoles }, true).changes).toEqual([]);
154
+ }
155
+ });
156
+ });