Two review findings from the independent Iron-Rule-10 reviewer, both confirmed
before applying:
1. docs/lan-mode.md: the sample `ocp update` output lost `ocp/claude-opus-4-8`
entirely — the edit substituted the id instead of inserting the new one, so
the block listed 6 bullets while line 219 of the same document claims
"7 models available". Self-contradictory. Restored; the block is 7 again.
2. test-features.mjs: "every contextWindow is 200000" was too rigid and
contradicted ADR 0009, which states the budget "scales automatically — no
code change". Asserting every entry turned that documented no-code-change
path into a must-edit-tests path, and would have failed on a future entry
with a legitimately SMALLER window. Now asserts the MAX instead: raising the
ceiling (the actual hazard, since the budget is global) still fails, while a
smaller-window model stays legal.
Verified the reformulation is strictly better, not just different:
- raise a window to 1000000 -> 2 failures (ceiling + derivePromptCharBudget SPOT)
- add a legitimate 128k model -> 452 passed, 0 failed (old test would have failed here)
Tests: 452 passed, 0 failed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017gbqUZ8HfBZpjjbzQ85oH8
Adds `claude-opus-5` to models.json (the SPOT) and moves the `opus` alias
from `claude-opus-4-8` to it. `/v1/models` goes 6 -> 7; OpenClaw picks the
new entry up on the next `ocp update` via scripts/sync-openclaw.mjs.
server.mjs is NOT modified by this PR — models.json is the single source of
truth (ADR 0003) and every consumer (server.mjs MODEL_MAP, setup.mjs,
sync-openclaw.mjs, ocp-connect) derives from it. ocp-connect needs no change
either: its metadata table matches on the `claude-opus` FAMILY prefix, which
`claude-opus-5` hits (the guard added in PR #152 review).
Alignment evidence. The claim "the CLI itself defaults opus -> claude-opus-5"
is verified from the compiled CLI binary 2.1.220 via `strings`, the same
protocol used for #152/#168:
latest_per_family:{fable:"claude-fable-5",opus:"claude-opus-5",
sonnet:"claude-sonnet-5",haiku:"claude-haiku-4-5"}
The same registry entry gives context:{window:1e6,native_1m:true},
max_output_tokens:{default:64000,upper:128000} and pricing:"tier_5_25" --
i.e. identical $5/$25 per MTok to Opus 4.8, so the alias repoint carries no
cost change. Availability confirmed with a live subscription-pool completion
(`claude -p --model claude-opus-5` -> "OK"). This mirrors #168 (sonnet ->
sonnet-5), which established the precedent that following the CLI's own
latest_per_family is the correct default behavior.
contextWindow is deliberately 200000, not the native 1M:
1. MAX_PROMPT_CHARS is a SINGLE GLOBAL budget, not per-model.
derivePromptCharBudget (lib/prompt.mjs) returns
`max(floor, max(...contextWindows) * 3)` across ALL entries, so a 1M entry
would lift the truncation ceiling to 3,000,000 chars for
claude-haiku-4-5-20251001 as well -- genuinely a 200k-native model --
turning clean OCP-side truncation into an upstream API rejection.
2. OpenClaw scales its history budget linearly off this value:
contextWindow * maxHistoryShare * SAFETY_MARGIN (= x0.6), plus an
oversized-message threshold at x0.5 (compaction-planning, OpenClaw
2026.7.1). Its own bundled registry hardcodes 200000 for Claude models,
and the upstream request to raise it to 1M (openclaw#22979) was closed
"not planned" -- 1M needs a beta header its compaction path omits.
Raising the window for real requires per-model budgets and is ADR-level;
a new regression test pins the invariant so that change has to be deliberate.
Tests: 452 passed, 0 failed. Three mutations verified to bite:
- revert aliases.opus -> 4-8 => 1 failure (opus-alias SPOT)
- delete the claude-opus-5 entry => 2 failures (presence + dangling alias)
- set its contextWindow to 1000000 => 2 failures (invariant + budget SPOT)
E2E on an isolated port (:3999, prod on :3456 untouched and verified so):
/v1/models returns 7 ids with claude-opus-5 first; a request with
model:"opus" logs event=claude_spawned model=claude-opus-5 tier=opus and
returns a real completion. Derived MAX_PROMPT_CHARS stays 600000.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017gbqUZ8HfBZpjjbzQ85oH8
Maintainer-approved P2 restructure. Principle: what a new user needs in the first
10 minutes stays in README; the operations manual moves to docs/. Content MOVED,
not rewritten — an independent verifier swept all 20 original sections, 60+
distinctive facts, and all table rows against the new corpus: zero content loss.
New files (verbatim moves + two mandated dedup merges):
- docs/lan-mode.md (396) — LAN setup, key management, quotas, anonymous access,
deployment/security model + honest limits, client connect
- docs/tui-mode.md (196) — full TUI section + the four giant env-cell essays as
prose subsections; opens with the single-user SECURITY
warning + the PAUSED billing-split status banner
- docs/troubleshooting.md (136) — full troubleshooting; canonical 401/credential-
isolation explanation (union of the 4 prior copies)
- docs/upgrading.md (79) — upgrade paths, snapshots, rollback, auto-sync
README keeps: pitch (byte-identical), new TOC, 62-line Quickstart, How It Works
verbatim (incl. #171 billing-status note + workload fit), the three release_kit-
pinned tables (Available Models / API Endpoints / all 37 Environment Variables
rows — 4 giant TUI cells now one-line pointers), All Commands, slim Troubleshooting
(bootstrap quirks retained per release_kit bootstrap_quirk_policy), summary stubs
linking each moved doc, Repository Layout (+4 doc rows), Governance, Support.
Dedup (canonical copies): sdk-cli vs subscription-pool table → docs/tui-mode.md;
credential-isolated-home / permanent-401 → docs/troubleshooting.md#tui-401.
Link retargets: docs/runbooks/615-canary.md, docs/runbooks/tui-flip-rollback.md,
setup.mjs (one banner string; node --check clean). 126 links across the touched
files verified resolving; repo-wide grep shows no reference to a removed anchor.
npm test: 332 passed / 0 failed.
Co-authored-by: dtzp555 <dtzp555@gmail.com>
Co-authored-by: Claude <claude-opus-4-8> <noreply@anthropic.com>