Skip to content

feat(t27os): key manager, KEYS tab, per-pane profile, router decisions (Refs #10782) - #10977

Closed
gHashTag wants to merge 7 commits into
feat/t27os-petal-menufrom
claude/t27os-keys-v3
Closed

gHashTag wants to merge 7 commits into
feat/t27os-petal-menufrom
claude/t27os-keys-v3

Conversation

@gHashTag

Copy link
Copy Markdown
Collaborator

Refs #10782

Supersedes #10959: the petal-menu base was rebased, so that branch conflicted add/add on every shared t27os file. This branch is the same work re-applied onto the new base as ordinary modifications.

What

  • keys.t27: key manager decisions (9 providers, env var per agent, masking, status, rotation, spawn env, KEYS-panel rules) plus the M12 Stage 1 per-pane PROFILE (z.ai first, then anthropic-api), pre-flight check and why line. 28 tests pass on the lab.
  • keys_host.t27: macOS Keychain (ai.t27.os) and the probe (GET, or one-token POST for z.ai). Keys are never in a file or the repo.
  • KEYS tab in glass_window.t27, editors.t27 + editors_host.t27 (open in editor).
  • PTY server: strips CLAUDE_CODE_* / CLAUDECODE, OP_SETKEY keeps keys in server memory, injects profile or key per agent.
  • router.t27: M12 Stage 2 decisions (7 tests). Implementation is blocked on t27b streaming HTTPS upstream and AF_INET sockaddr; design header names the gaps.
  • app.t27.ai map in the keys.t27 header; missing proxy endpoint filed as gHashTag/999-multibots-telegraf#4024.
  • Ledgers: width baseline for glass_window/pty_server; t27b expectations list the t27os specs the reference passes. pty_proto oversize test now zeroes its buffer.

Not verified live

Profile spawn with real keys, z.ai POST probe, Keychain and KEYS tab click-through.

🤖 Generated with Claude Code

… router decisions (Refs #10782)

Re-applies the keys work from PR 10972 onto the twice-rebased petal-menu base.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…lass copies (Refs #10782)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ops eval_hslm (Refs #10782)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This was referenced Oct 19, 2026
gHashTag and others added 2 commits October 20, 2026 11:11
…a-cloud profiles, key chain, in-pane failover decision (#11226)

* t27os keys: tier map as pure data -- a default model and a model per tier for each claude profile (FR-001)

The zai and anthropic-api profiles read their ANTHROPIC_MODEL, _SMALL_FAST_MODEL and
_DEFAULT_HAIKU/SONNET/OPUS_MODEL values from one table (a tier left empty falls back to the default
model, the Free Claude Code way) instead of a per-profile if-chain; zai now also sets the sonnet and
opus tiers. Prior art: https://github.com/Alishahryar1/free-claude-code

Updates #11224

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* t27os keys: openrouter and ollama-cloud claude profiles from the providers' own Anthropic-protocol pages (FR-002)

Two more profiles behind zai and anthropic-api, each only once its provider's key is stored:
OpenRouter (https://openrouter.ai/api, three Anthropic tier names, empty ANTHROPIC_API_KEY) and
Ollama cloud (https://ollama.com, one cloud model for every tier, empty ANTHROPIC_API_KEY). The
page of each is named in the spec. DeepSeek, Moonshot and MiniMax document the protocol too but
need provider rows of their own, which the window and the server size by nine; left to a
follow-up.

Updates #11224

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* t27os keys: profile chain with numbered keys -- next_profile, key labels per number, rotation that skips the failed key (FR-003)

next_profile(after, stored, bad) walks the profile list forward only; pick_profile is its start and
behaves as before for the old two profiles. keychain_label_n names key 2 and 3 of a provider (key 1
keeps the old Keychain item), rotate_pick_except lets rotation skip the key that just failed.

Updates #11224

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* t27os keys: pane failover decision -- screen line to failure class, respawn or give up, never a loop (FR-004)

classify_line sorts a screen line (429, Insufficient balance, disabled Claude subscription, 401, 403)
into a failure class by plain byte matching; fo_action says keep, respawn on the next profile, swap
to the next key of the same provider, or give up; fo_bad adds the failed provider to this pane's bad
mask; fo_why names the profile and the move with no key value. The chain is forward only and
MAX_FAILOVERS caps the count, so a pane that fails on every profile ends in give up.

Updates #11224

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* docs(t27os): key orchestration compared with Free Claude Code -- what T27 OS has, which spec function does it, what stays blocked (FR-005)

One table of the Free Claude Code ideas against keys.t27, the pane failover step by step, the providers
whose own pages were read (base URL, key variable, tier models, page), and the host work and the
local router (#10902) that remain. No key value, no personal name, no home path.

Updates #11224

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude <claude@anthropic.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
…ors, terminal editor opens inside the window (#11227)

* feat(t27os): the window is matte black glass, full screen stays opaque #000000 (FR-001)

Owner 2026-10-20: the window is matte black glass as in trios; where full screen cannot be transparent,
keep #000000. backdrop_alpha(full) is 0.0 in a window (BACK_GLASS) so the NSVisualEffectView blur and the
0.30 layer tint show through, and 1.0 in full screen. draw_backdrop wipes the bitmap with BLEND_CLEAR when
the fill is not opaque (so no old pixels stay) and `draw` no longer clears it twice. TINT_FULL is 1.0: the
layer background is opaque black in full screen and nothing of the wallpaper shows. tint_alpha and
tint_swap are the pure decisions behind the layer colour swap; the pins on TINT_FULL and BACK_GLASS and
two new tests cover them. The header comment records that 2026-10-20 supersedes 2026-10-19 for a window.

Updates #11223

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* feat(t27os): 27 external editors, Xcode through xed, and why an open failed (FR-003)

The table named 9 editors; the bench Mac has Cursor, Xcode, Antigravity, Antigravity IDE and ZCode, and
only Cursor and Xcode were known. It now names 27 (MAX_EDITORS 32 bounds the u32 mask): Antigravity,
Antigravity IDE, ZCode, PyCharm, GoLand, CLion, RustRover, Rider, PhpStorm, Android Studio, VS Code
Insiders, VSCodium, Kiro, Trae, Positron, BBEdit, TextMate, Fleet. Two ship no launcher (empty field).
The strip is 3 chips of 88 pt (was 4 of 66, which overlapped "Antigravity IDE").

editors_host opens a bundle with the path access(2) found (open -a <path> <dir>), not a name rebuilt
from the table into a 40-byte buffer, so a name with a space is one argv word and Antigravity cannot be
taken for Antigravity IDE. Xcode: launch_pick prefers xed <dir> and falls back to open -a; the
/usr/bin/xed shim every Mac has no longer makes Xcode look installed. open_in_editor returns an
OPEN_* code (bad folder / not installed / could not start / unknown editor) and the OPEN IN strip prints
the word after the last click that failed. exists() refuses a path that would be cut to its buffer.
JetBrains Toolbox folders (edition suffix) are not looked up; noted in the header.

Updates #11223

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* feat(t27os): T27 OS opens inside -- a terminal editor in a PTY pane, the Queen asks for it (FR-002, FR-004)

Owner 2026-10-20: "T27OS opens inside!!". A terminal editor is a program a pane of the PTY server can run,
so its screen is the window's own.

editors.t27: TERM_NAMES (vim, nvim, hx, micro, nano in order of preference), term_pick over a found-mask,
term_path_fits (dir_fits, at most a pane cwd, no single quote), editor_command (`<editor> '<path>'`) and
editor_spawn_payload. The wire format is unchanged: the SPAWN of the shell cell (9) whose model field names
the editor, the file or folder as the cwd -- pty_proto tests are untouched and green.
pty_logic.t27: wants_editor, editor_spawn_ok, launch_command (an editor pane runs the editor, every other pane
runs pane_command as before; a restored pane reopens the same path from its record). pty_server.t27: launch
uses launch_command; OP_SPAWN refuses an editor request whose path would break the quoting.
T27OS_CTL=spawn T27OS_AGENT=9 T27OS_MODEL=vim T27OS_CWD=<path> opens one from a script.
editors_host.t27: term_mask (access(2) over the launcher dirs). pty_client.t27: client_spawn_editor.
queen.t27: open_target(is_god, term_found, ext_found) -- inside whenever a terminal editor is there, for the
user's Confirm and GOD MODE alike; without one GOD MODE does nothing and a confirmed suggestion falls back
to a GUI editor. Header comments updated for the clear window glass.

Not wired: the window shows one pane, the selected Claude Code chat's, so the call site that spawns the
editor pane next to the chat and shows it is left (see the report on #11223).

Updates #11223

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(t27os): the backdrop wipe and fill reach one point past the scene so a fractional edge keeps no old pixels (FR-001)

A fractional scene edge is anti-aliased: a partly covered pixel would keep part of the last frame under the
clear window glass. BACK_BLEED = 1.0 widens the BLEND_CLEAR wipe and the opaque full-screen fill by a point on
every side; what lies outside the scene is never shown.

Updates #11223

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(t27os): same_bytes accumulates the difference, so it is not a third copy of the early-exit compare (FR-003)

tools/dupe_scan.py --like found editors.t27 same_bytes already written in igla/coder/tokenizer.t27 and
tri/crypto/hex.t27. Neither is importable from t27os. The body is now the accumulate-the-difference form:
the length check, then one loop that ORs the XOR of every byte pair into a u32, equal when it stays 0. Name,
signature and every test are unchanged.

Updates #11223

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude <claude@anthropic.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
@gHashTag

Copy link
Copy Markdown
Collaborator Author

Superseded by #11228 (same content on the current base tip; the rebased base made this branch unmergeable).

@gHashTag gHashTag closed this Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-auto-merge Opt out of the issue gate's default squash auto-merge (issue-gate.yml)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant