johns-harness 2026.9.32 → 2026.9.33

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,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 2026.9.33
4
+
5
+ - Claude Opus 5.5 context window cap raised from 300K to 500K (`contextWindow: 500000` in the shipped catalog and in both owner-cap paths). Opus 4.8 and Opus 5 stay at 300K. The single 300K set is now a per-model cap map (`JOHNNESS_OPUS_CONTEXT_TOKENS_BY_MODEL`); compaction and preflight follow the resolved window automatically. Verifier 78.4-78.7. Roll back with `npm i -g johns-harness@2026.9.32`.
6
+
3
7
  ## 2026.9.32
4
8
 
5
9
  - Family 79: recurring cron jobs retry transient errors (rate limit, overloaded, network, timeout, server error) at min(next natural slot, now + `cron.retry` backoff) up to `cron.retry.maxAttempts`, then return to the normal schedule, instead of burning the slot. Isolated cron runs always carry the default fallback chain, so a throttled job model falls through even when its provider differs from the default primary.
@@ -1802,11 +1802,19 @@ function applyTalkConfigNormalization(config) {
1802
1802
  window, but this scoped local ceiling keeps catalog, compaction, preflight,
1803
1803
  failover, and session snapshots on the same conservative budget. */
1804
1804
  const JOHNNESS_OPUS_CONTEXT_TOKENS = 3e5;
1805
- const JOHNNESS_OPUS_300K_MODEL_IDS = new Set(["claude-opus-4-8", "claude-opus-5", "claude-opus-5-5"]); // JOHNNESS_PATCH_OPUS_55_MODEL
1805
+ const JOHNNESS_OPUS_300K_MODEL_IDS = new Set(["claude-opus-4-8", "claude-opus-5"]);
1806
+ /* JOHNNESS_PATCH_OPUS_55_MODEL: per-model owner caps. Opus 4.8 and Opus 5 keep the family 30 300K budget;
1807
+ Claude Opus 5.5 is capped at 500K (1M native). Catalog, compaction and session snapshots
1808
+ all read the resolved contextWindow, so this map is the single source of the cap. */
1809
+ const JOHNNESS_OPUS_55_CONTEXT_TOKENS = 5e5;
1810
+ const JOHNNESS_OPUS_CONTEXT_TOKENS_BY_MODEL = new Map([
1811
+ ...[...JOHNNESS_OPUS_300K_MODEL_IDS].map((id) => [id, JOHNNESS_OPUS_CONTEXT_TOKENS]),
1812
+ ["claude-opus-5-5", JOHNNESS_OPUS_55_CONTEXT_TOKENS]
1813
+ ]);
1806
1814
  function resolveJohnnessOpusContextWindow(providerId, modelId) {
1807
1815
  if (normalizeProviderId(String(providerId ?? "")) !== "anthropic") return;
1808
1816
  const normalizedModelId = String(modelId ?? "").trim().toLowerCase();
1809
- if (JOHNNESS_OPUS_300K_MODEL_IDS.has(normalizedModelId)) return JOHNNESS_OPUS_CONTEXT_TOKENS;
1817
+ return JOHNNESS_OPUS_CONTEXT_TOKENS_BY_MODEL.get(normalizedModelId); // JOHNNESS_PATCH_OPUS_55_MODEL
1810
1818
  }
1811
1819
  /* JOHNNESS_PATCH_ALIAS_LATEST_79: bare shorthands (DEFAULT_MODEL_ALIASES keys without digits) always resolve
1812
1820
  * to the newest shipped model in their line. A user alias that claims one but pins an older model of the same
@@ -1777,11 +1777,19 @@ function applyTalkConfigNormalization(config) {
1777
1777
  window, but this scoped local ceiling keeps catalog, compaction, preflight,
1778
1778
  failover, and session snapshots on the same conservative budget. */
1779
1779
  const JOHNNESS_OPUS_CONTEXT_TOKENS = 3e5;
1780
- const JOHNNESS_OPUS_300K_MODEL_IDS = new Set(["claude-opus-4-8", "claude-opus-5", "claude-opus-5-5"]); // JOHNNESS_PATCH_OPUS_55_MODEL
1780
+ const JOHNNESS_OPUS_300K_MODEL_IDS = new Set(["claude-opus-4-8", "claude-opus-5"]);
1781
+ /* JOHNNESS_PATCH_OPUS_55_MODEL: per-model owner caps. Opus 4.8 and Opus 5 keep the family 30 300K budget;
1782
+ Claude Opus 5.5 is capped at 500K (1M native). Catalog, compaction and session snapshots
1783
+ all read the resolved contextWindow, so this map is the single source of the cap. */
1784
+ const JOHNNESS_OPUS_55_CONTEXT_TOKENS = 5e5;
1785
+ const JOHNNESS_OPUS_CONTEXT_TOKENS_BY_MODEL = new Map([
1786
+ ...[...JOHNNESS_OPUS_300K_MODEL_IDS].map((id) => [id, JOHNNESS_OPUS_CONTEXT_TOKENS]),
1787
+ ["claude-opus-5-5", JOHNNESS_OPUS_55_CONTEXT_TOKENS]
1788
+ ]);
1781
1789
  function resolveJohnnessOpusContextWindow(providerId, modelId) {
1782
1790
  if (normalizeProviderId(String(providerId ?? "")) !== "anthropic") return;
1783
1791
  const normalizedModelId = String(modelId ?? "").trim().toLowerCase();
1784
- if (JOHNNESS_OPUS_300K_MODEL_IDS.has(normalizedModelId)) return JOHNNESS_OPUS_CONTEXT_TOKENS;
1792
+ return JOHNNESS_OPUS_CONTEXT_TOKENS_BY_MODEL.get(normalizedModelId); // JOHNNESS_PATCH_OPUS_55_MODEL
1785
1793
  }
1786
1794
  /* JOHNNESS_PATCH_ALIAS_LATEST_79: bare shorthands (DEFAULT_MODEL_ALIASES keys without digits) always resolve
1787
1795
  * to the newest shipped model in their line. A user alias that claims one but pins an older model of the same
@@ -1708,11 +1708,19 @@ function applyTalkConfigNormalization(config) {
1708
1708
  window, but this scoped local ceiling keeps catalog, compaction, preflight,
1709
1709
  failover, and session snapshots on the same conservative budget. */
1710
1710
  const JOHNNESS_OPUS_CONTEXT_TOKENS = 3e5;
1711
- const JOHNNESS_OPUS_300K_MODEL_IDS = new Set(["claude-opus-4-8", "claude-opus-5", "claude-opus-5-5"]); // JOHNNESS_PATCH_OPUS_55_MODEL
1711
+ const JOHNNESS_OPUS_300K_MODEL_IDS = new Set(["claude-opus-4-8", "claude-opus-5"]);
1712
+ /* JOHNNESS_PATCH_OPUS_55_MODEL: per-model owner caps. Opus 4.8 and Opus 5 keep the family 30 300K budget;
1713
+ Claude Opus 5.5 is capped at 500K (1M native). Catalog, compaction and session snapshots
1714
+ all read the resolved contextWindow, so this map is the single source of the cap. */
1715
+ const JOHNNESS_OPUS_55_CONTEXT_TOKENS = 5e5;
1716
+ const JOHNNESS_OPUS_CONTEXT_TOKENS_BY_MODEL = new Map([
1717
+ ...[...JOHNNESS_OPUS_300K_MODEL_IDS].map((id) => [id, JOHNNESS_OPUS_CONTEXT_TOKENS]),
1718
+ ["claude-opus-5-5", JOHNNESS_OPUS_55_CONTEXT_TOKENS]
1719
+ ]);
1712
1720
  function resolveJohnnessOpusContextWindow(providerId, modelId) {
1713
1721
  if (normalizeProviderId(String(providerId ?? "")) !== "anthropic") return;
1714
1722
  const normalizedModelId = String(modelId ?? "").trim().toLowerCase();
1715
- if (JOHNNESS_OPUS_300K_MODEL_IDS.has(normalizedModelId)) return JOHNNESS_OPUS_CONTEXT_TOKENS;
1723
+ return JOHNNESS_OPUS_CONTEXT_TOKENS_BY_MODEL.get(normalizedModelId); // JOHNNESS_PATCH_OPUS_55_MODEL
1716
1724
  }
1717
1725
  /* JOHNNESS_PATCH_ALIAS_LATEST_79: bare shorthands (DEFAULT_MODEL_ALIASES keys without digits) always resolve
1718
1726
  * to the newest shipped model in their line. A user alias that claims one but pins an older model of the same
@@ -11,7 +11,15 @@ const MODELS_JSON_WRITE_LOCKS = /* @__PURE__ */ new Map();
11
11
  models.json is generated from the raw source snapshot. Do not broaden older
12
12
  Anthropic models or add aliases. */
13
13
  const JOHNNESS_OPUS_CONTEXT_TOKENS = 3e5;
14
- const JOHNNESS_OPUS_300K_MODEL_IDS = new Set(["claude-opus-4-8", "claude-opus-5", "claude-opus-5-5"]); // JOHNNESS_PATCH_OPUS_55_MODEL
14
+ const JOHNNESS_OPUS_300K_MODEL_IDS = new Set(["claude-opus-4-8", "claude-opus-5"]);
15
+ /* JOHNNESS_PATCH_OPUS_55_MODEL: per-model owner caps. Opus 4.8 and Opus 5 keep the family 30 300K budget;
16
+ Claude Opus 5.5 is capped at 500K (1M native). Catalog, compaction and session snapshots
17
+ all read the resolved contextWindow, so this map is the single source of the cap. */
18
+ const JOHNNESS_OPUS_55_CONTEXT_TOKENS = 5e5;
19
+ const JOHNNESS_OPUS_CONTEXT_TOKENS_BY_MODEL = new Map([
20
+ ...[...JOHNNESS_OPUS_300K_MODEL_IDS].map((id) => [id, JOHNNESS_OPUS_CONTEXT_TOKENS]),
21
+ ["claude-opus-5-5", JOHNNESS_OPUS_55_CONTEXT_TOKENS]
22
+ ]);
15
23
  function applyJohnnessOpusContextWindows(providers) {
16
24
  const anthropicKey = Object.keys(providers).find((key) => key.trim().toLowerCase() === "anthropic");
17
25
  if (!anthropicKey) return providers;
@@ -20,11 +28,12 @@ function applyJohnnessOpusContextWindows(providers) {
20
28
  let mutated = false;
21
29
  const models = anthropic.models.map((model) => {
22
30
  const modelId = String(model?.id ?? "").trim().toLowerCase();
23
- if (!JOHNNESS_OPUS_300K_MODEL_IDS.has(modelId) || model.contextWindow === JOHNNESS_OPUS_CONTEXT_TOKENS) return model;
31
+ const johnnessOpusCap = JOHNNESS_OPUS_CONTEXT_TOKENS_BY_MODEL.get(modelId); // JOHNNESS_PATCH_OPUS_55_MODEL
32
+ if (!johnnessOpusCap || model.contextWindow === johnnessOpusCap) return model;
24
33
  mutated = true;
25
34
  return {
26
35
  ...model,
27
- contextWindow: JOHNNESS_OPUS_CONTEXT_TOKENS
36
+ contextWindow: johnnessOpusCap
28
37
  };
29
38
  });
30
39
  if (!mutated) return providers;
@@ -11,7 +11,15 @@ const MODELS_JSON_WRITE_LOCKS = /* @__PURE__ */ new Map();
11
11
  models.json is generated from the raw source snapshot. Do not broaden older
12
12
  Anthropic models or add aliases. */
13
13
  const JOHNNESS_OPUS_CONTEXT_TOKENS = 3e5;
14
- const JOHNNESS_OPUS_300K_MODEL_IDS = new Set(["claude-opus-4-8", "claude-opus-5", "claude-opus-5-5"]); // JOHNNESS_PATCH_OPUS_55_MODEL
14
+ const JOHNNESS_OPUS_300K_MODEL_IDS = new Set(["claude-opus-4-8", "claude-opus-5"]);
15
+ /* JOHNNESS_PATCH_OPUS_55_MODEL: per-model owner caps. Opus 4.8 and Opus 5 keep the family 30 300K budget;
16
+ Claude Opus 5.5 is capped at 500K (1M native). Catalog, compaction and session snapshots
17
+ all read the resolved contextWindow, so this map is the single source of the cap. */
18
+ const JOHNNESS_OPUS_55_CONTEXT_TOKENS = 5e5;
19
+ const JOHNNESS_OPUS_CONTEXT_TOKENS_BY_MODEL = new Map([
20
+ ...[...JOHNNESS_OPUS_300K_MODEL_IDS].map((id) => [id, JOHNNESS_OPUS_CONTEXT_TOKENS]),
21
+ ["claude-opus-5-5", JOHNNESS_OPUS_55_CONTEXT_TOKENS]
22
+ ]);
15
23
  function applyJohnnessOpusContextWindows(providers) {
16
24
  const anthropicKey = Object.keys(providers).find((key) => key.trim().toLowerCase() === "anthropic");
17
25
  if (!anthropicKey) return providers;
@@ -20,11 +28,12 @@ function applyJohnnessOpusContextWindows(providers) {
20
28
  let mutated = false;
21
29
  const models = anthropic.models.map((model) => {
22
30
  const modelId = String(model?.id ?? "").trim().toLowerCase();
23
- if (!JOHNNESS_OPUS_300K_MODEL_IDS.has(modelId) || model.contextWindow === JOHNNESS_OPUS_CONTEXT_TOKENS) return model;
31
+ const johnnessOpusCap = JOHNNESS_OPUS_CONTEXT_TOKENS_BY_MODEL.get(modelId); // JOHNNESS_PATCH_OPUS_55_MODEL
32
+ if (!johnnessOpusCap || model.contextWindow === johnnessOpusCap) return model;
24
33
  mutated = true;
25
34
  return {
26
35
  ...model,
27
- contextWindow: JOHNNESS_OPUS_CONTEXT_TOKENS
36
+ contextWindow: johnnessOpusCap
28
37
  };
29
38
  });
30
39
  if (!mutated) return providers;
package/docs/PATCHES.md CHANGED
@@ -2803,10 +2803,11 @@ and historical replay; verifier 77.1 checks installed adapter hashes exactly.
2803
2803
 
2804
2804
  ## Family 78: Claude Opus 5.5 (2026.9.31)
2805
2805
 
2806
- - `anthropic/claude-opus-5-5` registered in the shipped pi-ai catalog (marker `JOHNNESS_PATCH_OPUS_55_MODEL`). Id, pricing ($4/$20, cache read $0.20, 5m write $5), 1M native context (300K owner cap via `JOHNNESS_OPUS_300K_MODEL_IDS`), 128K max output confirmed against `platform.claude.com/docs/en/models/opus-5-5` and its migration guide on 2026-09-23.
2806
+ - `anthropic/claude-opus-5-5` registered in the shipped pi-ai catalog (marker `JOHNNESS_PATCH_OPUS_55_MODEL`). Id, pricing ($4/$20, cache read $0.20, 5m write $5), 1M native context (500K owner cap since 2026.9.33, see below; 300K at 2026.9.31), 128K max output confirmed against `platform.claude.com/docs/en/models/opus-5-5` and its migration guide on 2026-09-23.
2807
2807
  - Adaptive thinking is always on for Opus 5.5 (`thinking.type` disabled/enabled are 400s); the adapter already sends `thinking: {type: "adaptive"}` via the `opus-5` substring gate, and effort maps 1:1 (xhigh and max are distinct). Sampling temperature is dropped for the model. `XHIGH_MODEL_REFS` lists it in all 12 copies.
2808
2808
  - `opus` alias moves to Opus 5.5 in all 14 alias copies through a second `Object.assign(DEFAULT_MODEL_ALIASES, ...)` block; `opus5` keeps Claude Opus 5 reachable and the opus-5 entry is untouched. `scripts/check-alias-contract.mjs` evaluates every contract block.
2809
2809
  - Exact replay: `scripts/patch-opus-5-5-model.py` with `patches/opus-5-5/changes.json` (31 files, preimage/postimage hashes, `--check`, `--dependency-only`, `--present-only`). Families 53 and 67 reverse the family 78 edits before checking their historical hashes. Verifier 78.1-78.3; 63.12 now expects two contract blocks.
2810
+ - **500K owner cap for Opus 5.5 (2026.9.33).** The family 30 set `JOHNNESS_OPUS_300K_MODEL_IDS` is back to `["claude-opus-4-8", "claude-opus-5"]` and a per-model map `JOHNNESS_OPUS_CONTEXT_TOKENS_BY_MODEL` now drives both cap paths in all five copies: `resolveJohnnessOpusContextWindow` (resolved config, three `model-selection` bundles) and `applyJohnnessOpusContextWindows` (models.json generation, two `models-config` bundles). Opus 4.8 and Opus 5 map to `JOHNNESS_OPUS_CONTEXT_TOKENS = 3e5`; `claude-opus-5-5` maps to `JOHNNESS_OPUS_55_CONTEXT_TOKENS = 5e5`. The shipped catalog entry carries `contextWindow: 500000`. Family 74 compaction, preflight and session snapshots read the resolved `contextWindow`, so no separate budget constant changes; the compaction threshold scales with the cap. Folded into the family 78 exact replay (same 31 files, manifest regenerated from the original preimages). Verifier 78.4-78.7 assert 5e5 for Opus 5.5 and 300K for Opus 4.8/Opus 5 in every cap copy and in the catalog; `tests/opus-55-context-500k.test.mjs` executes both cap functions per bundle.
2810
2811
 
2811
2812
  ## Family 79: cron reliability and shorthand freshness (2026.9.32)
2812
2813
 
@@ -1670,7 +1670,8 @@ export const MODELS = {
1670
1670
  date suffix) confirmed against platform.claude.com/docs/en/models/opus-5-5 on
1671
1671
  2026-09-23: $4/$20 per MTok, cache reads $0.20, 5m cache writes $5, 1M native
1672
1672
  context, 128K max output, adaptive thinking always on (effort is the only control,
1673
- default medium). contextWindow capped at 300K per the family 30 Opus budget. */
1673
+ default medium). contextWindow capped at 500K (owner cap for Opus 5.5; Opus 4.8 and
1674
+ Opus 5 keep the family 30 300K budget). */
1674
1675
  "claude-opus-5-5": {
1675
1676
  id: "claude-opus-5-5",
1676
1677
  name: "Claude Opus 5.5",
@@ -1685,7 +1686,7 @@ export const MODELS = {
1685
1686
  cacheRead: 0.2,
1686
1687
  cacheWrite: 5,
1687
1688
  },
1688
- contextWindow: 300000,
1689
+ contextWindow: 500000,
1689
1690
  maxTokens: 128000,
1690
1691
  },
1691
1692
  /* JOHNNESS_PATCH_DEFAULTS_61 (family 61): Claude Opus 5; native 1M window; 300K per family 30 Opus budget. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "johns-harness",
3
- "version": "2026.9.32",
3
+ "version": "2026.9.33",
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",
@@ -1670,7 +1670,8 @@ export const MODELS = {
1670
1670
  date suffix) confirmed against platform.claude.com/docs/en/models/opus-5-5 on
1671
1671
  2026-09-23: $4/$20 per MTok, cache reads $0.20, 5m cache writes $5, 1M native
1672
1672
  context, 128K max output, adaptive thinking always on (effort is the only control,
1673
- default medium). contextWindow capped at 300K per the family 30 Opus budget. */
1673
+ default medium). contextWindow capped at 500K (owner cap for Opus 5.5; Opus 4.8 and
1674
+ Opus 5 keep the family 30 300K budget). */
1674
1675
  "claude-opus-5-5": {
1675
1676
  id: "claude-opus-5-5",
1676
1677
  name: "Claude Opus 5.5",
@@ -1685,7 +1686,7 @@ export const MODELS = {
1685
1686
  cacheRead: 0.2,
1686
1687
  cacheWrite: 5,
1687
1688
  },
1688
- contextWindow: 300000,
1689
+ contextWindow: 500000,
1689
1690
  maxTokens: 128000,
1690
1691
  },
1691
1692
  /* JOHNNESS_PATCH_DEFAULTS_61 (family 61): Claude Opus 5; native 1M window; 300K per family 30 Opus budget. */