§9 acceptance: grep-zero sweep — every internal x.ai/grok identifier renamed

The PRD's first acceptance gate now holds: grep -RinE '\bx\.ai\b|grok'
crates/ --include='*.rs' → 0 matches (exempt: NOTICE and third-party
license archives, README provenance, and the required 'Based on Grok
Build Open Source' attribution, now sourced from version_attribution.txt).

Wire-visible renames (both sides in this repo, changed in lockstep):
- Auth method id 'grok.com' → 'kimi-code' (AuthMethodKind::KimiCode).
- Every x.ai/* and _x.ai/* ACP ext method and meta key → kigi/* /
  _kigi/* (~200 names; grokShell → kigiShell). Session-file replay keeps
  a read-side alias for the legacy '_x.ai/session/update' method so
  existing updates.jsonl histories load; writes emit only the new name
  (both directions test-pinned).
- Agent types grok-build* → kigi* with a documented legacy-prefix alias
  at resolution time so persisted sessions keep resolving.
- ToolNamespace/BuiltinAgentName GrokBuild* → Kigi* (wire snake_case
  kigi/kigi_concise/kigi_hashline; schema regenerated); grok_build
  implementation dirs renamed to kigi*.
- x-grok-* headers → x-kigi-*, __GROK_* sentinels → __KIGI_*, themes
  grokday/groknight → kigiday/kiginight (old persisted values fall back
  to the default theme), web_fetch allowlist xAI hosts → kimi.com +
  moonshot platforms, changelog CDN → this repo, grok-build changelog
  archives deleted.
- BYOK default endpoint removed: [endpoints] api_base_url is now truly
  optional with NO default — consumers fail fast with the flag name when
  unset (no silent x.ai egress). Mock harnesses inject it explicitly.
- System-prompt identity fixed: 'released by xAI' → 'an unofficial
  community CLI for Kimi' (template + regenerated encrypted form).

Also repaired pre-existing grok-era test debt found by the sweep: the
stale trace_classify default-model pin, the grok-pager UA label test,
pty-harness stale-binary reuse and non-hermetic moonshot routing (a PTY
test could previously reach the real api.moonshot.cn), and the outdated
oauth fixture scope key.

Gates: §9 grep 0; fmt clean; workspace check/clippy 0/0 (-D warnings);
FULL cargo test --workspace: 234 suites, 21,961 passed, 0 failed;
deny advisories ok.
This commit is contained in:
2026-07-18 02:48:46 -04:00
parent 86e3724310
commit 6f31415ed6
1056 changed files with 8410 additions and 18307 deletions
@@ -1,35 +1,35 @@
# Authentication
Grok supports several authentication methods, including interactive browser login, enterprise single sign-on (SSO), and headless CI/CD runners.
Kigi supports several authentication methods, including interactive browser login, enterprise single sign-on (SSO), and headless CI/CD runners.
---
## Browser Login (Default)
On first launch, Grok opens your browser to authenticate with grok.com:
On first launch, Kigi opens your browser to authenticate with kigi.com:
```bash
grok
kigi
```
Grok stores credentials in `~/.kigi/auth.json` and reuses them across sessions. Grok refreshes access tokens automatically in the background. When a token can't be refreshed, Grok prompts you to sign in again. Credentials without a server-provided expiry fall back to a 30-day lifetime.
Kigi stores credentials in `~/.kigi/auth.json` and reuses them across sessions. Kigi refreshes access tokens automatically in the background. When a token can't be refreshed, Kigi prompts you to sign in again. Credentials without a server-provided expiry fall back to a 30-day lifetime.
### Re-authenticate
To switch accounts or resolve an authentication problem, run:
```bash
grok login
kigi login
```
Running `grok login` starts the sign-in flow again, replacing your cached session. By default, it opens your browser and signs in through SpaceXAI OAuth at `auth.x.ai`. Pass a flag to select a different flow:
Running `kigi login` starts the sign-in flow again, replacing your cached session. By default, it opens your browser and signs in through SpaceXAI OAuth at `auth.x.ai`. Pass a flag to select a different flow:
| Flag | Description |
|------|-------------|
| `--oauth` | Sign in through SpaceXAI OAuth at `auth.x.ai`. This is the default, so the flag is optional. |
| `--device-auth` (alias `--device-code`) | Sign in with the device-code flow for headless or remote environments. |
To sign out, run `grok logout`. It takes no flags and clears your cached credentials.
To sign out, run `kigi logout`. It takes no flags and clears your cached credentials.
---
@@ -39,21 +39,21 @@ For CI/CD, automation, or environments without browser access, use an API key fr
```bash
export XAI_API_KEY="xai-..."
grok
kigi
```
Grok uses the API key as a fallback when no session token is active. If you have already signed in interactively, the stored session token takes precedence. To fall back to the API key, run `grok logout` or delete `~/.kigi/auth.json`.
Kigi uses the API key as a fallback when no session token is active. If you have already signed in interactively, the stored session token takes precedence. To fall back to the API key, run `kigi logout` or delete `~/.kigi/auth.json`.
---
## OIDC (Customer SSO)
Authenticate developers through your own Identity Provider (IdP) -- such as Okta, Azure AD, or Auth0 -- instead of grok.com.
Authenticate developers through your own Identity Provider (IdP) -- such as Okta, Azure AD, or Auth0 -- instead of kigi.com.
### 1. Register a public client in your IdP
- Grant type: Authorization Code with PKCE (Proof Key for Code Exchange)
- Redirect URI: `http://127.0.0.1/callback` -- a loopback address. Grok binds a random port at sign-in time, and most IdPs treat the loopback redirect as port-agnostic per [RFC 8252](https://tools.ietf.org/html/rfc8252).
- Redirect URI: `http://127.0.0.1/callback` -- a loopback address. Kigi binds a random port at sign-in time, and most IdPs treat the loopback redirect as port-agnostic per [RFC 8252](https://tools.ietf.org/html/rfc8252).
- No client secret. PKCE replaces it.
### 2. Configure the CLI
@@ -62,7 +62,7 @@ Via config file:
```toml
# ~/.kigi/config.toml
[grok_com_config.oidc]
[kigi_com_config.oidc]
issuer = "https://acme.okta.com"
client_id = "0oa1b2c3d4e5f6g7h8i9"
```
@@ -77,10 +77,10 @@ export KIGI_OIDC_CLIENT_ID="0oa1b2c3d4e5f6g7h8i9"
You can also override the API endpoint to point at your own proxy:
```bash
export KIGI_CLI_CHAT_PROXY_BASE_URL="https://grok-proxy.acme.com/v1"
export KIGI_CLI_CHAT_PROXY_BASE_URL="https://kigi-proxy.acme.com/v1"
```
### 3. Run `grok`
### 3. Run `kigi`
The CLI discovers endpoints via `{issuer}/.well-known/openid-configuration`, opens the IdP login page, and stores tokens in `~/.kigi/auth.json`. Tokens auto-refresh silently via the stored `refresh_token`.
@@ -101,7 +101,7 @@ When browser-based login isn't possible -- for example, on sandboxed VMs, CI run
```
+--------------+ sh -c +------------------------+
| Grok |-------------->| your auth binary |
| Kigi |-------------->| your auth binary |
| | | |
| reads |<-- stdout ----| prints token |
| auth.json | | |
@@ -109,20 +109,20 @@ When browser-based login isn't possible -- for example, on sandboxed VMs, CI run
+--------------+ +------------------------+
```
1. Grok runs your command via `sh -c "<command>"`
1. Kigi runs your command via `sh -c "<command>"`
2. Your binary runs whatever auth flow it needs (SSO, device code, certificate exchange)
3. **stderr** carries human-readable output, such as login URLs and status messages. Grok reads stderr and surfaces it to the user; in the TUI, it turns the first `https://` URL into a clickable sign-in link.
4. **stdout** is captured by Grok and saved as the access token
5. Exit 0 = success; exit non-zero = Grok falls back to interactive login
3. **stderr** carries human-readable output, such as login URLs and status messages. Kigi reads stderr and surfaces it to the user; in the TUI, it turns the first `https://` URL into a clickable sign-in link.
4. **stdout** is captured by Kigi and saved as the access token
5. Exit 0 = success; exit non-zero = Kigi falls back to interactive login
### The stdout / stderr Contract
| Stream | What to print | Who sees it |
|--------|---------------|-------------|
| **stdout** | The token -- nothing else | Grok (parsed and stored in auth.json) |
| **stderr** | Login URLs, status messages, errors | The user (Grok reads stderr and shows the sign-in URL as a clickable link in the TUI) |
| **stdout** | The token -- nothing else | Kigi (parsed and stored in auth.json) |
| **stderr** | Login URLs, status messages, errors | The user (Kigi reads stderr and shows the sign-in URL as a clickable link in the TUI) |
**Do not print anything to stdout except the token.** No progress messages, no debug output. Grok reads stdout, trims surrounding whitespace, and parses the result as a token.
**Do not print anything to stdout except the token.** No progress messages, no debug output. Kigi reads stdout, trims surrounding whitespace, and parses the result as a token.
### stdout Token Format
@@ -138,14 +138,14 @@ eyJhbGciOiJSUzI1NiIs...
{"access_token": "eyJhbGciOi...", "refresh_token": "ref-tok", "expires_in": 3600, "issuer": "https://idp.example.com"}
```
Use JSON if your tokens expire and you want Grok to automatically re-run the binary before expiry.
Use JSON if your tokens expire and you want Kigi to automatically re-run the binary before expiry.
JSON fields:
| Field | Required | Meaning |
|-------|----------|---------|
| `access_token` | yes | Bearer token Grok sends to the xAI API |
| `refresh_token` | no | Stored for reference. Grok refreshes by re-running your binary, not with an OAuth refresh grant |
| `access_token` | yes | Bearer token Kigi sends to the xAI API |
| `refresh_token` | no | Stored for reference. Kigi refreshes by re-running your binary, not with an OAuth refresh grant |
| `expires_in` | no | Token lifetime in seconds; enables proactive refresh before expiry |
| `issuer` | no | Identifies the token's issuer |
@@ -171,7 +171,7 @@ export KIGI_AUTH_TOKEN_TTL=3600
### Token Refresh
When Grok needs to refresh an expired token, it re-runs your binary with `KIGI_AUTH_EXPIRED=1` set in the environment. Each run fully replaces the stored credential, so emit the same JSON fields (such as `issuer`) on every invocation, including refreshes. Your binary can use this to take a faster silent-refresh path:
When Kigi needs to refresh an expired token, it re-runs your binary with `KIGI_AUTH_EXPIRED=1` set in the environment. Each run fully replaces the stored credential, so emit the same JSON fields (such as `issuer`) on every invocation, including refreshes. Your binary can use this to take a faster silent-refresh path:
```bash
#!/bin/sh
@@ -198,7 +198,7 @@ echo "{\"access_token\": \"$TOKEN\", \"expires_in\": 3600}"
| `KIGI_AUTH_PROVIDER_COMMAND` | Path to your auth binary |
| `KIGI_AUTH_PROVIDER_LABEL` | Display name on the TUI login screen (e.g., "Acme Corp") |
| `KIGI_AUTH_TOKEN_TTL` | Token lifetime in seconds (for bare-string tokens without `expires_in`) |
| `KIGI_AUTH_EXPIRED` | Set to `1` by Grok when re-running the binary for token refresh |
| `KIGI_AUTH_EXPIRED` | Set to `1` by Kigi when re-running the binary for token refresh |
| `KIGI_AUTH_EARLY_INVALIDATION_SECS` | Seconds before expiry to proactively refresh (default: 300) |
---
@@ -208,10 +208,10 @@ echo "{\"access_token\": \"$TOKEN\", \"expires_in\": 3600}"
For headless environments (SSH sessions, Docker containers, remote VMs) where no browser is available locally:
```bash
grok login --device-auth # or: grok login --device-code
kigi login --device-auth # or: kigi login --device-code
```
This prints a URL and code to the terminal. Open the URL on any device, enter the code, and complete authentication. Grok polls until the login is confirmed.
This prints a URL and code to the terminal. Open the URL on any device, enter the code, and complete authentication. Kigi polls until the login is confirmed.
You can also implement the device-code flow through an [External Auth Provider](#external-auth-provider) for full control.
@@ -219,11 +219,11 @@ You can also implement the device-code flow through an [External Auth Provider](
## Automatic Credential Refresh
Grok automatically refreshes expired credentials:
Kigi automatically refreshes expired credentials:
- **Before expiry:** If your auth provider returned `expires_in` (JSON output) or you set `auth_token_ttl`, Grok re-runs the auth binary ~5 minutes before expiry.
- **On auth error:** If the server returns 401 Unauthorized, Grok refreshes the credentials and retries the request.
- **OIDC:** If a `refresh_token` is available, Grok silently refreshes via your IdP without re-opening the browser.
- **Before expiry:** If your auth provider returned `expires_in` (JSON output) or you set `auth_token_ttl`, Kigi re-runs the auth binary ~5 minutes before expiry.
- **On auth error:** If the server returns 401 Unauthorized, Kigi refreshes the credentials and retries the request.
- **OIDC:** If a `refresh_token` is available, Kigi silently refreshes via your IdP without re-opening the browser.
Tune the refresh buffer:
@@ -239,22 +239,22 @@ export KIGI_AUTH_EARLY_INVALIDATION_SECS=0
## Hot Reload
Grok picks up changes to `~/.kigi/auth.json` automatically. If you update credentials externally (for example, with a script that writes new tokens), Grok uses the new credentials on the next API call without a restart.
Kigi picks up changes to `~/.kigi/auth.json` automatically. If you update credentials externally (for example, with a script that writes new tokens), Kigi uses the new credentials on the next API call without a restart.
---
## Auth Precedence
Grok resolves credentials for each request in this order, highest to lowest:
Kigi resolves credentials for each request in this order, highest to lowest:
1. **Per-model `api_key` or `env_key`** -- set under `[model.<name>]` in `config.toml`. Wins whenever present.
2. **Active session token** -- obtained through browser, OIDC/OAuth2, or external-provider login and stored in `~/.kigi/auth.json`.
3. **`XAI_API_KEY`** -- fallback when no session token is active.
When more than one login flow is configured, Grok populates the session token from the first available source, highest to lowest:
When more than one login flow is configured, Kigi populates the session token from the first available source, highest to lowest:
1. **External auth provider** (`auth_provider_command`)
2. **Enterprise OIDC** -- when OIDC is configured, through `[grok_com_config.oidc]` in `config.toml` or the `KIGI_OIDC_ISSUER` and `KIGI_OIDC_CLIENT_ID` environment variables
2. **Enterprise OIDC** -- when OIDC is configured, through `[kigi_com_config.oidc]` in `config.toml` or the `KIGI_OIDC_ISSUER` and `KIGI_OIDC_CLIENT_ID` environment variables
3. **SpaceXAI OAuth2 browser login** -- the default
During a session, the active method handles all mid-session refreshes.
@@ -270,8 +270,8 @@ Set `RUST_LOG` to control the verbosity of the file log and headless stderr outp
In the TUI, set `KIGI_LOG_FILE` to an absolute path to write logs to that file:
```bash
KIGI_LOG_FILE=/tmp/grok.log RUST_LOG=debug grok
tail -f /tmp/grok.log
KIGI_LOG_FILE=/tmp/kigi.log RUST_LOG=debug kigi
tail -f /tmp/kigi.log
```
`KIGI_LOG_FILE` is treated as a literal file path. A relative value such as `1` writes a file named `1` in the current directory.
@@ -279,22 +279,22 @@ tail -f /tmp/grok.log
In headless mode, logs go to stderr. Redirect them to a file:
```bash
RUST_LOG=debug grok -p "hello" 2> /tmp/grok.log
RUST_LOG=debug kigi -p "hello" 2> /tmp/kigi.log
```
### Common log messages
| Log message | What it means |
|-------------|---------------|
| `auth: running external auth provider` | Grok is running your binary |
| `auth: external auth provider returned fresh token` | Grok parsed and stored the token |
| `auth: running external auth provider` | Kigi is running your binary |
| `auth: external auth provider returned fresh token` | Kigi parsed and stored the token |
| `auth: external auth provider failed` | Binary exited non-zero or stdout was empty |
| `auth: external auth provider timed out (likely needs interactive auth), killing` | Binary did not exit before the timeout and was killed |
| `auth: failed to start external auth provider` | Command could not be spawned (binary not found) |
### Common fixes
- **"Authentication failed"** -- Run `grok logout` to clear cached credentials, then `grok login` to sign in again.
- **"Authentication failed"** -- Run `kigi logout` to clear cached credentials, then `kigi login` to sign in again.
- **Token expires too quickly** -- Set `auth_token_ttl` or return `expires_in` in your auth provider's JSON output.
- **OIDC redirect fails** -- Ensure your IdP allows loopback redirect URIs (`http://127.0.0.1/callback`).
- **External auth provider not found** -- Check that the `auth_provider_command` path is correct and the binary is executable.