docks-kit 0.17.2 → 0.18.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.
package/AGENTS.md CHANGED
@@ -28,7 +28,8 @@ launcher can fall back to Bun source.
28
28
 
29
29
  | Path | Purpose |
30
30
  |------|---------|
31
- | `docks-kit` / `docks-kit.ps1` | POSIX and Windows CLI launchers. On supported hosts, each runs the matching binary in `cli/dist/` only when its `--version` matches `package.json`. Otherwise it runs Bun-from-source and auto-installs Bun plus `node_modules`. Hosts outside the support matrix fail before source fallback. The standalone platform release binary provides no-Bun recovery. |
31
+ | `docks-kit` / `docks-kit.ps1` | POSIX and Windows CLI launchers. On supported hosts, each runs the matching binary in `cli/dist/` only when its `--version` matches `package.json`. Otherwise it runs Bun-from-source and auto-installs Bun plus `node_modules`, and the mismatch warning names the rebuild remedy. A launcher never deletes a binary: on a host without Bun it is the only remaining recovery path. Hosts outside the support matrix fail before source fallback. The standalone platform release binary provides no-Bun recovery. |
32
+ | `cli/build-binaries.sh` | Compiles the six release binaries. It checksums the six known artifact names rather than globbing `docks-kit-*`, so a packed `docks-kit-<version>.tgz` is never attested as a release binary. It stamps `cli/dist/VERSION` only when the directory holds one version, and on the next build discards every artifact that stamp attributes to a different version, because a launcher refuses to run one and keeping it makes `SHA256SUMS` span two versions. An artifact with no stamp has unknown provenance and may be a hand-built or downloaded recovery binary, so the script keeps it and warns; `--prune` discards those too. Nothing here removes an artifact the stamp vouches for. |
32
33
  | `cli/src/engine-native/` | EngineNative implementation for `sync`, `model`, and `toolchain`; idempotent, flag-gated for destructive reconciliation |
33
34
  | `cli/src/engine-native/ompSync.ts` | omp file deployment, marketplace registration, and plugin synchronization |
34
35
  | `cli/src/commands/omp.ts` | `docks-kit omp` session launcher: renders the free-model run overlay and forwards args to omp |
@@ -54,7 +55,7 @@ launcher can fall back to Bun source.
54
55
 
55
56
  Codex SoT notes:
56
57
  - `SoT/.codex/AGENTS.md` deploys to `~/.codex/AGENTS.md` as global Codex instructions.
57
- - `SoT/.codex/config.toml` pins Codex to `model = "gpt-5.6-sol"`, sets normal and plan reasoning to `high` with concise summaries, and sets `model_verbosity = "low"`, `personality`, live top-level `web_search`, workspace-write sandboxing with sandboxed command network access, cross-session `memories` (+ dedicated note tools), `[agents]` subagent limits (`max_threads = 12`, `max_depth = 2` — intentionally above Codex defaults for broad parallel kit work; deeper recursion increases cost and predictability risk), a 128 KiB `project_doc_max_bytes` budget for the repo-side AGENTS.md chain (the global `~/.codex/AGENTS.md` is uncapped and not counted), and enables the two Docks plugins `docks@docks` and `plan-lifecycle@docks` (the shared plan lifecycle).
58
+ - `SoT/.codex/config.toml` pins Codex to `model = "gpt-6-sol"`, sets normal and plan reasoning to `high` with concise summaries, and sets `model_verbosity = "low"`, `personality`, live top-level `web_search`, workspace-write sandboxing with sandboxed command network access, cross-session `memories` (+ dedicated note tools), `[agents]` subagent limits (`max_threads = 12`, `max_depth = 2` — intentionally above Codex defaults for broad parallel kit work; deeper recursion increases cost and predictability risk), a 128 KiB `project_doc_max_bytes` budget for the repo-side AGENTS.md chain (the global `~/.codex/AGENTS.md` is uncapped and not counted), and enables the two Docks plugins `docks@docks` and `plan-lifecycle@docks` (the shared plan lifecycle).
58
59
  - `SoT/.codex/rules/*.rules` deploys to `~/.codex/rules/` as kit-managed Codex command policy. This is Codex's equivalent of permission allow/prompt/block rules; user-learned approvals in `~/.codex/rules/default.rules` are preserved.
59
60
  - `SoT/.codex/plugins/marketplace.json` deploys to Codex's personal marketplace path at `~/.agents/plugins/marketplace.json`; when the `codex` CLI is available, sync reruns `codex plugin add <plugin@marketplace>` for enabled SoT plugins so stale cached installs are refreshed.
60
61
  - Codex `/import` can copy Claude hooks into `~/.codex/hooks.json`. `codexSync.ts removeRetiredImportedHooks, legacy SessionStart cleanup` removes only recognized hooks from retired docks-kit Claude settings, backs up a changed file, and preserves user-authored hooks. The current Claude SessionStart program emits the structured JSON shape shared by both tools.
@@ -63,18 +64,22 @@ Codex SoT notes:
63
64
  - The `codex` CLI binary is upstream-owned, not kit-owned. The official standalone installer keeps package metadata under `$CODEX_HOME/packages/standalone` and places the `codex` symlink in `~/.local/bin` by default; sync only warns with a download-then-run installer command when the CLI is missing. Existing installs can self-update with `codex update`; npm and Homebrew remain upstream alternatives.
64
65
 
65
66
  - Claude runtime settings are an authoring template with sentinels. `claudeRuntime.ts` materializes absolute Bun/script paths only after the shared `bun.ts` bootstrap is ready; `claudeSync.ts` writes all runtime assets before atomically committing settings, then prunes the legacy shell scripts and Stop hook. Native `rate_limits` is the sole quota source, so jq/curl/OAuth caches are not runtime dependencies. A missing Bun defers only this cutover and preserves legacy pointers/files.
66
- - Claude's deployed SoT defaults are `model: opus` and `effortLevel: high`; `advisorModel` is deliberately absent/off. `--claude-advisor=on` is the per-machine opt-in and writes `advisorModel: fable` after the settings merge. `opus` is the alias, not a pinned id: the `minimumVersion` floor of 2.1.219 ensures Claude Code can resolve it to the newest Opus its provider offers — Opus 5 on the Anthropic API or Opus 4.6 on Microsoft Foundry — instead of silently capping Anthropic API users at Opus 4.8 under the former 2.1.170 floor. Keeping the alias provides provider portability and tracks future Opus releases; the literal `claude-opus-5` is unavailable on Foundry. The floor also subsumes Fable 5's older 2.1.170 requirement.
67
+ - Claude's deployed SoT defaults are `model: opus` and `effortLevel: high`; `advisorModel` is deliberately absent/off. `--claude-advisor=on` is the per-machine opt-in and writes `advisorModel: opus` after the settings merge. `opus` is the alias, not a pinned id: the `minimumVersion` floor of 2.1.280 makes Claude Code resolve it to Opus 5.5, the default Opus from that release, instead of capping at Opus 5 under the former 2.1.219 floor. Keeping the alias tracks the next Opus release without a kit change and stays portable across providers. The floor also subsumes Fable 5.1's 2.1.257 requirement.
67
68
  - Claude permission rules are pruned, not host-scoped. The kit deploys its `PowerShell(...)` deny and ask rules on every host, because Claude Code leaves the PowerShell tool opt-in off Windows rather than unavailable, and a host that enables it must already carry the guards. `claudeRetired.ts RETIRED_PERMISSION_RULES, exact retired-rule inventory` lists the rules the kit no longer ships. `claudeSync.ts syncRemovals, retired-permission pass` force-prunes those exact strings from the kit-managed `~/.claude/settings.json` on every sync, because `settings.ts mergeSettings, permission-array union` would otherwise keep a dropped rule forever. A different user-authored rule survives. To restore an exact retired rule for one checkout, put it in that checkout's `.claude/settings.local.json`. Claude Code resolves that file against the working directory and merges it over user settings. Sync never reads or writes the checkout-local file. Claude Code has no user-scope local settings file. For a machine-wide restoration, add the rule to `SoT/.claude/settings.json`. At the same time, remove the exact string from `claudeRetired.ts RETIRED_PERMISSION_RULES, exact retired-rule inventory`. `permissions.allow` holds four read-only entries (`Read`, `Glob`, `Grep`, and `WebSearch`) plus the working-directory edit rule `Edit(./)`. Broad shell allow rules are not restored, because an allow rule resolves before Claude Code's read-only command analyzer and the auto-mode classifier. `autoMemoryEnabled` and `autoDreamEnabled` are both `false`.
68
69
 
69
70
  omp SoT notes:
70
71
  - `SoT/.omp/AGENTS.md`, `config.yml`, `models.yml`, and `mcp.json` deploy to `~/.omp/agent/`.
71
72
  - `SoT/.omp/intercom.json` deploys to `$PI_CODING_AGENT_DIR/intercom/config.json`. The default root is `~/.pi/agent`.
72
73
  - `ompSync.ts syncMergedYaml` deep-merges `config.yml` through `ompYaml.ts mergeOmpConfig` and `models.yml` through `mergeOmpModels`. Both wrap one generic mapping merge; only the config wrapper prunes stale `retry.fallbackChains` wildcards.
74
+ - `ompSync.ts` runs `ompRemovals.ts syncOmpRemovals, retired-key inventory` right after the config merge, and that pass force-prunes retired kit-owned keys from `~/.omp/agent/config.yml` on every sync, without `--reconcile`. The pass is required because `mergeOmpConfig` is additive, so removing a key from the SoT alone never removes it from a deployed file. A key retired with a recorded value is pruned only while the deployed value still matches that value, so a user edit survives; a key retired outright, such as `providers.webSearchOrder`, is pruned at any value.
73
75
  - `cycleOrder` ends with `astra` as its fifth stop. `modelRoles.astra` is `openai-codex/gpt-6-astra:xhigh`, and `modelTags.astra` is visible. Astra and Fable fall back to each other through concrete selectors. `modelRoles.fable` remains `anthropic/claude-fable-5-1:medium`, with visible `modelTags.fable`. The hidden `switch_fable` role uses the same Fable selector and keeps an empty fallback chain.
74
- - `modelRoles.task` is `openai-codex/gpt-5.6-sol:high`. The four reviewer entries in `task.agentModelOverrides` inherit it through `@task`. Only bundled `reviewer` and `security-reviewer` are discoverable OMP agents; `code-reviewer` and `plan-reviewer` stay dormant.
75
- - `SoT/.omp/models.yml` declares Astra's full `low, medium, high, xhigh, max` ladder with `defaultLevel: xhigh` as the worked provider ladder-override example. `ompYaml.ts mergeOmpModels` preserves deployed-only keys in `~/.omp/agent/models.yml`, because a user file may carry provider credentials. Whole-file replacement is wrong.
76
+ - `modelRoles.task` is `openai-codex/gpt-6-sol:high`, and `advisor` is `openai-codex/gpt-6-sol:medium`. `smol`, `commit`, and `tiny` use `openai-codex/gpt-6-luna`. The four reviewer entries in `task.agentModelOverrides` inherit `task` through `@task`. Only bundled `reviewer` and `security-reviewer` are discoverable OMP agents; `code-reviewer` and `plan-reviewer` stay dormant. omp 18.2.9 does not list `gpt-6-sol` or `gpt-6-luna` in its `openai-codex` catalog, so it fuzzy-matches both selectors to the GPT-5.6 models without a warning until the catalog lists them. The owner deployed them anyway. `cli/docs/omp-models.md` records the checks.
77
+ - The five Anthropic roles (`default`, `slow`, `plan`, `designer`, `vision`) and the five Anthropic retry chains use `anthropic/claude-opus-5-5` at the levels the role map records. `cli/docs/omp-models.md` carries the Artificial Analysis capture behind the role map, read 2026-09-22 at Intelligence Index v4.3.2 and Coding Agent Index v1.5 from the AA comparison-page metric tables. Opus 5.5 max has the highest index in that topic. AA has not measured speed or latency for Opus 5.5 max, GPT-6 Sol, or GPT-6 Luna.
78
+ - `modelRoles.web` is `web/firecrawl` and `retry.fallbackChains.web` carries the explicit 20-entry provider order. The kit declares both keys because the legacy `providers.webSearchOrder` key is retired: omp expands it in memory into these two keys and then drops it, and never writes that expansion back to disk. An explicit chain replaces omp's built-in web order wholesale, so every entry left out is a provider omp never tries. The owner removed the seven entries that named older models (Gemini 2.5 Flash, Claude Haiku 4.5, GPT-5.6, GPT-5.5, and Grok 4.5); keep every other provider.
79
+ - `SoT/.omp/models.yml` declares Astra's full `low, medium, high, xhigh, max` ladder with `defaultLevel: xhigh` as the worked provider ladder-override example. It also carries a temporary `anthropic.modelOverrides.claude-opus-5-5` block with that model's limits, ladder, and prices, because the shared catalog still serves the id as a stub with null limits and zero cost; remove the block once the catalog publishes the row. `ompYaml.ts mergeOmpModels` preserves deployed-only keys in `~/.omp/agent/models.yml`, because a user file may carry provider credentials. Whole-file replacement is wrong.
76
80
  - `SoT/.omp/AGENTS.md` carries the rule `Please remove all mannered prose.` Anthropic's Fable 5.1 prompting guide documents mannered prose as a Fable 5.1 behavior and gives that sentence as its short-version fix: https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/prompting-claude-fable-5-1
77
81
  - `cli/docs/omp-models.md` (topic `omp-models`) records the role map rationale and the Artificial Analysis snapshot behind it. Model choices change with published benchmarks, so update that topic in the same commit as a role change.
82
+ - `SoT/.omp/config.yml` sets `compaction.thresholdTokens` to `-1`, omp's schema default sentinel selecting reserve-based behavior: the trigger becomes `contextWindow` minus `max(floor(contextWindow * 0.15), 16384)`, which is 231,200 on the 272,000-token Codex window and 850,000 on the 1,000,000-token Anthropic window. The key ships as `-1` rather than being deleted because `ompYaml.ts mergeOmpConfig` is additive, so removing a key from SoT never removes it from a deployed file. `cli/docs/omp-context.md` (topic `omp-context`) carries the derivation and the measured evidence, so update that topic in the same commit as any compaction-setting change.
78
83
  - Sync registers the `docks` marketplace. It installs or upgrades `docks@docks` and `plan-lifecycle@docks` at user scope.
79
84
  - Sync installs `pi-intercom` at the verified version from `SoT/toolchain.json`.
80
85
  - The omp CLI is upstream-owned and self-updating through `omp update`. Sync never installs or upgrades the CLI.
@@ -115,7 +120,7 @@ For per-tool SoT layouts (`SoT/.claude/`, `SoT/.codex/`, `SoT/.omp/`), see the m
115
120
  - **One exemption: the kit's own package.** `install.sh` and `install.ps1` end with `bun add -g docks-kit@latest`, because a global installer that pinned itself would install a fixed old kit forever, and pinning it to `package.json` would request an unpublished version between the release-prep commit and the npm publish. The exemption covers `docks-kit` alone. Both installers still pin the Bun installer they download to the manifest's verified version, and `cli/test/unit/install.test.ts` asserts that pin in all four launcher and installer scripts.
116
121
  ## Testing
117
122
 
118
- Run `bun run check` before and after each change: oxlint, `tsc --noEmit`, unit tests, and both golden suites. Scripts: `lint`, `typecheck`, `test:unit`, `test:integration` (goldens), `test`, `format`; CI runs `check` on push and pull request with Bun 1.4.2. Prove-red modes must exit non-zero after detecting planted mismatches. Also verify user-facing changes via `./docks-kit sync --dry-run`, per-tool sanity (`/doctor`, `/plugin`, etc.), `bun run test:runtime:posix`, and `diff <(jq -S . <SoT>) <(jq -S . <deployed>)` recipes from the per-tool file.
123
+ Run `bun run check` before and after each change: oxlint, `oxfmt --check`, `tsc --noEmit`, unit tests, and both golden suites. Scripts: `lint`, `format:check`, `typecheck`, `test:unit`, `test:integration` (goldens), `test`, `format`; CI runs `check` on push and pull request with Bun 1.4.2. Prove-red modes must exit non-zero after detecting planted mismatches. The golden writer emits two-space JSON that `oxfmt` re-serializes, so run `bun run format` after `--update-goldens` or `format:check` fails. Also verify user-facing changes via `./docks-kit sync --dry-run`, per-tool sanity (`/doctor`, `/plugin`, etc.), `bun run test:runtime:posix`, and `diff <(jq -S . <SoT>) <(jq -S . <deployed>)` recipes from the per-tool file.
119
124
 
120
125
  Use direct acceptance and focused regressions while iterating, then run the full unit/golden gate once at the pre-commit or release boundary. Reuse still-matching evidence; a later relevant edit invalidates only the affected rung and final gate, not every prior check.
121
126
 
@@ -17,15 +17,16 @@ the entry and date when a model ships or retires.
17
17
 
18
18
  ## The `best` alias and `default` pseudo-value
19
19
 
20
- - `best` resolves to Fable 5 where the org has access, latest Opus otherwise.
21
- It needs Claude Code >= 2.1.170. The kit SoT pins the `opus` alias directly
22
- rather than `best` or a full id, so the deployed model is unambiguous. Its
23
- `minimumVersion` of 2.1.219 ensures Claude Code can resolve that alias to the
24
- newest Opus its provider offers: Opus 5 on the Anthropic API or Opus 4.6 on
25
- Microsoft Foundry. The former 2.1.170 floor silently capped Anthropic API
26
- users at Opus 4.8. Keeping the alias provides provider portability and tracks
27
- future Opus releases; the literal `claude-opus-5` is unavailable on Foundry.
28
- The floor also subsumes `best`/Fable 5's older 2.1.170 requirement.
20
+ - `best` resolves to Fable 5.1 where the org has access, latest Opus
21
+ otherwise. It needs Claude Code >= 2.1.257. Claude apps gateway sessions
22
+ still resolve `best` and `fable` to Fable 5. The kit SoT pins the `opus`
23
+ alias directly rather than `best` or a full id, so the deployed model is
24
+ unambiguous. Its `minimumVersion` of 2.1.280 ensures Claude Code can resolve
25
+ that alias to Opus 5.5, the default Opus from that release. The former
26
+ 2.1.219 floor capped the alias at Opus 5. The kit keeps the alias because it
27
+ tracks the next Opus release without a kit change and stays portable across
28
+ every provider that carries a different newest Opus. The floor also subsumes
29
+ the older `best`/Fable 5.1 requirement of 2.1.257.
29
30
  - `default` is an engine pseudo-value: it DELETES the deployed `model` key so
30
31
  the account default applies. It never reaches the settings file as a value.
31
32
 
@@ -35,14 +36,13 @@ the entry and date when a model ships or retires.
35
36
  docks-kit models # both catalogs
36
37
  docks-kit models claude --json # machine-readable
37
38
  docks-kit model claude # current deployed + SoT + picker (TTY)
38
- docks-kit model claude opus # per-machine override from the Fable SoT
39
+ docks-kit model claude opus # per-machine override from the Opus SoT
39
40
  docks-kit sync claude --claude-model=opus # same, as part of a sync
40
41
  ```
41
42
 
42
43
  ## Advisor pairing note (Claude)
43
44
 
44
- The SoT ships `model: fable` with advisor off (`advisorModel` unset).
45
+ The SoT ships `model: opus` with advisor off (`advisorModel` unset).
45
46
  Advisor is a per-machine opt-in: `docks-kit sync claude --claude-advisor=on`
46
- writes `advisorModel: fable`; `off` and `default` delete the key. Fable-main +
47
- Fable-advisor is an accepted pairing. The advisor needs Fable org access and
48
- Claude Code >= 2.1.170.
47
+ writes `advisorModel: opus`; `off` and `default` delete the key. The advisor
48
+ then runs the same Opus 5.5 the main session uses.
@@ -9,15 +9,15 @@ the SoT is never touched. They all share one contract:
9
9
  > profiles can instead use `~/.claude/settings.local.json`, which sync never
10
10
  > touches.
11
11
 
12
- Claude's embedded SoT is `model: fable`, `effortLevel: high`, with advisor
12
+ Claude's embedded SoT is `model: opus`, `effortLevel: high`, with advisor
13
13
  off (`advisorModel` unset). Codex's embedded normal and plan reasoning effort is
14
14
  `high`.
15
15
 
16
16
  | Modifier | Deployed change | Typical use |
17
17
  |----------|-----------------|-------------|
18
- | `--claude-model=<m>` | `.model` in ~/.claude/settings.json (`default` deletes the key) | Override one machine while the SoT retains `fable` |
18
+ | `--claude-model=<m>` | `.model` in ~/.claude/settings.json (`default` deletes the key) | Override one machine while the SoT retains `opus` |
19
19
  | `--claude-effort=<level>` | `.effortLevel` in ~/.claude/settings.json (`default` writes `high`) | Tune persisted Claude effort per machine; valid `low`, `medium`, `high`, `xhigh` |
20
- | `--claude-advisor=<state>` | `on` sets `.advisorModel = "fable"`; `off`/`default` remove it | Enable Claude advisor only on machines that need it |
20
+ | `--claude-advisor=<state>` | `on` sets `.advisorModel = "opus"`; `off`/`default` remove it | Enable Claude advisor only on machines that need it |
21
21
  | `--claude-compact-window=<n>` | `env.CLAUDE_CODE_AUTO_COMPACT_WINDOW` | Disposable containers running long autonomous work (e.g. `680k`) — not host machines |
22
22
  | `--claude-permissive` | `permissions.ask = []`, `permissions.deny = []` | Sandboxes/containers where prompts stall unattended work. Never on a host — the deny list is the safety floor |
23
23
  | `--codex-model=<m>` | top-level `model = "…"` in ~/.codex/config.toml | Same as claude-model, for Codex |
@@ -29,7 +29,7 @@ selecting that positional target warns and ignores it.
29
29
 
30
30
  A flag-less Claude sync also removes the formerly kit-owned `advisorModel`
31
31
  from machines synced before advisor became opt-in. Any explicit advisor state
32
- owns that key for the run: `on` writes `fable`; `off` and `default` delete it.
32
+ owns that key for the run: `on` writes `opus`; `off` and `default` delete it.
33
33
  Codex has no advisor modifier because its documented config has no advisor
34
34
  setting; `review_model` applies only to `/review`.
35
35
 
@@ -0,0 +1,104 @@
1
+ # omp context and compaction
2
+
3
+ This topic records why `SoT/.omp/config.yml` does not pin a compaction
4
+ threshold, and what omp's reserve-based default computes on each model lane.
5
+
6
+ ## How omp resolves the trigger
7
+
8
+ `resolveThresholdTokens` in omp source
9
+ `packages/agent/src/compaction/compaction.ts` selects the trigger from three
10
+ branches, in priority order.
11
+
12
+ 1. A positive `compaction.thresholdTokens` wins. omp clamps it to the range 1
13
+ through `contextWindow - 1`.
14
+ 2. Otherwise a positive `compaction.thresholdPercent` applies. omp clamps the
15
+ percent to the range 1 through 99 and computes
16
+ `floor(contextWindow * percent / 100)`.
17
+ 3. Otherwise, when both keys hold `-1`, reserve-based behavior applies.
18
+
19
+ The reserve-based branch computes the trigger from the window itself:
20
+
21
+ ```text
22
+ threshold = contextWindow - max(floor(contextWindow * 0.15), 16384)
23
+ ```
24
+
25
+ omp names the 16384 constant `DEFAULT_RESERVE_TOKENS`. The 15% proportional
26
+ reserve dominates on any window above roughly 109,227 tokens, so every lane
27
+ the kit uses resolves through the proportional term and never through the flat
28
+ constant.
29
+
30
+ ## Per-lane result
31
+
32
+ | Lane | Window | Reserve | Threshold | Percent of window |
33
+ |---|---:|---:|---:|---:|
34
+ | `openai-codex/*` | 272,000 | 40,800 | 231,200 | 85.0% |
35
+ | `anthropic/*` | 1,000,000 | 150,000 | 850,000 | 85.0% |
36
+
37
+ Both lanes compact at the same fraction of their own window. The absolute
38
+ trigger differs only because the windows differ.
39
+
40
+ ## Why the kit no longer pins 231200
41
+
42
+ The kit previously shipped `compaction.thresholdTokens: 231200`. That value is
43
+ exactly the reserve-based default for a 272,000-token window. It was therefore
44
+ identical to the default on the Codex lane and changed nothing there. Its only
45
+ real effect was forcing the Anthropic lane to compact at 23.1% of its window
46
+ instead of 85%.
47
+
48
+ The evidence below records 83 compactions measured between 2026-09-12 and
49
+ 2026-09-21, after omp 18.1.18 introduced the Anthropic server-side compaction
50
+ lane.
51
+
52
+ | Lane | Compactions | Maximum tokens before | Over window | Warnings |
53
+ |---|---:|---:|---:|---:|
54
+ | `anthropic` | 75 | 248,583 (24.9% of window) | 0 | 0 |
55
+ | `openai-codex` | 8 | 263,591 (96.9% of window) | 0 | 0 |
56
+
57
+ The median context freed was 64.8%. The pin was safe rather than dangerous.
58
+ No session ran past its window, and omp raised no warning on either lane.
59
+ Under the reserve-based default none of the 75 Anthropic compactions would
60
+ have fired, because no session reached 850,000.
61
+
62
+ ## Why the key ships as -1 rather than being deleted
63
+
64
+ `ompYaml.ts` `mergeOmpConfig` is additive. Its `mergeMappings, deployed-key
65
+ retention loop` returns every deployed key that the SoT omits to the merged
66
+ output, and the only drop predicate is `dropFallbackWildcard`, which is scoped
67
+ to `retry.fallbackChains`.
68
+
69
+ Deleting the key from the SoT would therefore leave the stale `231200` in
70
+ every already-deployed `~/.omp/agent/config.yml` permanently. A present key
71
+ holding the schema default sentinel `-1` overwrites that stale value on the
72
+ next sync.
73
+
74
+ Verify the deployed value after a sync:
75
+
76
+ ```bash
77
+ omp config get compaction.thresholdTokens
78
+ ```
79
+
80
+ The command must print `-1`.
81
+
82
+ ## The clamp hazard a fixed pin carries
83
+
84
+ The fixed-token branch clamps the pinned value to `contextWindow - 1`. On any
85
+ model whose window is below the pinned value, the reserve collapses to one
86
+ token, so omp compacts only once the context is already full. The
87
+ reserve-based default always leaves at least 15% of the window free.
88
+
89
+ No current role model has a window below 272,000, so the hazard was latent
90
+ rather than live. Not pinning removes it entirely, including for any future
91
+ model with a smaller window.
92
+
93
+ ## Related settings left at their omp defaults
94
+
95
+ | Setting | Value | Reason |
96
+ |---|---|---|
97
+ | `extendedContext` | `false` | omp 17.4.0 added the setting defaulting on, and a later release flipped the default to off. It caps a model carrying a premium long-context price tier at that model's standard-pricing window, so `openai-codex/gpt-5.6-sol` reports 272,000 rather than about 1,050,000. Enabling it makes a Codex window overrun structurally impossible. The cost is a cliff rather than a marginal rate: any request above the 272,000 threshold bills the whole request at input $10 instead of $4, cache read $1.00 instead of $0.40, and cache write $12.50 instead of $5.00. |
98
+ | `compaction.idleEnabled` | `true` | omp default. Idle compaction fires below the reserve-based trigger on both lanes. A compaction whose reason is `idle` skips the progress guard. |
99
+ | `compaction.idleThresholdTokens` | `200000` | omp default. |
100
+ | `compaction.idleTimeoutSeconds` | `300` | omp default. |
101
+ | `compaction.methodOrder` | `["remote","snapcompact","handoff","shake","soft"]` | omp default, remote first. Since omp 18.1.18 the Anthropic server-side lane handles Anthropic models, so snapcompact is a fallback rather than the primary path. |
102
+
103
+ Every row records a decision to leave the omp default in place. None of these
104
+ keys carries a kit value that differs from the default omp already applies.