Files
dtzp555-maxGitHubtaodengClaude <claude-opus-4-8> <noreply@anthropic.com>
b038d3ceac docs: restructure README (1205 → 497 lines) — ops-manual content moves to docs/ (#172)
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>
2026-07-17 14:28:36 +10:00

7.7 KiB

2026-06-15 Canary Runbook

Purpose: Confirm that a TUI-mode turn is billed to the Pro/Max subscription pool (not the Agent SDK credit pool) after Anthropic's 2026-06-15 billing split activates.

The billing classifier reading cli is necessary but NOT sufficient proof. (Note the naming: the value is stored in the JSONL transcript under the field name entrypoint, and sent to Anthropic on the wire as the cc_entrypoint header — they carry the same value after claude's startup classification. The commands below grep the transcript, so they match entrypoint.) A cli label tells you OCP sent the right classification; it does not tell you Anthropic billed the right pool. The only authoritative test is to observe whether the Agent SDK credit balance moves or not before and after the canary turn.


Prerequisites

  • CLAUDE_TUI_MODE=true already set and OCP restarted (see TUI-mode setup)
  • tmux installed on the host
  • No other OCP traffic during the canary (quiesce — see below)
  • Access to your Anthropic account billing page (manual step — see below)

Step 1 — Quiesce the host

Stop any IDE or client that is actively sending requests through this OCP instance.

Confirm the proxy is idle:

curl -s http://127.0.0.1:3456/health | python3 -m json.tool | grep activeRequests
# Expected: "activeRequests": 0

Wait until activeRequests is 0 before proceeding. If you cannot quiesce (e.g. family members are actively using it), run the canary on a separate OCP instance or during a quiet window.


Step 2 — Read the Agent SDK credit balance BEFORE the canary

Manual step — no programmatic API available.

OCP's /usage endpoint reads anthropic-ratelimit-unified-* response headers from the Pro/Max plan quota (5-hour and 7-day subscription windows). These headers report subscription usage, not the Agent SDK credit pool balance. There is no known programmatic API to query the Agent SDK credit pool balance from outside the Anthropic web app.

To read the balance:

  1. Open https://claude.ai/settings/billing (or your Anthropic Console billing page) in a browser.
  2. Find the Agent SDK Credits section (sometimes labeled "API Credits" or "Agent SDK usage").
  3. Note the current balance (e.g. $18.43 remaining of $20.00).

Write the value down — you will compare it after the canary turn.


Step 3 — Send the canary turn

With TUI-mode on and the host quiesced, send exactly one small request:

curl -s -X POST http://127.0.0.1:3456/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-haiku-4-5-20251001",
    "messages": [{"role": "user", "content": "Reply with the single word: pong"}],
    "max_tokens": 10
  }' | python3 -m json.tool

Use Haiku (the cheapest model) to minimize any hypothetical impact if the canary turns red.

Wait for the response to arrive completely (TUI-mode buffers the full response before returning — you will see a delay of several seconds, then the full reply).


Step 4 — Confirm the transcript shows entrypoint:"cli"

After the canary turn completes, inspect the most recent JSONL transcript for the billing-classifier label:

# The canary was run quiesced (Step 1), so the most recent JSONL across ALL project
# dirs IS the canary turn. We glob every projects subdir instead of recomputing
# claude's cwd-encoding rule (it maps every "/" AND "." to "-", e.g. ~/.ocp-tui/work
# => projects/-home-<user>--ocp-tui-work/; see lib/tui/transcript.mjs encodeCwd) —
# a glob is robust even if that encoding changes in a future claude build.
LATEST=$(ls -t "$HOME"/.claude/projects/*/*.jsonl 2>/dev/null | head -1)
echo "Transcript: $LATEST"
grep -o '"entrypoint":"[^"]*"' "$LATEST" | tail -1
# Expected: "entrypoint":"cli"

If the output shows "entrypoint":"cli", the billing-classifier label is correct. If it shows "entrypoint":"sdk-cli", the spawn did not get a real PTY — stop immediately and do not re-enable TUI-mode without investigation. Check tmux new-session manually and review ADR 0007 § spawn/PTY gate. (If the grep returns nothing, the transcript may not yet be flushed — re-run after a second, or confirm the turn completed.)

Reminder: an entrypoint:cli label (the cc_entrypoint=cli wire header) is necessary but not sufficient. It tells you OCP sent the right label to Anthropic. You must still check the credit balance in Step 5.


Step 5 — Re-read the Agent SDK credit balance AFTER the canary

Return to https://claude.ai/settings/billing and reload the page. Note the current balance again.


Step 6 — Green/Red decision

Green (balance unchanged)

The Agent SDK credit balance did not decrease. The turn billed against the Pro/Max subscription pool as expected. TUI-mode is working correctly.

Actions:

  • Keep CLAUDE_TUI_MODE=true on this host.
  • Monitor the balance periodically for the first week to catch any delayed attribution.
  • Resume normal traffic.

Red (Agent SDK credit balance decreased)

The Agent SDK credit balance decreased. The subscription pool is not being used for TUI-mode turns on this host, despite cc_entrypoint=cli being set. This may indicate a backend routing change on Anthropic's side, a TTY detection failure, or a policy change.

Actions — immediate:

  1. Unset CLAUDE_TUI_MODE (or set to any value other than "true") in the service unit:
    • systemd: edit /etc/ocp/ocp.env (or the unit's Environment= line), then sudo systemctl daemon-reload && sudo systemctl restart ocp.service
    • launchd: edit the plist EnvironmentVariables section, then launchctl bootout gui/$(id -u)/dev.ocp.proxy && launchctl bootstrap gui/$(id -u) <plist-path>
  2. Restart OCP and confirm the /health response no longer shows TUI-mode active.
  3. If you share this OCP with family or other Max users: freeze their access temporarily until you understand the billing impact.
  4. Consider pivoting to OLP multi-provider (see OLP) which can spread load across other providers to avoid the Agent SDK credit drain.

Per ALIGNMENT.md Rule 2 / ADR 0007 § Kill-switch: "Per the constitution, the response is to drop the Anthropic provider rather than escalate spoofing."


Ongoing monitoring — self-classification mini-canary

To detect future drift (e.g. a claude CLI upgrade that changes TTY-detection behavior), you can run a periodic one-liner that sends a tiny TUI turn with OCP_TUI_ENTRYPOINT=auto (so claude self-classifies rather than having OCP pin the value) and alerts if the transcript self-classification is not cli:

# Run with OCP temporarily configured OCP_TUI_ENTRYPOINT=auto
# Then check the most recent transcript:
# Glob the most recent transcript across all project dirs (robust to claude's
# cwd-encoding rule; run this right after the auto-mode mini-canary turn).
LATEST=$(ls -t "$HOME"/.claude/projects/*/*.jsonl 2>/dev/null | head -1)
RESULT=$(grep -o '"entrypoint":"[^"]*"' "$LATEST" | tail -1)
echo "Self-classified entrypoint: $RESULT"
if echo "$RESULT" | grep -q '"entrypoint":"cli"'; then
  echo "OK — subscription pool"
else
  echo "ALERT — not cli; check TTY and billing"
fi

Run this after any major claude CLI upgrade. The auto mode lets the CLI's own t$A startup function determine the value from the actual TTY state (see ADR 0007 § Billing-classifier labeling).