Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .forbidden-paths.regex
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@
(^|/)\.codex/
(^|/)\.claude/
(^|/)\.cursor/
(^|/)\.astro/
(^|/)\.cache/
(^|/)\.vite/
(^|/)\.turbo/
(^|/)\.nyc_output/
(^|/)(node_modules|target|dist|coverage|tmp)/
(^|/)npm/native/

# Generated reports stay local. The compact public byte certificate is the
# single deliberate tracked exception; raw workdirs and host logs are blocked.
(^|/)reports/(?!release-ready-v[0-9]+\.[0-9]+\.[0-9]+/public-byte-certification\.json$)

# Environment and credential files
(^|/)\.env$
Expand Down Expand Up @@ -45,3 +56,13 @@
(^|/)\.idea/
(^|/)\.vscode/settings\.json$
(^|/)\.vscode/launch\.json$

# Runtime transcripts, databases, and diagnostics
\.log$
\.jsonl$
\.(stdout|stderr|trace|pid)$
\.(sqlite|sqlite3|db)($|-)
\.(profraw|profdata)$
\.dSYM/
(\.tgz|\.crate)$
(^|/)core($|\.)
1 change: 1 addition & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#!/usr/bin/env sh
set -eu
node scripts/hooks/block-forbidden-staged-files.mjs
node scripts/hooks/block-sensitive-diff-content.mjs
19 changes: 19 additions & 0 deletions .github/workflows/secret-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,25 @@ jobs:
node-version: 22
- run: node scripts/hooks/block-forbidden-staged-files.mjs --tracked

sensitive-added-content:
name: Sensitive added content
runs-on: ubuntu-latest
if: github.event_name == 'pull_request' || github.event_name == 'push'
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
with:
node-version: 22
- name: Check pull request additions
if: github.event_name == 'pull_request'
run: node scripts/hooks/block-sensitive-diff-content.mjs --base "${{ github.event.pull_request.base.sha }}"
- name: Check pushed additions
if: github.event_name == 'push' && github.event.before != '0000000000000000000000000000000000000000'
run: node scripts/hooks/block-sensitive-diff-content.mjs --base "${{ github.event.before }}"

trufflehog:
name: TruffleHog verified secrets
runs-on: ubuntu-latest
Expand Down
21 changes: 21 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,34 @@ id_dsa
# Node and deployment tooling
/node_modules/
/.astro/
/.cache/
/.vite/
/.turbo/
/.nyc_output/
/.npm-package/
/npm/native/
/.pnpm-store/
/.alchemy/
/.wrangler/
pnpm-debug.log*
*.log
*.jsonl
*.out
*.stdout
*.stderr
*.trace
*.pid
*.pid.lock
*.db
*.db-*
*.sqlite3
*.sqlite3-*
*.profraw
*.profdata
*.dSYM/
core
core.*
/*.tgz

# Infrastructure state
*.tfstate
Expand Down
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ exclude = [
"xtask/**",
"scripts/**",
"dist/**",
"docs/prepublish-certification-*.md",
"reports/**",
"retained-evidence/**",
"tmp/**",
Expand Down
51 changes: 21 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,30 +36,22 @@ verify it against `SHA256SUMS`, and place `model-routing` on your `PATH`.

## Setup from the website

The generator at [switchloom.ai](https://switchloom.ai) produces only the versioned
`SetupSpecV1` transport. It does not compile or write host files in the browser. Its primary
action copies a shell-safe command like:
The generator at [switchloom.ai](https://switchloom.ai) produces only the
versioned `SetupSpecV1` transport. It does not compile or write host files in
the browser. After choosing a provider and team, open the provider onboarding
flow, run the copied apply command from the target repository, then run doctor:

```sh
npx switchloom@0.3.1 preview --recipe 'sw1_...'
npx switchloom@0.3.1 apply --recipe 'sw1_...'
npx switchloom@0.3.1 apply --recipe 'sw1_...' --repository .
npx switchloom doctor codex
```

The secondary action downloads the same setup as a readable `.switchloom/config.toml`:

```sh
switchloom preview --config .switchloom/config.toml
switchloom apply --config .switchloom/config.toml
switchloom status
switchloom update
switchloom rollback
switchloom uninstall
```

Setup-backed apply previews the exact repository-local change set and asks for confirmation.
Use `--yes` only in an explicitly non-interactive workflow. Standalone mode never emits
`.planr`; optional Planr mode emits provider-neutral Planr declarations and thin native roles,
while Switchloom remains independent of Planr at build and runtime.
The onboarding steps include the provider version check and project-local
setup guidance. CLI apply previews the exact repository-local change set and
asks for confirmation before writing it. Use `--yes` only in an explicitly
non-interactive workflow. Standalone mode never emits `.planr`; optional Planr
mode emits provider-neutral Planr declarations and thin native roles, while
Switchloom remains independent of Planr at build and runtime.

For direct CLI use, compile a bundle and run the same lifecycle against a
repository:
Expand All @@ -79,10 +71,9 @@ apply when setup depends on a locally installed host CLI.

## Current Status

The v0.3.1 public CLI compiles independently, preserves the frozen
Planr v1.5.0 routing inventory in [docs/migration-baseline.md](docs/migration-baseline.md),
and hard-cuts maintainer-only evaluation, catalog, registry, and live-verification
operations from the public command surface.
The v0.3.1 public CLI compiles independently and hard-cuts maintainer-only
evaluation, catalog, registry, and live-verification operations from the
public command surface.

Current Planr handoff rules, runtime classes, and maintainer verification gates are in
[docs/model-routing-policy.md](docs/model-routing-policy.md). Planr consumes
Expand All @@ -101,9 +92,9 @@ cargo run -- policy list

## Website Generator

The static Astro website is an above-the-fold team generator built with React and shadcn. Users first choose standalone or optional Planr integration, then choose Codex, Cursor, Claude Code, OpenCode, or Pi, select up to four explicit roles, start from a Light, Balanced, or High team preset, and optionally override each role's model and reasoning effort. The primary result is a CLI recipe; the secondary result is a readable setup config. Only the Rust CLI compiles and applies project-native files. Codex is shown as an internal V2 thread-tree path; Cursor, Claude Code, and OpenCode are native subagent paths; Pi is an external runner path; separate app tasks are not treated as Codex V2 child threads. The host remains authoritative for model availability, execution, and billing.
The static Astro website is an above-the-fold team generator built with React and shadcn. Users first choose standalone or optional Planr integration, then choose Codex, Cursor, Claude Code, OpenCode, or Pi, select up to four explicit roles, start from a Light, Balanced, or High team preset, and optionally override each role's model and reasoning effort. The result is a provider-specific onboarding flow with a CLI apply recipe and doctor command. Only the Rust CLI previews, compiles, and applies project-native files. Codex is shown as an internal V2 thread-tree path; Cursor, Claude Code, and OpenCode are native subagent paths; Pi is an external runner path; separate app tasks are not treated as Codex V2 child threads. The host remains authoritative for model availability, execution, and billing.

Claude Code model and effort options are derived at build time from the canonical catalog produced by the Rust compiler. Codex mirrors its current desktop picker: `low`, `medium`, `high`, and `xhigh`, while Terra and Sol additionally expose `ultra` as a manual-only mode. Pure `max` is intentionally omitted because the desktop picker does not expose it separately; Ultra sends Max reasoning plus automatic multi-agent delegation. Light, Balanced, and High never select Ultra, and Codex defaults keep mechanical work on certified Terra rather than Luna. Luna remains selectable only as an explicit experimental/unverified choice until authentic Codex 0.145.0 V2 evidence is independently reviewed. Cursor uses a deliberately small, researched frontier allowlist because its full picker changes frequently; the website presents those models in a searchable selector. Generated custom setups are local and unverified until the user reviews them.
Claude Code model and effort options are derived at build time from the canonical catalog produced by the Rust compiler. Codex exposes `low`, `medium`, `high`, `xhigh`, and `max` for Luna, Terra, and Sol; Terra and Sol additionally expose `ultra`. Max is the largest single-agent reasoning budget and may need to be enabled in Codex app settings, while Ultra adds automatic multi-agent delegation. Light, Balanced, and High never select Max or Ultra, and Codex defaults keep mechanical work on certified Terra rather than Luna. Luna remains selectable only as an explicit experimental/unverified choice and stays out of V2 presets until authentic V2 support is independently reviewed. Cursor uses a deliberately small, researched frontier allowlist because its full picker changes frequently; the website presents those models in a searchable selector. Generated custom setups are local and unverified until the user reviews them.

```sh
cargo run -p xtask -- release prepare --allow-dirty
Expand All @@ -112,10 +103,10 @@ pnpm site:check
pnpm site:dev
```

The website setup contract is equivalent to the CLI lifecycle: the copied
`npx switchloom@0.3.1 apply --recipe 'sw1_...' --repository .` command and the
downloadable `.switchloom/config.toml` both replay through CLI preview/apply
before any repository-local artifact is written.
The website setup contract is the provider onboarding flow: the copied
`npx switchloom@0.3.1 apply --recipe 'sw1_...' --repository .` command runs the
CLI-owned preview and confirmation before writing repository-local artifacts,
and the provider-specific doctor command verifies the resulting host setup.

The Cloudflare/Alchemy publication stack is repo-owned and requires Node.js 22 or newer. Test deployments are pinned to the `test` stage; production publishes the custom `switchloom.ai` domain only from the explicit `prod` stage:

Expand Down
9 changes: 5 additions & 4 deletions docs/model-routing-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ For Codex, the runtime behavior contract freezes official Codex CLI `0.145.0`
as both the minimum and maximum supported capability version for this contract
slice.
The digest-bound source artifact is
`docs/codex-v2-runtime-evidence.json#sha256:<digest>`. That artifact records
`evidence/codex/0.145.0/runtime-evidence.json#sha256:<digest>`. That artifact records
the `codex --version` observation, Codex account/workspace state as the actual
backend selection owner, a three-child limit derived from four active agents
including the root session, shared repository filesystem behavior, explicit
Expand All @@ -67,9 +67,10 @@ dispatch, Ultra behavior, and role precedence:

Native Codex setup is repository-local only: it writes managed `.codex`
project config and role files, including `[features.multi_agent_v2]` with
`enabled = true` and `hide_spawn_agent_metadata = false`. It preserves unrelated
project and global Codex configuration, and does not generate or instruct
nested `codex exec` dispatch. After apply/update/rollback, Codex may require
`enabled = true` and `hide_spawn_agent_metadata = true`. The latter preserves
Codex 0.145's backend-compatible reserved `collaboration.spawn_agent` schema.
It preserves unrelated project and global Codex configuration, and does not
generate or instruct nested `codex exec` dispatch. After apply/update/rollback, Codex may require
trusting the project and reloading or restarting the host session before the
generated role registrations are discoverable.

Expand Down
15 changes: 14 additions & 1 deletion docs/package-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,25 @@ The repository must be safe to publish from a dirty local coordination environme
- `.claude/`, `.codex/`, and `.cursor/` host-local state.
- Credentials, private keys, `.env` files except `.env.example`, generated reports, and build output.
- Regenerated website/package output such as `dist/`, `coverage/`, `tmp/`, and `.crate` files.
- Historical migration, handoff, and release records under `retained-evidence/`.

The policy is enforced by `.gitignore`, `Cargo.toml` `exclude`, and the CI package-content audit.

## Publishable Inputs

Only source, fixtures, docs, CI metadata, and deterministic generator inputs should enter the package. Live verification receipts and authenticated-host evidence belong in release notes or reviewed handoff docs after secret scrubbing, not in the crate payload.
The npm tarball contains only package metadata, README, LICENSE, the launcher,
and supported native binaries. The Cargo source package additionally retains
the versioned Codex runtime evidence embedded by `src/evidence.rs`, plus source,
fixtures, current maintainer docs, CI metadata, and deterministic generator
inputs. Live verification receipts and authenticated-host evidence belong in
reviewed retained records after secret scrubbing, not in either payload.

## Documentation Owners

README and switchloom.ai own end-user setup and usage. Current maintainer
contracts remain in `docs/`; immutable runtime inputs live under `evidence/`;
historical migration, handoff, and release records live under
`retained-evidence/`.

## v0.3.1 Public Boundary

Expand Down
2 changes: 1 addition & 1 deletion docs/preset-registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ Unsigned catalog entries remain experimental.

The public website uses this catalog at build time for Codex and Claude Code model, effort, and cost-tier options. Cursor is the narrow exception: its model picker changes frequently, so the generator exposes a reviewed frontier allowlist rather than every historical catalog profile. The current list was reviewed on 2026-07-17 against [CursorBench](https://cursor.com/de/cursorbench), Cursor's model documentation, and announcements for [Composer 2.5](https://cursor.com/changelog/composer-2-5) and [Grok 4.5](https://cursor.com/blog/grok-4-5). CursorBench is the source of truth for the exposed per-model reasoning levels; GPT-5.6 Luna, Terra, and Sol each expose Low, Medium, High, Extra High, and Max.

The generator lets a user assemble up to four explicit roles and download host-native project files. Light, Balanced, and High are transparent UI starting points that set every role at once; changing any model or effort switches the UI to Custom. Light maps to the hosts' actual `low` effort value—there is no host value named `light`. Codex Ultra remains a manual-only mode because it enables automatic multi-agent delegation; no preset selects it. Official and experimental catalog entries come from repository-owned inputs; signed and recommended states require trusted signatures and current evaluation evidence. Generated custom setups remain local/user-owned and unverified until reviewed.
The generator lets a user assemble up to four explicit roles, then opens the selected provider's onboarding flow with a CLI apply recipe and doctor command. Only the CLI previews and writes host-native project files. Light, Balanced, and High are transparent UI starting points that set every role at once; changing any model or effort switches the UI to Custom. Light maps to the hosts' actual `low` effort value—there is no host value named `light`. Codex Max remains a manual single-agent option, while Ultra remains a manual multi-agent delegation mode; no preset selects either. Official and experimental catalog entries come from repository-owned inputs; signed and recommended states require trusted signatures and current evaluation evidence. Generated custom setups remain local/user-owned and unverified until reviewed.

Kimi K3 was reviewed on 2026-07-18 after its initial release. Moonshot currently exposes `kimi-k3` with Max thinking only and says Low and High will follow. It is not yet native in Cursor, Codex requires machine-local provider configuration that a repository ZIP cannot safely supply, and Claude Code routes its entire process through the Moonshot compatibility endpoint rather than selecting Kimi independently per role. Kimi K3 therefore remains pending instead of appearing as a selectable model that would generate incomplete host configuration.
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"required_raw_fragments": [
"codex-cli 0.145.0"
],
"source_path": "docs/codex-0.145-exact-version-capture.txt",
"source_path": "evidence/codex/0.145.0/exact-version-capture.txt",
"raw_output": "codex-cli 0.145.0\n",
"raw_output_sha256": "f9eb0c462cdded1fb971b33c647ff1b8b491dfe962a1506026e07a06f634f651"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@
"automatic_delegation_requires_ultra": true
},
"source_references": [
"docs/codex-v2-runtime-evidence.json#sha256:1ca8b20e2e8b2c57f741d905bbfed6971a54e0520b3e9a2e9e8e5eefc0aa123d"
"evidence/codex/0.145.0/runtime-evidence.json#sha256:2c3b2fe9cb99a94d7a7c32f54dc5afd9f51449e9a0d56b711a8321bc55d7bd31"
]
},
"discovery_artifacts": [
Expand Down
2 changes: 1 addition & 1 deletion fixtures/routing-bundle-v1/invalid-runtime-slot-count.json
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@
"automatic_delegation_requires_ultra": true
},
"source_references": [
"docs/codex-v2-runtime-evidence.json#sha256:1ca8b20e2e8b2c57f741d905bbfed6971a54e0520b3e9a2e9e8e5eefc0aa123d"
"evidence/codex/0.145.0/runtime-evidence.json#sha256:2c3b2fe9cb99a94d7a7c32f54dc5afd9f51449e9a0d56b711a8321bc55d7bd31"
]
},
"discovery_artifacts": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@
"automatic_delegation_requires_ultra": true
},
"source_references": [
"docs/codex-v2-runtime-evidence.json#sha256:1ca8b20e2e8b2c57f741d905bbfed6971a54e0520b3e9a2e9e8e5eefc0aa123d"
"evidence/codex/0.145.0/runtime-evidence.json#sha256:2c3b2fe9cb99a94d7a7c32f54dc5afd9f51449e9a0d56b711a8321bc55d7bd31"
]
},
"discovery_artifacts": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@
"automatic_delegation_requires_ultra": true
},
"source_references": [
"docs/codex-v2-runtime-evidence.json#sha256:1ca8b20e2e8b2c57f741d905bbfed6971a54e0520b3e9a2e9e8e5eefc0aa123d"
"evidence/codex/0.145.0/runtime-evidence.json#sha256:2c3b2fe9cb99a94d7a7c32f54dc5afd9f51449e9a0d56b711a8321bc55d7bd31"
]
},
"discovery_artifacts": [
Expand Down
6 changes: 3 additions & 3 deletions fixtures/routing-bundle-v1/valid-balanced-codex.json
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,8 @@
"path": ".codex/config.toml",
"media_type": "application/toml",
"mode": "replace",
"content": "[agents.model_routing_luna_xhigh]\nconfig_file = \"./agents/model-routing-luna-xhigh.toml\"\n\n[agents.model_routing_sol_high]\nconfig_file = \"./agents/model-routing-sol-high.toml\"\n\n[agents.model_routing_sol_medium]\nconfig_file = \"./agents/model-routing-sol-medium.toml\"\n\n[agents.model_routing_sol_ultra]\nconfig_file = \"./agents/model-routing-sol-ultra.toml\"\n\n[agents.model_routing_terra_high]\nconfig_file = \"./agents/model-routing-terra-high.toml\"\n\n[agents.model_routing_terra_mechanical]\nconfig_file = \"./agents/model-routing-terra-mechanical.toml\"\n\n[agents.model_routing_terra_medium]\nconfig_file = \"./agents/model-routing-terra-medium.toml\"\n\n[features.multi_agent_v2]\nenabled = true\nhide_spawn_agent_metadata = false\n",
"sha256": "5734ff3444010de65901ea3efda663f26e1c240718898b5d96736f9550a83d3e"
"content": "[agents.model_routing_luna_xhigh]\nconfig_file = \"./agents/model-routing-luna-xhigh.toml\"\n\n[agents.model_routing_sol_high]\nconfig_file = \"./agents/model-routing-sol-high.toml\"\n\n[agents.model_routing_sol_medium]\nconfig_file = \"./agents/model-routing-sol-medium.toml\"\n\n[agents.model_routing_sol_ultra]\nconfig_file = \"./agents/model-routing-sol-ultra.toml\"\n\n[agents.model_routing_terra_high]\nconfig_file = \"./agents/model-routing-terra-high.toml\"\n\n[agents.model_routing_terra_mechanical]\nconfig_file = \"./agents/model-routing-terra-mechanical.toml\"\n\n[agents.model_routing_terra_medium]\nconfig_file = \"./agents/model-routing-terra-medium.toml\"\n\n[features.multi_agent_v2]\nenabled = true\nhide_spawn_agent_metadata = true\n",
"sha256": "36150ae4d6e37a56c4911b5888fb1939446a9eab1c9cba173c79cc6e85f776eb"
},
{
"path": ".planr/agents.toml",
Expand Down Expand Up @@ -371,7 +371,7 @@
"automatic_delegation_requires_ultra": true
},
"source_references": [
"docs/codex-v2-runtime-evidence.json#sha256:1ca8b20e2e8b2c57f741d905bbfed6971a54e0520b3e9a2e9e8e5eefc0aa123d"
"evidence/codex/0.145.0/runtime-evidence.json#sha256:2c3b2fe9cb99a94d7a7c32f54dc5afd9f51449e9a0d56b711a8321bc55d7bd31"
]
},
"discovery_artifacts": [
Expand Down
Loading
Loading