johns-harness 2026.9.36 → 2026.9.37

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 2026.9.37
4
+
5
+ - Every Sonnet now gets its full native 1M context window. Claude Sonnet 5.5 175K -> 1M, Claude Sonnet 5 175K -> 1M (it was capped), Claude Sonnet 4.6 200K -> 1M; max output unchanged (Sonnet 5.5 and 5 stay at 128K). The "standing Sonnet window = 175K" rule is gone. A new resolver gives `claude-sonnet-4-6` and every later Sonnet 1M in the resolved config and in `models.json`, so a user config that still pins a Sonnet at 175K is lifted at load and future Sonnets need no patch. No beta header is needed (Anthropic serves 1M by default on these models).
6
+ - Live probe: a 463,749-token prompt to `claude-sonnet-5-5` through the harness's Anthropic adapter completed normally; a raw 648,450-token request returned HTTP 200.
7
+ - Folded into the family 82 exact replay (32 files); verifier checks 82.13-82.17. Roll back with `npm i -g johns-harness@2026.9.36`.
8
+
3
9
  ## 2026.9.36
4
10
 
5
11
  - Family 82 (daily model integration, 2026-09-29): Claude Sonnet 5.5 (`claude-sonnet-5-5`) ships on `anthropic`. Card data from the official model page checked 2026-09-29: $2/$10 per MTok, cache read $0.20, 5m write $2.50, 1h write $4, 1M native context and 128K max output, adaptive thinking on by default (effort `low` through `max`, default `high`; `between_tools` is the lowest setting), and non-default `temperature`/`top_p`/`top_k` are rejected. `contextWindow` stays the standing 175K Sonnet window (owner caps do not change). Live probe 2026-09-29: the default request and the `thinking: adaptive` + `output_config.effort: xhigh` request both returned 200.
@@ -5367,7 +5367,7 @@ function applyModelDefaults(cfg) {
5367
5367
  if (raw.input === void 0) modelMutated = true;
5368
5368
  const cost = resolveModelCost(raw.cost);
5369
5369
  if (!raw.cost || raw.cost.input !== cost.input || raw.cost.output !== cost.output || raw.cost.cacheRead !== cost.cacheRead || raw.cost.cacheWrite !== cost.cacheWrite) modelMutated = true;
5370
- const contextWindow = isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS;
5370
+ const contextWindow = resolveJohnnessSonnetNativeContextWindow(providerId, raw.id) ?? (isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS); // JOHNNESS_PATCH_SONNET_55_MODEL
5371
5371
  if (raw.contextWindow !== contextWindow) modelMutated = true;
5372
5372
  const defaultMaxTokens = Math.min(DEFAULT_MODEL_MAX_TOKENS, contextWindow);
5373
5373
  const rawMaxTokens = isPositiveNumber(raw.maxTokens) ? raw.maxTokens : defaultMaxTokens;
@@ -5433,6 +5433,19 @@ function applyModelDefaults(cfg) {
5433
5433
  }
5434
5434
  };
5435
5435
  }
5436
+ /* JOHNNESS_PATCH_SONNET_55_MODEL: every Anthropic Sonnet from Sonnet 4.6 on (claude-sonnet-4-6, claude-sonnet-5,
5437
+ claude-sonnet-5-5 and every later Sonnet) runs on its full native 1M context window; the harness
5438
+ never caps a Sonnet. Anthropic serves 1M by default on these models (no beta header). Resolved
5439
+ config, models.json, compaction and session snapshots all read this one value. */
5440
+ function resolveJohnnessSonnetNativeContextWindow(providerId, modelId) {
5441
+ const JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS = 1e6; // function-scoped: callable before module init completes
5442
+ if (String(providerId ?? "").trim().toLowerCase() !== "anthropic") return;
5443
+ const match = /^claude-sonnet-(\d+)(?:-(\d{1,2}))?(?:-\d{8})?$/.exec(String(modelId ?? "").trim().toLowerCase());
5444
+ if (!match) return;
5445
+ const major = Number(match[1]);
5446
+ const minor = Number(match[2] ?? 0);
5447
+ if (major > 4 || (major === 4 && minor >= 6)) return JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS;
5448
+ }
5436
5449
  function applyAgentDefaults(cfg) {
5437
5450
  const agents = cfg.agents;
5438
5451
  const defaults = agents?.defaults;
@@ -2062,7 +2062,7 @@ function applyModelDefaults(cfg) {
2062
2062
  if (raw.input === void 0) modelMutated = true;
2063
2063
  const cost = resolveModelCost(raw.cost);
2064
2064
  if (!raw.cost || raw.cost.input !== cost.input || raw.cost.output !== cost.output || raw.cost.cacheRead !== cost.cacheRead || raw.cost.cacheWrite !== cost.cacheWrite) modelMutated = true;
2065
- const contextWindow = isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS;
2065
+ const contextWindow = resolveJohnnessSonnetNativeContextWindow(providerId, raw.id) ?? (isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS); // JOHNNESS_PATCH_SONNET_55_MODEL
2066
2066
  if (raw.contextWindow !== contextWindow) modelMutated = true;
2067
2067
  const defaultMaxTokens = Math.min(DEFAULT_MODEL_MAX_TOKENS, contextWindow);
2068
2068
  const rawMaxTokens = isPositiveNumber(raw.maxTokens) ? raw.maxTokens : defaultMaxTokens;
@@ -2128,6 +2128,19 @@ function applyModelDefaults(cfg) {
2128
2128
  }
2129
2129
  };
2130
2130
  }
2131
+ /* JOHNNESS_PATCH_SONNET_55_MODEL: every Anthropic Sonnet from Sonnet 4.6 on (claude-sonnet-4-6, claude-sonnet-5,
2132
+ claude-sonnet-5-5 and every later Sonnet) runs on its full native 1M context window; the harness
2133
+ never caps a Sonnet. Anthropic serves 1M by default on these models (no beta header). Resolved
2134
+ config, models.json, compaction and session snapshots all read this one value. */
2135
+ function resolveJohnnessSonnetNativeContextWindow(providerId, modelId) {
2136
+ const JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS = 1e6; // function-scoped: callable before module init completes
2137
+ if (String(providerId ?? "").trim().toLowerCase() !== "anthropic") return;
2138
+ const match = /^claude-sonnet-(\d+)(?:-(\d{1,2}))?(?:-\d{8})?$/.exec(String(modelId ?? "").trim().toLowerCase());
2139
+ if (!match) return;
2140
+ const major = Number(match[1]);
2141
+ const minor = Number(match[2] ?? 0);
2142
+ if (major > 4 || (major === 4 && minor >= 6)) return JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS;
2143
+ }
2131
2144
  function applyAgentDefaults(cfg) {
2132
2145
  const agents = cfg.agents;
2133
2146
  const defaults = agents?.defaults;
@@ -5214,7 +5214,7 @@ function applyModelDefaults(cfg) {
5214
5214
  if (raw.input === void 0) modelMutated = true;
5215
5215
  const cost = resolveModelCost(raw.cost);
5216
5216
  if (!raw.cost || raw.cost.input !== cost.input || raw.cost.output !== cost.output || raw.cost.cacheRead !== cost.cacheRead || raw.cost.cacheWrite !== cost.cacheWrite) modelMutated = true;
5217
- const contextWindow = isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS;
5217
+ const contextWindow = resolveJohnnessSonnetNativeContextWindow(providerId, raw.id) ?? (isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS); // JOHNNESS_PATCH_SONNET_55_MODEL
5218
5218
  if (raw.contextWindow !== contextWindow) modelMutated = true;
5219
5219
  const defaultMaxTokens = Math.min(DEFAULT_MODEL_MAX_TOKENS, contextWindow);
5220
5220
  const rawMaxTokens = isPositiveNumber(raw.maxTokens) ? raw.maxTokens : defaultMaxTokens;
@@ -5280,6 +5280,19 @@ function applyModelDefaults(cfg) {
5280
5280
  }
5281
5281
  };
5282
5282
  }
5283
+ /* JOHNNESS_PATCH_SONNET_55_MODEL: every Anthropic Sonnet from Sonnet 4.6 on (claude-sonnet-4-6, claude-sonnet-5,
5284
+ claude-sonnet-5-5 and every later Sonnet) runs on its full native 1M context window; the harness
5285
+ never caps a Sonnet. Anthropic serves 1M by default on these models (no beta header). Resolved
5286
+ config, models.json, compaction and session snapshots all read this one value. */
5287
+ function resolveJohnnessSonnetNativeContextWindow(providerId, modelId) {
5288
+ const JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS = 1e6; // function-scoped: callable before module init completes
5289
+ if (String(providerId ?? "").trim().toLowerCase() !== "anthropic") return;
5290
+ const match = /^claude-sonnet-(\d+)(?:-(\d{1,2}))?(?:-\d{8})?$/.exec(String(modelId ?? "").trim().toLowerCase());
5291
+ if (!match) return;
5292
+ const major = Number(match[1]);
5293
+ const minor = Number(match[2] ?? 0);
5294
+ if (major > 4 || (major === 4 && minor >= 6)) return JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS;
5295
+ }
5283
5296
  function applyAgentDefaults(cfg) {
5284
5297
  const agents = cfg.agents;
5285
5298
  const defaults = agents?.defaults;
@@ -1938,7 +1938,7 @@ function applyModelDefaults(cfg) {
1938
1938
  if (raw.input === void 0) modelMutated = true;
1939
1939
  const cost = resolveModelCost(raw.cost);
1940
1940
  if (!raw.cost || raw.cost.input !== cost.input || raw.cost.output !== cost.output || raw.cost.cacheRead !== cost.cacheRead || raw.cost.cacheWrite !== cost.cacheWrite) modelMutated = true;
1941
- const contextWindow = resolveJohnnessOpusContextWindow(providerId, raw.id) ?? (isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS);
1941
+ const contextWindow = resolveJohnnessSonnetNativeContextWindow(providerId, raw.id) ?? resolveJohnnessOpusContextWindow(providerId, raw.id) ?? (isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS); // JOHNNESS_PATCH_SONNET_55_MODEL
1942
1942
  if (raw.contextWindow !== contextWindow) modelMutated = true;
1943
1943
  const defaultMaxTokens = Math.min(DEFAULT_MODEL_MAX_TOKENS, contextWindow);
1944
1944
  const rawMaxTokens = isPositiveNumber(raw.maxTokens) ? raw.maxTokens : defaultMaxTokens;
@@ -2004,6 +2004,19 @@ function applyModelDefaults(cfg) {
2004
2004
  }
2005
2005
  };
2006
2006
  }
2007
+ /* JOHNNESS_PATCH_SONNET_55_MODEL: every Anthropic Sonnet from Sonnet 4.6 on (claude-sonnet-4-6, claude-sonnet-5,
2008
+ claude-sonnet-5-5 and every later Sonnet) runs on its full native 1M context window; the harness
2009
+ never caps a Sonnet. Anthropic serves 1M by default on these models (no beta header). Resolved
2010
+ config, models.json, compaction and session snapshots all read this one value. */
2011
+ function resolveJohnnessSonnetNativeContextWindow(providerId, modelId) {
2012
+ const JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS = 1e6; // function-scoped: callable before module init completes
2013
+ if (String(providerId ?? "").trim().toLowerCase() !== "anthropic") return;
2014
+ const match = /^claude-sonnet-(\d+)(?:-(\d{1,2}))?(?:-\d{8})?$/.exec(String(modelId ?? "").trim().toLowerCase());
2015
+ if (!match) return;
2016
+ const major = Number(match[1]);
2017
+ const minor = Number(match[2] ?? 0);
2018
+ if (major > 4 || (major === 4 && minor >= 6)) return JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS;
2019
+ }
2007
2020
  function applyAgentDefaults(cfg) {
2008
2021
  const agents = cfg.agents;
2009
2022
  const defaults = agents?.defaults;
@@ -1913,7 +1913,7 @@ function applyModelDefaults(cfg) {
1913
1913
  if (raw.input === void 0) modelMutated = true;
1914
1914
  const cost = resolveModelCost(raw.cost);
1915
1915
  if (!raw.cost || raw.cost.input !== cost.input || raw.cost.output !== cost.output || raw.cost.cacheRead !== cost.cacheRead || raw.cost.cacheWrite !== cost.cacheWrite) modelMutated = true;
1916
- const contextWindow = resolveJohnnessOpusContextWindow(providerId, raw.id) ?? (isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS);
1916
+ const contextWindow = resolveJohnnessSonnetNativeContextWindow(providerId, raw.id) ?? resolveJohnnessOpusContextWindow(providerId, raw.id) ?? (isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS); // JOHNNESS_PATCH_SONNET_55_MODEL
1917
1917
  if (raw.contextWindow !== contextWindow) modelMutated = true;
1918
1918
  const defaultMaxTokens = Math.min(DEFAULT_MODEL_MAX_TOKENS, contextWindow);
1919
1919
  const rawMaxTokens = isPositiveNumber(raw.maxTokens) ? raw.maxTokens : defaultMaxTokens;
@@ -1979,6 +1979,19 @@ function applyModelDefaults(cfg) {
1979
1979
  }
1980
1980
  };
1981
1981
  }
1982
+ /* JOHNNESS_PATCH_SONNET_55_MODEL: every Anthropic Sonnet from Sonnet 4.6 on (claude-sonnet-4-6, claude-sonnet-5,
1983
+ claude-sonnet-5-5 and every later Sonnet) runs on its full native 1M context window; the harness
1984
+ never caps a Sonnet. Anthropic serves 1M by default on these models (no beta header). Resolved
1985
+ config, models.json, compaction and session snapshots all read this one value. */
1986
+ function resolveJohnnessSonnetNativeContextWindow(providerId, modelId) {
1987
+ const JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS = 1e6; // function-scoped: callable before module init completes
1988
+ if (String(providerId ?? "").trim().toLowerCase() !== "anthropic") return;
1989
+ const match = /^claude-sonnet-(\d+)(?:-(\d{1,2}))?(?:-\d{8})?$/.exec(String(modelId ?? "").trim().toLowerCase());
1990
+ if (!match) return;
1991
+ const major = Number(match[1]);
1992
+ const minor = Number(match[2] ?? 0);
1993
+ if (major > 4 || (major === 4 && minor >= 6)) return JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS;
1994
+ }
1982
1995
  function applyAgentDefaults(cfg) {
1983
1996
  const agents = cfg.agents;
1984
1997
  const defaults = agents?.defaults;
@@ -1844,7 +1844,7 @@ function applyModelDefaults(cfg) {
1844
1844
  if (raw.input === void 0) modelMutated = true;
1845
1845
  const cost = resolveModelCost(raw.cost);
1846
1846
  if (!raw.cost || raw.cost.input !== cost.input || raw.cost.output !== cost.output || raw.cost.cacheRead !== cost.cacheRead || raw.cost.cacheWrite !== cost.cacheWrite) modelMutated = true;
1847
- const contextWindow = resolveJohnnessOpusContextWindow(providerId, raw.id) ?? (isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS);
1847
+ const contextWindow = resolveJohnnessSonnetNativeContextWindow(providerId, raw.id) ?? resolveJohnnessOpusContextWindow(providerId, raw.id) ?? (isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS); // JOHNNESS_PATCH_SONNET_55_MODEL
1848
1848
  if (raw.contextWindow !== contextWindow) modelMutated = true;
1849
1849
  const defaultMaxTokens = Math.min(DEFAULT_MODEL_MAX_TOKENS, contextWindow);
1850
1850
  const rawMaxTokens = isPositiveNumber(raw.maxTokens) ? raw.maxTokens : defaultMaxTokens;
@@ -1910,6 +1910,19 @@ function applyModelDefaults(cfg) {
1910
1910
  }
1911
1911
  };
1912
1912
  }
1913
+ /* JOHNNESS_PATCH_SONNET_55_MODEL: every Anthropic Sonnet from Sonnet 4.6 on (claude-sonnet-4-6, claude-sonnet-5,
1914
+ claude-sonnet-5-5 and every later Sonnet) runs on its full native 1M context window; the harness
1915
+ never caps a Sonnet. Anthropic serves 1M by default on these models (no beta header). Resolved
1916
+ config, models.json, compaction and session snapshots all read this one value. */
1917
+ function resolveJohnnessSonnetNativeContextWindow(providerId, modelId) {
1918
+ const JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS = 1e6; // function-scoped: callable before module init completes
1919
+ if (String(providerId ?? "").trim().toLowerCase() !== "anthropic") return;
1920
+ const match = /^claude-sonnet-(\d+)(?:-(\d{1,2}))?(?:-\d{8})?$/.exec(String(modelId ?? "").trim().toLowerCase());
1921
+ if (!match) return;
1922
+ const major = Number(match[1]);
1923
+ const minor = Number(match[2] ?? 0);
1924
+ if (major > 4 || (major === 4 && minor >= 6)) return JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS;
1925
+ }
1913
1926
  function applyAgentDefaults(cfg) {
1914
1927
  const agents = cfg.agents;
1915
1928
  const defaults = agents?.defaults;
@@ -45,6 +45,43 @@ function applyJohnnessOpusContextWindows(providers) {
45
45
  }
46
46
  };
47
47
  }
48
+ /* JOHNNESS_PATCH_SONNET_55_MODEL: every Anthropic Sonnet from Sonnet 4.6 on (claude-sonnet-4-6, claude-sonnet-5,
49
+ claude-sonnet-5-5 and every later Sonnet) runs on its full native 1M context window; the harness
50
+ never caps a Sonnet. Anthropic serves 1M by default on these models (no beta header). Resolved
51
+ config, models.json, compaction and session snapshots all read this one value. */
52
+ function resolveJohnnessSonnetNativeContextWindow(providerId, modelId) {
53
+ const JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS = 1e6; // function-scoped: callable before module init completes
54
+ if (String(providerId ?? "").trim().toLowerCase() !== "anthropic") return;
55
+ const match = /^claude-sonnet-(\d+)(?:-(\d{1,2}))?(?:-\d{8})?$/.exec(String(modelId ?? "").trim().toLowerCase());
56
+ if (!match) return;
57
+ const major = Number(match[1]);
58
+ const minor = Number(match[2] ?? 0);
59
+ if (major > 4 || (major === 4 && minor >= 6)) return JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS;
60
+ }
61
+ function applyJohnnessSonnetNativeContextWindows(providers) {
62
+ const anthropicKey = Object.keys(providers).find((key) => key.trim().toLowerCase() === "anthropic");
63
+ if (!anthropicKey) return providers;
64
+ const anthropic = providers[anthropicKey];
65
+ if (!Array.isArray(anthropic?.models)) return providers;
66
+ let mutated = false;
67
+ const models = anthropic.models.map((model) => {
68
+ const nativeWindow = resolveJohnnessSonnetNativeContextWindow("anthropic", model?.id);
69
+ if (!nativeWindow || model.contextWindow === nativeWindow) return model;
70
+ mutated = true;
71
+ return {
72
+ ...model,
73
+ contextWindow: nativeWindow
74
+ };
75
+ });
76
+ if (!mutated) return providers;
77
+ return {
78
+ ...providers,
79
+ [anthropicKey]: {
80
+ ...anthropic,
81
+ models
82
+ }
83
+ };
84
+ }
48
85
  function isPositiveFiniteTokenLimit(value) {
49
86
  return typeof value === "number" && Number.isFinite(value) && value > 0;
50
87
  }
@@ -141,7 +178,7 @@ async function resolveProvidersForModelsJson(params) {
141
178
  }
142
179
  const implicitCopilot = await resolveImplicitCopilotProvider({ agentDir });
143
180
  if (implicitCopilot && !providers["github-copilot"]) providers["github-copilot"] = implicitCopilot;
144
- return applyJohnnessOpusContextWindows(providers);
181
+ return applyJohnnessSonnetNativeContextWindows(applyJohnnessOpusContextWindows(providers)); // JOHNNESS_PATCH_SONNET_55_MODEL
145
182
  }
146
183
  function mergeWithExistingProviderSecrets(params) {
147
184
  const { nextProviders, existingProviders, secretRefManagedProviders, explicitBaseUrlProviders } = params;
@@ -45,6 +45,43 @@ function applyJohnnessOpusContextWindows(providers) {
45
45
  }
46
46
  };
47
47
  }
48
+ /* JOHNNESS_PATCH_SONNET_55_MODEL: every Anthropic Sonnet from Sonnet 4.6 on (claude-sonnet-4-6, claude-sonnet-5,
49
+ claude-sonnet-5-5 and every later Sonnet) runs on its full native 1M context window; the harness
50
+ never caps a Sonnet. Anthropic serves 1M by default on these models (no beta header). Resolved
51
+ config, models.json, compaction and session snapshots all read this one value. */
52
+ function resolveJohnnessSonnetNativeContextWindow(providerId, modelId) {
53
+ const JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS = 1e6; // function-scoped: callable before module init completes
54
+ if (String(providerId ?? "").trim().toLowerCase() !== "anthropic") return;
55
+ const match = /^claude-sonnet-(\d+)(?:-(\d{1,2}))?(?:-\d{8})?$/.exec(String(modelId ?? "").trim().toLowerCase());
56
+ if (!match) return;
57
+ const major = Number(match[1]);
58
+ const minor = Number(match[2] ?? 0);
59
+ if (major > 4 || (major === 4 && minor >= 6)) return JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS;
60
+ }
61
+ function applyJohnnessSonnetNativeContextWindows(providers) {
62
+ const anthropicKey = Object.keys(providers).find((key) => key.trim().toLowerCase() === "anthropic");
63
+ if (!anthropicKey) return providers;
64
+ const anthropic = providers[anthropicKey];
65
+ if (!Array.isArray(anthropic?.models)) return providers;
66
+ let mutated = false;
67
+ const models = anthropic.models.map((model) => {
68
+ const nativeWindow = resolveJohnnessSonnetNativeContextWindow("anthropic", model?.id);
69
+ if (!nativeWindow || model.contextWindow === nativeWindow) return model;
70
+ mutated = true;
71
+ return {
72
+ ...model,
73
+ contextWindow: nativeWindow
74
+ };
75
+ });
76
+ if (!mutated) return providers;
77
+ return {
78
+ ...providers,
79
+ [anthropicKey]: {
80
+ ...anthropic,
81
+ models
82
+ }
83
+ };
84
+ }
48
85
  function isPositiveFiniteTokenLimit(value) {
49
86
  return typeof value === "number" && Number.isFinite(value) && value > 0;
50
87
  }
@@ -141,7 +178,7 @@ async function resolveProvidersForModelsJson(params) {
141
178
  }
142
179
  const implicitCopilot = await resolveImplicitCopilotProvider({ agentDir });
143
180
  if (implicitCopilot && !providers["github-copilot"]) providers["github-copilot"] = implicitCopilot;
144
- return applyJohnnessOpusContextWindows(providers);
181
+ return applyJohnnessSonnetNativeContextWindows(applyJohnnessOpusContextWindows(providers)); // JOHNNESS_PATCH_SONNET_55_MODEL
145
182
  }
146
183
  function mergeWithExistingProviderSecrets(params) {
147
184
  const { nextProviders, existingProviders, secretRefManagedProviders, explicitBaseUrlProviders } = params;
@@ -7312,7 +7312,7 @@ function applyModelDefaults(cfg) {
7312
7312
  if (raw.input === void 0) modelMutated = true;
7313
7313
  const cost = resolveModelCost(raw.cost);
7314
7314
  if (!raw.cost || raw.cost.input !== cost.input || raw.cost.output !== cost.output || raw.cost.cacheRead !== cost.cacheRead || raw.cost.cacheWrite !== cost.cacheWrite) modelMutated = true;
7315
- const contextWindow = isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS;
7315
+ const contextWindow = resolveJohnnessSonnetNativeContextWindow(providerId, raw.id) ?? (isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS); // JOHNNESS_PATCH_SONNET_55_MODEL
7316
7316
  if (raw.contextWindow !== contextWindow) modelMutated = true;
7317
7317
  const defaultMaxTokens = Math.min(DEFAULT_MODEL_MAX_TOKENS, contextWindow);
7318
7318
  const rawMaxTokens = isPositiveNumber(raw.maxTokens) ? raw.maxTokens : defaultMaxTokens;
@@ -7378,6 +7378,19 @@ function applyModelDefaults(cfg) {
7378
7378
  }
7379
7379
  };
7380
7380
  }
7381
+ /* JOHNNESS_PATCH_SONNET_55_MODEL: every Anthropic Sonnet from Sonnet 4.6 on (claude-sonnet-4-6, claude-sonnet-5,
7382
+ claude-sonnet-5-5 and every later Sonnet) runs on its full native 1M context window; the harness
7383
+ never caps a Sonnet. Anthropic serves 1M by default on these models (no beta header). Resolved
7384
+ config, models.json, compaction and session snapshots all read this one value. */
7385
+ function resolveJohnnessSonnetNativeContextWindow(providerId, modelId) {
7386
+ const JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS = 1e6; // function-scoped: callable before module init completes
7387
+ if (String(providerId ?? "").trim().toLowerCase() !== "anthropic") return;
7388
+ const match = /^claude-sonnet-(\d+)(?:-(\d{1,2}))?(?:-\d{8})?$/.exec(String(modelId ?? "").trim().toLowerCase());
7389
+ if (!match) return;
7390
+ const major = Number(match[1]);
7391
+ const minor = Number(match[2] ?? 0);
7392
+ if (major > 4 || (major === 4 && minor >= 6)) return JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS;
7393
+ }
7381
7394
  function applyAgentDefaults(cfg) {
7382
7395
  const agents = cfg.agents;
7383
7396
  const defaults = agents?.defaults;
@@ -8313,7 +8313,7 @@ function applyModelDefaults(cfg) {
8313
8313
  if (raw.input === void 0) modelMutated = true;
8314
8314
  const cost = resolveModelCost(raw.cost);
8315
8315
  if (!raw.cost || raw.cost.input !== cost.input || raw.cost.output !== cost.output || raw.cost.cacheRead !== cost.cacheRead || raw.cost.cacheWrite !== cost.cacheWrite) modelMutated = true;
8316
- const contextWindow = isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS;
8316
+ const contextWindow = resolveJohnnessSonnetNativeContextWindow(providerId, raw.id) ?? (isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS); // JOHNNESS_PATCH_SONNET_55_MODEL
8317
8317
  if (raw.contextWindow !== contextWindow) modelMutated = true;
8318
8318
  const defaultMaxTokens = Math.min(DEFAULT_MODEL_MAX_TOKENS, contextWindow);
8319
8319
  const rawMaxTokens = isPositiveNumber(raw.maxTokens) ? raw.maxTokens : defaultMaxTokens;
@@ -8379,6 +8379,19 @@ function applyModelDefaults(cfg) {
8379
8379
  }
8380
8380
  };
8381
8381
  }
8382
+ /* JOHNNESS_PATCH_SONNET_55_MODEL: every Anthropic Sonnet from Sonnet 4.6 on (claude-sonnet-4-6, claude-sonnet-5,
8383
+ claude-sonnet-5-5 and every later Sonnet) runs on its full native 1M context window; the harness
8384
+ never caps a Sonnet. Anthropic serves 1M by default on these models (no beta header). Resolved
8385
+ config, models.json, compaction and session snapshots all read this one value. */
8386
+ function resolveJohnnessSonnetNativeContextWindow(providerId, modelId) {
8387
+ const JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS = 1e6; // function-scoped: callable before module init completes
8388
+ if (String(providerId ?? "").trim().toLowerCase() !== "anthropic") return;
8389
+ const match = /^claude-sonnet-(\d+)(?:-(\d{1,2}))?(?:-\d{8})?$/.exec(String(modelId ?? "").trim().toLowerCase());
8390
+ if (!match) return;
8391
+ const major = Number(match[1]);
8392
+ const minor = Number(match[2] ?? 0);
8393
+ if (major > 4 || (major === 4 && minor >= 6)) return JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS;
8394
+ }
8382
8395
  function applyAgentDefaults(cfg) {
8383
8396
  const agents = cfg.agents;
8384
8397
  const defaults = agents?.defaults;
@@ -5442,7 +5442,7 @@ function applyModelDefaults(cfg) {
5442
5442
  if (raw.input === void 0) modelMutated = true;
5443
5443
  const cost = resolveModelCost(raw.cost);
5444
5444
  if (!raw.cost || raw.cost.input !== cost.input || raw.cost.output !== cost.output || raw.cost.cacheRead !== cost.cacheRead || raw.cost.cacheWrite !== cost.cacheWrite) modelMutated = true;
5445
- const contextWindow = isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS;
5445
+ const contextWindow = resolveJohnnessSonnetNativeContextWindow(providerId, raw.id) ?? (isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS); // JOHNNESS_PATCH_SONNET_55_MODEL
5446
5446
  if (raw.contextWindow !== contextWindow) modelMutated = true;
5447
5447
  const defaultMaxTokens = Math.min(DEFAULT_MODEL_MAX_TOKENS, contextWindow);
5448
5448
  const rawMaxTokens = isPositiveNumber(raw.maxTokens) ? raw.maxTokens : defaultMaxTokens;
@@ -5508,6 +5508,19 @@ function applyModelDefaults(cfg) {
5508
5508
  }
5509
5509
  };
5510
5510
  }
5511
+ /* JOHNNESS_PATCH_SONNET_55_MODEL: every Anthropic Sonnet from Sonnet 4.6 on (claude-sonnet-4-6, claude-sonnet-5,
5512
+ claude-sonnet-5-5 and every later Sonnet) runs on its full native 1M context window; the harness
5513
+ never caps a Sonnet. Anthropic serves 1M by default on these models (no beta header). Resolved
5514
+ config, models.json, compaction and session snapshots all read this one value. */
5515
+ function resolveJohnnessSonnetNativeContextWindow(providerId, modelId) {
5516
+ const JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS = 1e6; // function-scoped: callable before module init completes
5517
+ if (String(providerId ?? "").trim().toLowerCase() !== "anthropic") return;
5518
+ const match = /^claude-sonnet-(\d+)(?:-(\d{1,2}))?(?:-\d{8})?$/.exec(String(modelId ?? "").trim().toLowerCase());
5519
+ if (!match) return;
5520
+ const major = Number(match[1]);
5521
+ const minor = Number(match[2] ?? 0);
5522
+ if (major > 4 || (major === 4 && minor >= 6)) return JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS;
5523
+ }
5511
5524
  function applyAgentDefaults(cfg) {
5512
5525
  const agents = cfg.agents;
5513
5526
  const defaults = agents?.defaults;
@@ -6233,7 +6233,7 @@ function applyModelDefaults(cfg) {
6233
6233
  if (raw.input === void 0) modelMutated = true;
6234
6234
  const cost = resolveModelCost(raw.cost);
6235
6235
  if (!raw.cost || raw.cost.input !== cost.input || raw.cost.output !== cost.output || raw.cost.cacheRead !== cost.cacheRead || raw.cost.cacheWrite !== cost.cacheWrite) modelMutated = true;
6236
- const contextWindow = isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS;
6236
+ const contextWindow = resolveJohnnessSonnetNativeContextWindow(providerId, raw.id) ?? (isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS); // JOHNNESS_PATCH_SONNET_55_MODEL
6237
6237
  if (raw.contextWindow !== contextWindow) modelMutated = true;
6238
6238
  const defaultMaxTokens = Math.min(DEFAULT_MODEL_MAX_TOKENS, contextWindow);
6239
6239
  const rawMaxTokens = isPositiveNumber(raw.maxTokens) ? raw.maxTokens : defaultMaxTokens;
@@ -6299,6 +6299,19 @@ function applyModelDefaults(cfg) {
6299
6299
  }
6300
6300
  };
6301
6301
  }
6302
+ /* JOHNNESS_PATCH_SONNET_55_MODEL: every Anthropic Sonnet from Sonnet 4.6 on (claude-sonnet-4-6, claude-sonnet-5,
6303
+ claude-sonnet-5-5 and every later Sonnet) runs on its full native 1M context window; the harness
6304
+ never caps a Sonnet. Anthropic serves 1M by default on these models (no beta header). Resolved
6305
+ config, models.json, compaction and session snapshots all read this one value. */
6306
+ function resolveJohnnessSonnetNativeContextWindow(providerId, modelId) {
6307
+ const JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS = 1e6; // function-scoped: callable before module init completes
6308
+ if (String(providerId ?? "").trim().toLowerCase() !== "anthropic") return;
6309
+ const match = /^claude-sonnet-(\d+)(?:-(\d{1,2}))?(?:-\d{8})?$/.exec(String(modelId ?? "").trim().toLowerCase());
6310
+ if (!match) return;
6311
+ const major = Number(match[1]);
6312
+ const minor = Number(match[2] ?? 0);
6313
+ if (major > 4 || (major === 4 && minor >= 6)) return JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS;
6314
+ }
6302
6315
  function applyAgentDefaults(cfg) {
6303
6316
  const agents = cfg.agents;
6304
6317
  const defaults = agents?.defaults;
@@ -5202,7 +5202,7 @@ function applyModelDefaults(cfg) {
5202
5202
  if (raw.input === void 0) modelMutated = true;
5203
5203
  const cost = resolveModelCost(raw.cost);
5204
5204
  if (!raw.cost || raw.cost.input !== cost.input || raw.cost.output !== cost.output || raw.cost.cacheRead !== cost.cacheRead || raw.cost.cacheWrite !== cost.cacheWrite) modelMutated = true;
5205
- const contextWindow = isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS;
5205
+ const contextWindow = resolveJohnnessSonnetNativeContextWindow(providerId, raw.id) ?? (isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS); // JOHNNESS_PATCH_SONNET_55_MODEL
5206
5206
  if (raw.contextWindow !== contextWindow) modelMutated = true;
5207
5207
  const defaultMaxTokens = Math.min(DEFAULT_MODEL_MAX_TOKENS, contextWindow);
5208
5208
  const rawMaxTokens = isPositiveNumber(raw.maxTokens) ? raw.maxTokens : defaultMaxTokens;
@@ -5268,6 +5268,19 @@ function applyModelDefaults(cfg) {
5268
5268
  }
5269
5269
  };
5270
5270
  }
5271
+ /* JOHNNESS_PATCH_SONNET_55_MODEL: every Anthropic Sonnet from Sonnet 4.6 on (claude-sonnet-4-6, claude-sonnet-5,
5272
+ claude-sonnet-5-5 and every later Sonnet) runs on its full native 1M context window; the harness
5273
+ never caps a Sonnet. Anthropic serves 1M by default on these models (no beta header). Resolved
5274
+ config, models.json, compaction and session snapshots all read this one value. */
5275
+ function resolveJohnnessSonnetNativeContextWindow(providerId, modelId) {
5276
+ const JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS = 1e6; // function-scoped: callable before module init completes
5277
+ if (String(providerId ?? "").trim().toLowerCase() !== "anthropic") return;
5278
+ const match = /^claude-sonnet-(\d+)(?:-(\d{1,2}))?(?:-\d{8})?$/.exec(String(modelId ?? "").trim().toLowerCase());
5279
+ if (!match) return;
5280
+ const major = Number(match[1]);
5281
+ const minor = Number(match[2] ?? 0);
5282
+ if (major > 4 || (major === 4 && minor >= 6)) return JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS;
5283
+ }
5271
5284
  function applyAgentDefaults(cfg) {
5272
5285
  const agents = cfg.agents;
5273
5286
  const defaults = agents?.defaults;
@@ -5206,7 +5206,7 @@ function applyModelDefaults(cfg) {
5206
5206
  if (raw.input === void 0) modelMutated = true;
5207
5207
  const cost = resolveModelCost(raw.cost);
5208
5208
  if (!raw.cost || raw.cost.input !== cost.input || raw.cost.output !== cost.output || raw.cost.cacheRead !== cost.cacheRead || raw.cost.cacheWrite !== cost.cacheWrite) modelMutated = true;
5209
- const contextWindow = isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS;
5209
+ const contextWindow = resolveJohnnessSonnetNativeContextWindow(providerId, raw.id) ?? (isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS); // JOHNNESS_PATCH_SONNET_55_MODEL
5210
5210
  if (raw.contextWindow !== contextWindow) modelMutated = true;
5211
5211
  const defaultMaxTokens = Math.min(DEFAULT_MODEL_MAX_TOKENS, contextWindow);
5212
5212
  const rawMaxTokens = isPositiveNumber(raw.maxTokens) ? raw.maxTokens : defaultMaxTokens;
@@ -5272,6 +5272,19 @@ function applyModelDefaults(cfg) {
5272
5272
  }
5273
5273
  };
5274
5274
  }
5275
+ /* JOHNNESS_PATCH_SONNET_55_MODEL: every Anthropic Sonnet from Sonnet 4.6 on (claude-sonnet-4-6, claude-sonnet-5,
5276
+ claude-sonnet-5-5 and every later Sonnet) runs on its full native 1M context window; the harness
5277
+ never caps a Sonnet. Anthropic serves 1M by default on these models (no beta header). Resolved
5278
+ config, models.json, compaction and session snapshots all read this one value. */
5279
+ function resolveJohnnessSonnetNativeContextWindow(providerId, modelId) {
5280
+ const JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS = 1e6; // function-scoped: callable before module init completes
5281
+ if (String(providerId ?? "").trim().toLowerCase() !== "anthropic") return;
5282
+ const match = /^claude-sonnet-(\d+)(?:-(\d{1,2}))?(?:-\d{8})?$/.exec(String(modelId ?? "").trim().toLowerCase());
5283
+ if (!match) return;
5284
+ const major = Number(match[1]);
5285
+ const minor = Number(match[2] ?? 0);
5286
+ if (major > 4 || (major === 4 && minor >= 6)) return JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS;
5287
+ }
5275
5288
  function applyAgentDefaults(cfg) {
5276
5289
  const agents = cfg.agents;
5277
5290
  const defaults = agents?.defaults;
@@ -5206,7 +5206,7 @@ function applyModelDefaults(cfg) {
5206
5206
  if (raw.input === void 0) modelMutated = true;
5207
5207
  const cost = resolveModelCost(raw.cost);
5208
5208
  if (!raw.cost || raw.cost.input !== cost.input || raw.cost.output !== cost.output || raw.cost.cacheRead !== cost.cacheRead || raw.cost.cacheWrite !== cost.cacheWrite) modelMutated = true;
5209
- const contextWindow = isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS;
5209
+ const contextWindow = resolveJohnnessSonnetNativeContextWindow(providerId, raw.id) ?? (isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS); // JOHNNESS_PATCH_SONNET_55_MODEL
5210
5210
  if (raw.contextWindow !== contextWindow) modelMutated = true;
5211
5211
  const defaultMaxTokens = Math.min(DEFAULT_MODEL_MAX_TOKENS, contextWindow);
5212
5212
  const rawMaxTokens = isPositiveNumber(raw.maxTokens) ? raw.maxTokens : defaultMaxTokens;
@@ -5272,6 +5272,19 @@ function applyModelDefaults(cfg) {
5272
5272
  }
5273
5273
  };
5274
5274
  }
5275
+ /* JOHNNESS_PATCH_SONNET_55_MODEL: every Anthropic Sonnet from Sonnet 4.6 on (claude-sonnet-4-6, claude-sonnet-5,
5276
+ claude-sonnet-5-5 and every later Sonnet) runs on its full native 1M context window; the harness
5277
+ never caps a Sonnet. Anthropic serves 1M by default on these models (no beta header). Resolved
5278
+ config, models.json, compaction and session snapshots all read this one value. */
5279
+ function resolveJohnnessSonnetNativeContextWindow(providerId, modelId) {
5280
+ const JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS = 1e6; // function-scoped: callable before module init completes
5281
+ if (String(providerId ?? "").trim().toLowerCase() !== "anthropic") return;
5282
+ const match = /^claude-sonnet-(\d+)(?:-(\d{1,2}))?(?:-\d{8})?$/.exec(String(modelId ?? "").trim().toLowerCase());
5283
+ if (!match) return;
5284
+ const major = Number(match[1]);
5285
+ const minor = Number(match[2] ?? 0);
5286
+ if (major > 4 || (major === 4 && minor >= 6)) return JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS;
5287
+ }
5275
5288
  function applyAgentDefaults(cfg) {
5276
5289
  const agents = cfg.agents;
5277
5290
  const defaults = agents?.defaults;
@@ -5015,7 +5015,7 @@ function applyModelDefaults(cfg) {
5015
5015
  if (raw.input === void 0) modelMutated = true;
5016
5016
  const cost = resolveModelCost(raw.cost);
5017
5017
  if (!raw.cost || raw.cost.input !== cost.input || raw.cost.output !== cost.output || raw.cost.cacheRead !== cost.cacheRead || raw.cost.cacheWrite !== cost.cacheWrite) modelMutated = true;
5018
- const contextWindow = isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS;
5018
+ const contextWindow = resolveJohnnessSonnetNativeContextWindow(providerId, raw.id) ?? (isPositiveNumber(raw.contextWindow) ? raw.contextWindow : DEFAULT_CONTEXT_TOKENS); // JOHNNESS_PATCH_SONNET_55_MODEL
5019
5019
  if (raw.contextWindow !== contextWindow) modelMutated = true;
5020
5020
  const defaultMaxTokens = Math.min(DEFAULT_MODEL_MAX_TOKENS, contextWindow);
5021
5021
  const rawMaxTokens = isPositiveNumber(raw.maxTokens) ? raw.maxTokens : defaultMaxTokens;
@@ -5081,6 +5081,19 @@ function applyModelDefaults(cfg) {
5081
5081
  }
5082
5082
  };
5083
5083
  }
5084
+ /* JOHNNESS_PATCH_SONNET_55_MODEL: every Anthropic Sonnet from Sonnet 4.6 on (claude-sonnet-4-6, claude-sonnet-5,
5085
+ claude-sonnet-5-5 and every later Sonnet) runs on its full native 1M context window; the harness
5086
+ never caps a Sonnet. Anthropic serves 1M by default on these models (no beta header). Resolved
5087
+ config, models.json, compaction and session snapshots all read this one value. */
5088
+ function resolveJohnnessSonnetNativeContextWindow(providerId, modelId) {
5089
+ const JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS = 1e6; // function-scoped: callable before module init completes
5090
+ if (String(providerId ?? "").trim().toLowerCase() !== "anthropic") return;
5091
+ const match = /^claude-sonnet-(\d+)(?:-(\d{1,2}))?(?:-\d{8})?$/.exec(String(modelId ?? "").trim().toLowerCase());
5092
+ if (!match) return;
5093
+ const major = Number(match[1]);
5094
+ const minor = Number(match[2] ?? 0);
5095
+ if (major > 4 || (major === 4 && minor >= 6)) return JOHNNESS_SONNET_NATIVE_CONTEXT_TOKENS;
5096
+ }
5084
5097
  function applyAgentDefaults(cfg) {
5085
5098
  const agents = cfg.agents;
5086
5099
  const defaults = agents?.defaults;
package/docs/PATCHES.md CHANGED
@@ -107,6 +107,7 @@ Family 01 is retired. Families 02 through 41, 43 through 81, including the 65.1
107
107
  79. **79, cron reliability and shorthand freshness:** recurring cron transient retry, cron run fallbacks, `cron.failureLog`, and stale shorthand aliases move to the newest shipped model. [Details](#family-79-cron-reliability-and-shorthand-freshness-20269332)
108
108
  80. **80, daily model integration:** GPT-6 Sol and GPT-6 Luna (openai + openai-codex) and xAI Grok 4.7 registered; `sol`/`gpt`/`luna` move to GPT-6 with `sol56`/`luna56` kept, `grok` ships on Grok 4.7 with `grok46` kept. [Details](#80---daily-models-80-2026-09-24)
109
109
  81. **81, session store memory:** `skillsSnapshot` and `systemPromptReport` are no longer written to `sessions.json` (27 MB to under 1 MB on the live store), compact writes, maintenance enforces by default without touching active, main or recent sessions, and the gateway heap rises to min(8 GB, RAM/2). [Details](#81---session-store-memory-2026-09-28)
110
+ 82. **82, daily model integration:** Claude Sonnet 5.5 (`claude-sonnet-5-5`) registered; `sonnet` moves to it with `sonnet5` kept on Sonnet 5. Since 2026.9.37 every Sonnet runs on its full native 1M window. [Details](#82---sonnet-5-5-2026-09-29)
110
111
 
111
112
  ---
112
113
 
@@ -2854,10 +2855,21 @@ The gateway heap grew about 65 MB an hour and hit the Node default limit (about
2854
2855
  Second run of the daily model integration. One new model appeared in the authenticated provider lists since the 2026-09-28 run (Anthropic 12 -> 13: `claude-sonnet-5-5`); it is registered from its official page (checked 2026-09-29) and was wire-probed live.
2855
2856
 
2856
2857
  - **Claude Sonnet 5.5** (`claude-sonnet-5-5`, anthropic, native Messages). Source: <https://platform.claude.com/docs/en/models/sonnet-5-5/overview> (checked 2026-09-29). Fixed API id, no date suffix (Bedrock `anthropic.claude-sonnet-5-5`); released 2026-09-28. 1,000,000-token native context, 128,000 max output (300K on the Message Batches API with the `output-300k-2026-03-24` beta header), text + images in and text out, knowledge cutoff Jun 2026. Adaptive thinking is on by default: the manual-budget thinking type is not accepted, effort is `low|medium|high|xhigh|max` with default `high`, and `between_tools` is the lowest setting (turns up-front thinking off at high or below). Non-default `temperature`/`top_p`/`top_k` return 400. Pricing $2/$10 per MTok, cache reads $0.20, 5m cache writes $2.50, 1h cache writes $4, Batch API 50% off. The authenticated Models API list agrees (max_input_tokens 1,000,000; max_tokens 128,000; adaptive thinking with `enabled: false`; effort incl. xhigh/max).
2857
- - **Context cap.** `contextWindow` ships at 175000, the standing Sonnet window (the Sonnet 5 value retained; owner caps do not change and a new model in a family keeps the latest cap of that family). `maxTokens` 128000. Sonnet 5's entry is untouched.
2858
+ - **Context window.** `contextWindow` is the full native 1,000,000 (since 2026.9.37; it first shipped at 175000). `maxTokens` 128000. See "Sonnet native 1M" below.
2858
2859
  - **Gates.** `supportsXhigh` gains an exact branch for `claude-sonnet-5-5` on anthropic; the Anthropic adapter's effort map accepts the id with 1:1 low/medium/high/xhigh/max (minimal -> low) and the temperature gate includes it, because non-default sampling params are 400s on this model. Adaptive thinking needs no new code: the existing `sonnet-5` substring gate already covers it. `XHIGH_MODEL_REFS` lists `anthropic/claude-sonnet-5-5` in all 12 copies, directly in front of the family 78 Opus 5.5 ref (families 78/80 refs stay contiguous).
2859
2860
  - **Aliases** (marker `JOHNNESS_PATCH_SONNET_55_MODEL`, a fourth `Object.assign(DEFAULT_MODEL_ALIASES, ...)` block in all 14 copies): `sonnet` -> `anthropic/claude-sonnet-5-5`, `sonnet5` -> `anthropic/claude-sonnet-5` (the previous version stays reachable). `opus`/`opus5`, the GPT-6/GPT-5.6 lines, `grok`, `astra`, `fable`, `sonnet46`, `deepseek` (Flash), `deepseek-pro`, `muse`, `gemini`, `banana`, `terra` and `image` are unchanged. On the next config load the family 79 migration moves a user alias that pins Sonnet 5 under `sonnet` to Sonnet 5.5 and gives the old model `sonnet5`; cross-line pins (e.g. `sonnet` on a Fable model) stay.
2860
- - **Exact replay.** `scripts/patch-sonnet-5-5-model.py` with `patches/sonnet-5-5/changes.json` (29 files: catalog, `models.js`, the Anthropic adapter, 12 thinking copies, 14 alias copies). Preimage/postimage sha256, all-file preflight, `--check`, `--record`, `--dependency-only`, `--present-only`. Families 67, 78 and 80 reverse the family 82 edits before their historical hash checks (80 re-layers them after replaying its own edits); the family 67 replay fixture now replays 78, 79, 80 and 82 in order.
2861
+ - **Exact replay.** `scripts/patch-sonnet-5-5-model.py` with `patches/sonnet-5-5/changes.json` (29 files at 2026.9.36: catalog, `models.js`, the Anthropic adapter, 12 thinking copies, 14 alias copies; 32 since 2026.9.37). Preimage/postimage sha256, all-file preflight, `--check`, `--record`, `--dependency-only`, `--present-only`. Families 67, 78 and 80 reverse the family 82 edits before their historical hash checks (80 re-layers them after replaying its own edits); the family 67 replay fixture now replays 78, 79, 80 and 82 in order.
2861
2862
  - Verifier 82.1-82.12; 63.12 now expects four contract blocks. Tests: `tests/sonnet-5-5-model.test.mjs` (catalog in both the overlay and installed pi-ai, the adaptive effort/temperature wire path, 12 xhigh copies, 14 alias copies, the family 79 migration, exact replay and older-family replays). Counts pinned by `fable-51-model` (anthropic catalog 30 -> 31) and the family 79 migration fixture were updated.
2862
2863
  - Live probes 2026-09-29 (128 max tokens, "Answer with the single word: OK"): the default request and the harness-shaped `thinking: {type: "adaptive"}` + `output_config: {effort: "xhigh"}` request both returned HTTP 200 with `stop_reason: end_turn`.
2863
2864
  - Roll back with `npm i -g johns-harness@2026.9.35`.
2865
+
2866
+ ### Sonnet native 1M (2026.9.37)
2867
+
2868
+ John's rule, permanent: every Sonnet model gets its full native 1M context window. The old "standing Sonnet window = 175K" is gone from the source, the patch scripts, the verifier and the daily model integration cron.
2869
+
2870
+ - **Catalog.** `claude-sonnet-5-5` 175000 -> 1000000, `claude-sonnet-5` 175000 -> 1000000 (it was capped), `claude-sonnet-4-6` 200000 -> 1000000. Max output unchanged (128K, 128K, 64K). Sonnet 4.5 and older keep 200K (their native window). Family 61's Sonnet 5 tuple in `scripts/patch-batteries-included-defaults.py` moves with the catalog so family 61 still regenerates the exact text.
2871
+ - **Resolver.** `resolveJohnnessSonnetNativeContextWindow(providerId, modelId)` returns 1e6 for `anthropic` + `claude-sonnet-4-6` and every later Sonnet (`claude-sonnet-<major>[-<minor>][-<date>]`, major > 4 or 4.6+), so a future Sonnet is 1M without a patch. It runs first in `applyModelDefaults` (all 14 alias copies), which lifts a stale user config that still pins a Sonnet at 175K to 1M at load, and in both `models-config` copies (`applyJohnnessSonnetNativeContextWindows` after the Opus caps) for the raw snapshot that writes `models.json`. Compaction, preflight and session snapshots read the resolved window, so they follow.
2872
+ - **No beta header.** Anthropic serves 1M by default on these models (`max_input_tokens` 1,000,000 in the authenticated Models API for `claude-sonnet-5-5`, `claude-sonnet-5` and `claude-sonnet-4-6`, checked 2026-09-29; the context-windows doc says 1M models need no beta header). The harness sends only `fine-grained-tool-streaming-2025-05-14`.
2873
+ - **Live probe 2026-09-29** through the harness's own pi-ai Anthropic adapter (`completeSimple`, API key auth): a 463,749-token prompt (count_tokens) to `claude-sonnet-5-5` returned `stop: end_turn` with the correct needle answer; usage reported 463,756 total tokens. A raw 648,450-token request also returned HTTP 200 (`usage.input_tokens` 648450).
2874
+ - Folded into the family 82 exact replay (32 files: + `scripts/patch-batteries-included-defaults.py` and the two `models-config` copies). Verifier 82.13-82.17. Tests in `tests/sonnet-5-5-model.test.mjs` execute the resolver in all 16 copies and run the real `loadConfig` in three loader bundles against an isolated state dir with a stale 175K config.
2875
+ - Roll back with `npm i -g johns-harness@2026.9.36`.
@@ -12,7 +12,7 @@ pinned 2026.3.7 foundation, not an upstream upgrade or a default-model change.
12
12
  | Meta | `muse-spark-1.3` (current), `muse-spark-1.2` (retained) | Responses, `https://api.meta.ai/v1` | text/image | 1,048,576 context; 131,072 output |
13
13
  | Google | `gemini-3.8-flash`, `gemini-3.5-flash-lite`; `gemini-3.1-pro-preview` remains explicitly preview | native `generateContent` | text/image in pi-ai; native API also accepts other media | 1,048,576 input; 65,536 output |
14
14
  | OpenAI | `gpt-6-astra`, `gpt-6-sol`, `gpt-6-luna` (Family 80), `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna` | Responses on API-key provider; Codex Responses on subscription | text/image | Native API 1,050,000 context / 922,000 input / 128,000 output; existing 272,000 effective harness context retained |
15
- | Anthropic | `claude-sonnet-5-5` (Family 82, current), `claude-opus-5-5` (Family 78), `claude-fable-5-1`, `claude-opus-5`, `claude-sonnet-5` | native Messages | text/image | Native 1M context / 128,000 output; Fable/Opus 300K owner caps and Opus 5.5's 500K cap retained, Sonnet 175K effective context retained (Sonnet 5.5 keeps it) |
15
+ | Anthropic | `claude-sonnet-5-5` (Family 82, current), `claude-opus-5-5` (Family 78), `claude-fable-5-1`, `claude-opus-5`, `claude-sonnet-5` | native Messages | text/image | Native 1M context / 128,000 output; Fable/Opus 300K owner caps and Opus 5.5's 500K cap retained; every Sonnet (4.6, 5, 5.5 and later) runs on its full native 1M window (2026.9.37) |
16
16
  | xAI | `grok-4.7` (Family 80, current), `grok-4.6` (retained) | Chat Completions | text/image | Native 500K context; exactly 200K owner cap retained; 64K output (4.7 does not publish a max output; the 4.6 value is kept) |
17
17
 
18
18
  `deepseek-flash` is **DeepSeek V4.1 Flash**, not “V1-flash.” The authenticated
@@ -1671,8 +1671,8 @@ export const MODELS = {
1671
1671
  2026-09-29: $2/$10 per MTok, cache reads $0.20, 5m cache writes $2.50, 1h writes $4,
1672
1672
  1M native context, 128K max output, adaptive thinking on by default (effort low through
1673
1673
  max, default high; between_tools turns up-front thinking off). temperature/top_p/top_k
1674
- non-default values return 400. contextWindow capped at 175000, the standing Sonnet
1675
- window (Sonnet 5 value retained; owner caps do not change). */
1674
+ non-default values return 400. contextWindow is the full native 1M (every Sonnet gets
1675
+ its native 1M window; no beta header needed). */
1676
1676
  "claude-sonnet-5-5": {
1677
1677
  id: "claude-sonnet-5-5",
1678
1678
  name: "Claude Sonnet 5.5",
@@ -1687,7 +1687,7 @@ export const MODELS = {
1687
1687
  cacheRead: 0.2,
1688
1688
  cacheWrite: 2.5,
1689
1689
  },
1690
- contextWindow: 175000,
1690
+ contextWindow: 1000000,
1691
1691
  maxTokens: 128000,
1692
1692
  },
1693
1693
  /* JOHNNESS_PATCH_OPUS_55_MODEL (family 78): Claude Opus 5.5. API id "claude-opus-5-5" (fixed id, no
@@ -1731,7 +1731,7 @@ export const MODELS = {
1731
1731
  contextWindow: 300000,
1732
1732
  maxTokens: 128000,
1733
1733
  },
1734
- /* JOHNNESS_PATCH_DEFAULTS_61 (family 61): Claude Sonnet 5; 175K effective context; native 1M; 2026-09-13 pricing. */
1734
+ /* JOHNNESS_PATCH_DEFAULTS_61 (family 61): Claude Sonnet 5; native 1M context; 2026-09-13 pricing. */
1735
1735
  "claude-sonnet-5": {
1736
1736
  id: "claude-sonnet-5",
1737
1737
  name: "Claude Sonnet 5",
@@ -1746,7 +1746,7 @@ export const MODELS = {
1746
1746
  cacheRead: 0.2,
1747
1747
  cacheWrite: 2.5,
1748
1748
  },
1749
- contextWindow: 175000,
1749
+ contextWindow: 1000000,
1750
1750
  maxTokens: 128000,
1751
1751
  },
1752
1752
  /* JOHNNESS_PATCH_DEFAULTS_61 (family 61): Claude Fable 5; 300K fable cap, same as fable-5-1. */
@@ -2038,7 +2038,7 @@ export const MODELS = {
2038
2038
  cacheRead: 0.3,
2039
2039
  cacheWrite: 3.75,
2040
2040
  },
2041
- contextWindow: 200000,
2041
+ contextWindow: 1000000, // JOHNNESS_PATCH_SONNET_55_MODEL: every Sonnet gets its native 1M window
2042
2042
  maxTokens: 64000,
2043
2043
  },
2044
2044
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "johns-harness",
3
- "version": "2026.9.36",
3
+ "version": "2026.9.37",
4
4
  "description": "John's Harness: a production agent harness that runs autonomous coding agents as one cooperative swarm.",
5
5
  "keywords": [
6
6
  "ai-agents",
@@ -1671,8 +1671,8 @@ export const MODELS = {
1671
1671
  2026-09-29: $2/$10 per MTok, cache reads $0.20, 5m cache writes $2.50, 1h writes $4,
1672
1672
  1M native context, 128K max output, adaptive thinking on by default (effort low through
1673
1673
  max, default high; between_tools turns up-front thinking off). temperature/top_p/top_k
1674
- non-default values return 400. contextWindow capped at 175000, the standing Sonnet
1675
- window (Sonnet 5 value retained; owner caps do not change). */
1674
+ non-default values return 400. contextWindow is the full native 1M (every Sonnet gets
1675
+ its native 1M window; no beta header needed). */
1676
1676
  "claude-sonnet-5-5": {
1677
1677
  id: "claude-sonnet-5-5",
1678
1678
  name: "Claude Sonnet 5.5",
@@ -1687,7 +1687,7 @@ export const MODELS = {
1687
1687
  cacheRead: 0.2,
1688
1688
  cacheWrite: 2.5,
1689
1689
  },
1690
- contextWindow: 175000,
1690
+ contextWindow: 1000000,
1691
1691
  maxTokens: 128000,
1692
1692
  },
1693
1693
  /* JOHNNESS_PATCH_OPUS_55_MODEL (family 78): Claude Opus 5.5. API id "claude-opus-5-5" (fixed id, no
@@ -1731,7 +1731,7 @@ export const MODELS = {
1731
1731
  contextWindow: 300000,
1732
1732
  maxTokens: 128000,
1733
1733
  },
1734
- /* JOHNNESS_PATCH_DEFAULTS_61 (family 61): Claude Sonnet 5; 175K effective context; native 1M; 2026-09-13 pricing. */
1734
+ /* JOHNNESS_PATCH_DEFAULTS_61 (family 61): Claude Sonnet 5; native 1M context; 2026-09-13 pricing. */
1735
1735
  "claude-sonnet-5": {
1736
1736
  id: "claude-sonnet-5",
1737
1737
  name: "Claude Sonnet 5",
@@ -1746,7 +1746,7 @@ export const MODELS = {
1746
1746
  cacheRead: 0.2,
1747
1747
  cacheWrite: 2.5,
1748
1748
  },
1749
- contextWindow: 175000,
1749
+ contextWindow: 1000000,
1750
1750
  maxTokens: 128000,
1751
1751
  },
1752
1752
  /* JOHNNESS_PATCH_DEFAULTS_61 (family 61): Claude Fable 5; 300K fable cap, same as fable-5-1. */
@@ -2038,7 +2038,7 @@ export const MODELS = {
2038
2038
  cacheRead: 0.3,
2039
2039
  cacheWrite: 3.75,
2040
2040
  },
2041
- contextWindow: 200000,
2041
+ contextWindow: 1000000, // JOHNNESS_PATCH_SONNET_55_MODEL: every Sonnet gets its native 1M window
2042
2042
  maxTokens: 64000,
2043
2043
  },
2044
2044
  },