From 1d23ec28666825c61a6b929a21b3869efc47b794 Mon Sep 17 00:00:00 2001 From: Lakshman Patel Date: Tue, 15 Sep 2026 09:23:51 +0530 Subject: [PATCH] refactor!: rename host product references from hawk to rho Replace all hawk/Hawk/HAWK references with rho/Rho/RHO across code, docs, CI, and templates. Functional identifiers move with the rename: ~/.hawk -> ~/.rho, hawk_build -> rho_build, hawk_response -> rho_response, EXPORT_HAWK_FIXTURE -> EXPORT_RHO_FIXTURE, ToolNamespaceHawkBuild -> ToolNamespaceRhoBuild. Drop references to retired ecosystem repos shrike, harrier, kestrel, merlin, and fix the stale CODEOWNERS /flux.go path to /version.go. --- .github/ISSUE_TEMPLATE/feature_request.yml | 4 +- .github/workflows/ci.yml | 2 +- AGENTS.md | 14 +++--- CHANGELOG.md | 23 +++++---- CODEOWNERS | 2 +- CONTRIBUTING.md | 2 +- LICENSE | 2 +- Makefile | 8 ++-- README.md | 25 +++++----- SECURITY.md | 4 +- assets/logo.svg | 2 +- catalog/catalog_test.go | 2 +- catalog/credentials.go | 2 +- catalog/errors.go | 2 +- catalog/live/fetchers_providers.go | 2 +- catalog/provider_credentials.go | 2 +- catalog/refresh.go | 2 +- catalog/registry/protocol_matrix_test.go | 6 +-- catalog/registry/provider_spec_test.go | 2 +- catalog/testdata_test.go | 10 ++-- catalog/v1.go | 4 +- catalog/zai/endpoints.go | 2 +- client/adapters/concentrate_responses.go | 2 +- client/adapters/concentrate_responses_test.go | 2 +- client/adapters/poolside.go | 2 +- client/continuation.go | 4 +- client/core/image.go | 2 +- client/extract.go | 4 +- client/extract_test.go | 2 +- client/media.go | 2 +- client/token_utils.go | 2 +- config/category.go | 2 +- config/discovery_env.go | 2 +- config/provider_env.go | 2 +- config/routing_build.go | 4 +- credentials/combined_test.go | 8 ++-- credentials/health.go | 4 +- credentials/migrate.go | 16 +++---- credentials/migrate_test.go | 12 ++--- credentials/platform.go | 2 +- docs/ARCHITECTURE.md | 4 +- docs/architecture/HOST-ENGINE-BOUNDARY.md | 42 ++++++++-------- docs/design/FLUX-ENTERPRISE.md | 6 +-- docs/guides/CREDENTIAL-SETUP-FLOW.md | 12 ++--- docs/guides/DYNAMIC-MODEL-DISCOVERY.md | 48 +++++++++---------- docs/plans/fix-critical-and-high-review.md | 6 +-- engine/control_plane_test.go | 2 +- engine/host_control.go | 2 +- internal/observability/genai_semconv.go | 2 +- internal/probehttp/probehttp.go | 2 +- lefthook.yml | 2 +- llm/provider.go | 6 +-- llm/types.go | 6 +-- plans/client-package-decomposition.md | 24 +++++----- runtime/preflight.go | 4 +- runtime/runtime.go | 4 +- scripts/check-ecosystem-boundaries.sh | 16 +++---- setup/apply_credentials.go | 2 +- setup/catalog.go | 2 +- setup/deployment.go | 2 +- setup/setup_ui.go | 2 +- setup/status.go | 2 +- setup/status_test.go | 12 ++--- tools/versioning.go | 26 +++++----- verify/cases.go | 2 +- 65 files changed, 219 insertions(+), 217 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index cb193397..d330cc69 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -8,7 +8,7 @@ body: attributes: value: | Thanks for proposing a feature. flux is the LLM client + skill router - that backs the hawk-eco ecosystem. Every feature is evaluated against + that backs the rho-eco ecosystem. Every feature is evaluated against whether it serves **a single developer** running an AI agent locally. Before submitting: @@ -65,6 +65,6 @@ body: description: flux avoids enterprise scope. Confirm this feature respects that. options: - label: Works with zero configuration (sensible defaults). - - label: Does not require a network call to a hawk-eco service. + - label: Does not require a network call to a rho-eco service. - label: Stores any state locally by default. - label: Has an escape hatch (override via flag, env, or config). diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2987f30b..79ecb903 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,4 @@ -# Strict CI pipeline for hawk-eco Go repos. +# Strict CI pipeline for rho-eco Go repos. # All jobs must pass — no continue-on-error except where explicitly noted. name: CI diff --git a/AGENTS.md b/AGENTS.md index 38967ba1..ae86d0ab 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -15,7 +15,7 @@ When starting any new work (feature, fix, refactor, chore), always create a feat ## Observability -See [hawk/docs/OTEL-CONVENTIONS.md](https://github.com/GrayCodeAI/hawk/blob/main/docs/OTEL-CONVENTIONS.md) for the shared OpenTelemetry attribute vocabulary (`gen_ai.*`, `cost.usd`, etc.) used across all GrayCodeAI repos. +See [rho/docs/OTEL-CONVENTIONS.md](https://github.com/GrayCodeAI/rho/blob/main/docs/OTEL-CONVENTIONS.md) for the shared OpenTelemetry attribute vocabulary (`gen_ai.*`, `cost.usd`, etc.) used across all GrayCodeAI repos. ## Build & Test @@ -49,9 +49,9 @@ make ci # Full CI suite ## Common Pitfalls -- `engine`, `llm`, `graph` and `tools` are the host contract surface. Hawk +- `engine`, `llm`, `graph` and `tools` are the host contract surface. Rho must not assemble `client`, `catalog`, `config`, `credentials`, `router` or - `runtime`. Six symbols Hawk needs (`ChatOptions`, `ContinuationConfig`, + `runtime`. Six symbols Rho needs (`ChatOptions`, `ContinuationConfig`, `StreamResult`, `ResponseFormat`, `ImageURLPart`, `InputAudioPart`) live in `llm` with no `engine` alias; widening the facade to cover them is a deliberate API change, not an incidental one. @@ -59,7 +59,7 @@ make ci # Full CI suite consumers; preserve its method set and the facade's type identity - Streaming tests need careful goroutine management - `go.work` here should stay minimal; the parent `graycode-eco/go.work` - connects this independent `flux` checkout beside Hawk for local development. + connects this independent `flux` checkout beside Rho for local development. Do not add extra local `replace` directives here without coordinating with the parent workspace. @@ -145,7 +145,7 @@ make ci # Full CI suite | Main test file | `client/client_test.go` (httptest servers, provider detection) | | Linter config | `.golangci.yml` (govet, ineffassign, misspell — minimal) | -This is an independent repository consumed by Hawk. In the local -`graycode-eco` parent workspace it is checked out beside `hawk` as `../flux` +This is an independent repository consumed by Rho. In the local +`graycode-eco` parent workspace it is checked out beside `rho` as `../flux` and connected through the parent `go.work`; publish changes here, then update -Hawk's module pin through a separate PR. +Rho's module pin through a separate PR. diff --git a/CHANGELOG.md b/CHANGELOG.md index a67aa4d9..7a9417ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,23 +7,29 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) · Versioning: ## [Unreleased] +### Changed +- **Renamed host product references from hawk to rho.** Host config paths + (`~/.rho/`), the `rho_build`/`rho_build_concise` tool namespaces, the + `rho_response` schema name, and the `EXPORT_RHO_FIXTURE` env var now use the + rho identity. Retired ecosystem repos (`shrike`, `harrier`, `kestrel`, + `merlin`) are no longer referenced. + ## [0.0.1] — 2026-09-15 Reset to v0.0.1 for the rename to `flux`. ### Changed -- **Renamed the project from eyrie to flux.** Module path is now +- **Renamed the project to flux.** Module path is now `github.com/GrayCodeAI/flux`. All packages, docs, SDK stubs, CI workflows, and issue templates reference the new name; no Go API surface changed. - **Logo redesigned** for the flux identity — abstract flow arcs around a - glowing bolt; the hawk/nest artwork is gone. + glowing bolt; the previous nest artwork is gone. - **Makefile drops linker LDFLAGS.** flux is a library; the version is embedded from the VERSION file, not injected into a main package. -Versions v0.3.0–v0.6.0 were published under the previous module paths -(`github.com/hawk/flux`, then `github.com/GrayCodeAI/eyrie`). They remain on -the Go module proxy under those old paths; new consumption starts at v0.0.1 -of `github.com/GrayCodeAI/flux`. +Versions v0.3.0–v0.6.0 were published under the previous module paths. They +remain on the Go module proxy under those old paths; new consumption starts at +v0.0.1 of `github.com/GrayCodeAI/flux`. ### Changed — Shared MiMo auth-retry helper (2026-08-16) - **Deduplicated `doRequestWithMimoAuthRetry`** between the OpenAI and @@ -108,8 +114,7 @@ of `github.com/GrayCodeAI/flux`. 5. Whitespace collapse Reports aggregate `BytesSaved` and `PercentOff` across all tools in the slice. Safe to call concurrently. - Aligns flux with the rest of the hawk-eco ecosystem (`hawk`, `shrike`, - `harrier`, `kestrel`, `merlin`). + Aligns flux with the rest of the rho-eco ecosystem. ### Added - Output guardrails framework (PII, secrets, injection, harmful content) @@ -190,7 +195,7 @@ of `github.com/GrayCodeAI/flux`. **Config** - Provider detection from env vars (priority order) -- `~/.hawk/provider.json` config file I/O +- `~/.rho/provider.json` config file I/O - `ApplyProviderConfigToEnv` — applies config to `os.Environ` - OpenAI-compatible runtime resolution - Provider profile management diff --git a/CODEOWNERS b/CODEOWNERS index f30603a5..11a86102 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -9,7 +9,7 @@ /types/ @GrayCodeAI/llm-team /catalog/ @GrayCodeAI/llm-team /router/ @GrayCodeAI/llm-team -/flux.go @GrayCodeAI/llm-team +/version.go @GrayCodeAI/llm-team /VERSION @GrayCodeAI/maintainers # CI / release diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5022d9d2..cac9384b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ Thanks for your interest! This guide covers the conventions used across the graycode-eco. The eco-wide standards (versioning, release tooling, repo layout) -are defined in . +are defined in . ## Quick start diff --git a/LICENSE b/LICENSE index 1f593fd8..ff25dd91 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2026 Hawk Contributors +Copyright (c) 2026 Rho Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile b/Makefile index 37c5e28a..ac28836b 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ -# Canonical hawk-eco Makefile for Go LIBRARY repos. -# flux is a versioned Go library consumed by Hawk (no standalone binary). +# Canonical rho-eco Makefile for Go LIBRARY repos. +# flux is a versioned Go library consumed by Rho (no standalone binary). # --------------------------------------------------------------------------- # Project metadata @@ -8,7 +8,7 @@ NAME := flux # --------------------------------------------------------------------------- # Versioning — sourced from VERSION file; falls back to git describe. -# See https://github.com/GrayCodeAI/hawk/blob/main/VERSIONING.md. +# See https://github.com/GrayCodeAI/rho/blob/main/VERSIONING.md. # --------------------------------------------------------------------------- VERSION ?= $(shell cat VERSION 2>/dev/null | head -n1 | tr -d '[:space:]' || git describe --tags --always --dirty 2>/dev/null || echo "dev") COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "none") @@ -49,7 +49,7 @@ all: lint test build ## Default — lint, test, build. # --------------------------------------------------------------------------- # Build / install / release. # --------------------------------------------------------------------------- -build: ## Build all library packages (flux is a library consumed by hawk; no standalone binary). +build: ## Build all library packages (flux is a library consumed by rho; no standalone binary). go build ./... # --------------------------------------------------------------------------- diff --git a/README.md b/README.md index 4e0cd1d7..033dbb8e 100644 --- a/README.md +++ b/README.md @@ -30,22 +30,22 @@ ## What is flux -flux is the LLM provider runtime that powers the [hawk](https://github.com/GrayCodeAI/hawk) coding agent. It handles everything between your application and LLM APIs — authentication, model resolution, streaming, retries, rate limiting, and caching. +flux is the LLM provider runtime that powers the [rho](https://github.com/GrayCodeAI/rho) coding agent. It handles everything between your application and LLM APIs — authentication, model resolution, streaming, retries, rate limiting, and caching. When your app calls a model, flux figures out which provider to use, how to talk to it, and how to stream the response back. Switch from Anthropic to Ollama? flux handles the translation. API returns 529? flux retries with backoff. Response hits `max_tokens`? flux continues automatically. **Your app never talks to an LLM API directly. flux does.** -Hawk is the product face: it owns UX, agent orchestration, tools, permissions, +Rho is the product face: it owns UX, agent orchestration, tools, permissions, sessions, and product semantics. Flux is the provider engine: it owns credentials, catalog and route resolution, provider transports, normalized -streams, retry/fallback, usage, and provider telemetry. Hawk integrates through +streams, retry/fallback, usage, and provider telemetry. Rho integrates through the stable [`engine`](engine/) facade rather than assembling Flux's internal provider packages. ## Ecosystem Boundaries -flux is a Hawk support engine. Keep the dependency edge one-way. +flux is a Rho support engine. Keep the dependency edge one-way. Hosts may import exactly four packages: @@ -58,13 +58,12 @@ Hosts may import exactly four packages: Everything else is engine-internal: `client`, `catalog`, `config`, `credentials`, `router`, `runtime`, and their subpackages are not shared -contracts. Enforced by `hawk/scripts/check-flux-engine-boundary.sh` -and two Go AST tests in `hawk/internal/testaudit/`. +contracts. Enforced by `rho/scripts/check-flux-engine-boundary.sh` +and two Go AST tests in `rho/internal/testaudit/`. -- do not import `hawk/internal/*` -- do not import the removed legacy path `hawk/shared/types` -- do not import other engines (`harrier`, `shrike`, `swift`, `kestrel`, - `merlin`) — engines are peers, not dependencies +- do not import `rho/internal/*` +- do not import the removed legacy path `rho/shared/types` +- do not import other engines (`swift`) — engines are peers, not dependencies ## Quick Start @@ -187,7 +186,7 @@ ANTHROPIC_API_KEY=sk-... go run ./examples/basic/ ## Supported Providers -22 provider gateways in `catalog/registry/providers.go` (hawk `/config` uses the same list), listed in registry `SortOrder`: +22 provider gateways in `catalog/registry/providers.go` (rho `/config` uses the same list), listed in registry `SortOrder`: | Provider | ID | Env variable | |---|---|---| @@ -319,10 +318,8 @@ flux is part of the graycode-eco: | Component | Repository | Purpose | |---|---|---| -| **hawk** | [GrayCodeAI/hawk](https://github.com/GrayCodeAI/hawk) | AI coding agent | +| **rho** | [GrayCodeAI/rho](https://github.com/GrayCodeAI/rho) | AI coding agent | | **flux** | This repo | LLM provider runtime | -| **shrike** | [GrayCodeAI/shrike](https://github.com/GrayCodeAI/shrike) | Tokenizer & compression | -| **harrier** | [GrayCodeAI/harrier](https://github.com/GrayCodeAI/harrier) | Graph-based memory | | **swift** | [GrayCodeAI/swift](https://github.com/GrayCodeAI/swift) | Session capture | ## Development diff --git a/SECURITY.md b/SECURITY.md index e2719f34..b2fe2fca 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -7,7 +7,7 @@ minor versions once `1.x` ships. Older versions receive critical-severity fixes only on a best-effort basis. The current canonical version is the contents of the [`VERSION`](./VERSION) -file at the repo root. See [`VERSIONING.md`](https://github.com/GrayCodeAI/hawk/blob/main/VERSIONING.md) +file at the repo root. See [`VERSIONING.md`](https://github.com/GrayCodeAI/rho/blob/main/VERSIONING.md) for the eco-wide versioning scheme. ## Reporting a vulnerability @@ -15,7 +15,7 @@ for the eco-wide versioning scheme. **Do not open a public GitHub issue for security vulnerabilities.** Instead: 1. Open a private [GitHub Security Advisory](https://github.com/GrayCodeAI/flux/security/advisories/new), **or** -2. Email `security@hawk.ai` with the details below. +2. Email `security@rho.ai` with the details below. Include in your report: diff --git a/assets/logo.svg b/assets/logo.svg index fe6f073e..b8ea1c33 100644 --- a/assets/logo.svg +++ b/assets/logo.svg @@ -88,7 +88,7 @@ the foundation layer for hawk + font-size="12" fill="#4ECDC4" opacity="0.65" letter-spacing="1.5">the foundation layer for rho diff --git a/catalog/catalog_test.go b/catalog/catalog_test.go index ef56d314..80d6797f 100644 --- a/catalog/catalog_test.go +++ b/catalog/catalog_test.go @@ -6,7 +6,7 @@ func TestAnthropicNameToCanonical(t *testing.T) { t.Parallel() tests := []struct{ input, want string }{ {"claude-sonnet-4-6-20250814", "claude-sonnet-4-6"}, - {"us.hawk.claude-opus-4-6-v1:0", "claude-opus-4-6"}, + {"us.rho.claude-opus-4-6-v1:0", "claude-opus-4-6"}, {"claude-3-5-haiku-20241022", "claude-3-5-haiku"}, {"claude-3-7-sonnet-20250219", "claude-3-7-sonnet"}, {"claude-opus-4-5-20251101", "claude-opus-4-5"}, diff --git a/catalog/credentials.go b/catalog/credentials.go index b81f04ae..1ea1c84f 100644 --- a/catalog/credentials.go +++ b/catalog/credentials.go @@ -2,7 +2,7 @@ package catalog // Credentials carries API keys and related env (base URLs) for provider-backed catalog discovery. // Keys use standard env var names (e.g. OPENROUTER_API_KEY). Populate via config.DiscoveryCredentials. -// or pass an explicit map from hawk — do not hardcode provider lists in hawk. +// or pass an explicit map from rho — do not hardcode provider lists in rho. type Credentials struct { APIKeys map[string]string } diff --git a/catalog/errors.go b/catalog/errors.go index 9562cc3c..5f0ba02b 100644 --- a/catalog/errors.go +++ b/catalog/errors.go @@ -3,5 +3,5 @@ package catalog import "errors" // ErrCatalogCacheRequired is returned when no valid ~/.flux/model_catalog.json exists. -// Run catalog discovery (hawk models refresh / flux catalog discover) to populate the cache. +// Run catalog discovery (rho models refresh / flux catalog discover) to populate the cache. var ErrCatalogCacheRequired = errors.New("model catalog cache required") diff --git a/catalog/live/fetchers_providers.go b/catalog/live/fetchers_providers.go index 3248fe07..d0e14293 100644 --- a/catalog/live/fetchers_providers.go +++ b/catalog/live/fetchers_providers.go @@ -977,7 +977,7 @@ func FetchConcentrate(env map[string]string) ([]Entry, error) { // capabilities but omits the provider-level supports.tools field. // The Responses API and model-details endpoint advertise function // calling for these routed models, so preserve that capability for - // Hawk's tool-enabled coding loop. + // Rho's tool-enabled coding loop. entry.Features = append(entry.Features, "function_calling") entries = append(entries, entry) } diff --git a/catalog/provider_credentials.go b/catalog/provider_credentials.go index d876a175..c0297da1 100644 --- a/catalog/provider_credentials.go +++ b/catalog/provider_credentials.go @@ -59,7 +59,7 @@ func apiKeyEnvFromDeployment(dep Deployment) string { } // CredentialStatusForProvider reports whether a provider needs an API key (local vs required). -// For set/empty status use hawk config.EnvKeyStatus or credentials.HasSecret — catalog does not read env. +// For set/empty status use rho config.EnvKeyStatus or credentials.HasSecret — catalog does not read env. func CredentialStatusForProvider(compiled *CompiledCatalog, providerID string) string { providerID = canonicalProviderID(providerID) if providerID == "" { diff --git a/catalog/refresh.go b/catalog/refresh.go index 2705246b..dd8b1b18 100644 --- a/catalog/refresh.go +++ b/catalog/refresh.go @@ -96,7 +96,7 @@ func (r *RefreshResult) Summary() string { ) } -// DiscoverReport returns a multi-line report for `hawk models refresh` / `flux catalog discover`. +// DiscoverReport returns a multi-line report for `rho models refresh` / `flux catalog discover`. func (r *RefreshResult) DiscoverReport() string { if r == nil || r.Compiled == nil { return "Catalog discovery: no data" diff --git a/catalog/registry/protocol_matrix_test.go b/catalog/registry/protocol_matrix_test.go index 7f436cc2..86ef0a7a 100644 --- a/catalog/registry/protocol_matrix_test.go +++ b/catalog/registry/protocol_matrix_test.go @@ -12,7 +12,7 @@ import ( // agnes, kimi, openai, grok, openrouter, groq, canopywave, poolside, // clinepass, ollama, azure, gemini (native/Gemini protocol), concentrate (Responses) // -// Vendors documenting both OpenAI + Anthropic (hawk uses exactly one — OpenAI): +// Vendors documenting both OpenAI + Anthropic (rho uses exactly one — OpenAI): // deepseek, zai_*, xiaomi_mimo_*, minimax_*, longcat // opencodego keeps both clients only for per-model routing (one protocol per call; // never cross-protocol fallback on the same request) @@ -21,7 +21,7 @@ import ( // anthropic, bedrock // // Rule: if a vendor is OpenAI-compatible only, do not invent an Anthropic client. -// If a vendor documents both, hawk uses OpenAI only — never both protocols for the +// If a vendor documents both, rho uses OpenAI only — never both protocols for the // same provider request (no OpenAI→Anthropic error fallback). func TestProviderProtocolMatrix_OpenAIOnlyHaveNoAnthropicTransport(t *testing.T) { @@ -50,7 +50,7 @@ func TestProviderProtocolMatrix_OpenAIOnlyHaveNoAnthropicTransport(t *testing.T) func TestProviderProtocolMatrix_DualOfficialStayOpenAIPrimary(t *testing.T) { t.Parallel() - // Catalog primary protocol is OpenAI chat completions. Hawk clients for these + // Catalog primary protocol is OpenAI chat completions. Rho clients for these // providers use OpenAI only (OpenCode Go is the exception: per-model single // protocol, still no cross-protocol fallback). dualPrimaryOpenAI := []string{ diff --git a/catalog/registry/provider_spec_test.go b/catalog/registry/provider_spec_test.go index dbf1f152..ae5f41e0 100644 --- a/catalog/registry/provider_spec_test.go +++ b/catalog/registry/provider_spec_test.go @@ -26,7 +26,7 @@ func TestProviderSpecs_AgnesOpenAIOnlyLongCatOpenAIPrimary(t *testing.T) { } // LongCat: official docs expose BOTH OpenAI (/openai) and Anthropic (/anthropic). - // Hawk uses the OpenAI primary only — Anthropic is not required when OpenAI works. + // Rho uses the OpenAI primary only — Anthropic is not required when OpenAI works. longcat, ok := registry.SpecByProviderID("longcat") if !ok { t.Fatal("missing longcat") diff --git a/catalog/testdata_test.go b/catalog/testdata_test.go index 278836d0..f5f0acff 100644 --- a/catalog/testdata_test.go +++ b/catalog/testdata_test.go @@ -7,18 +7,18 @@ import ( "testing" ) -// Run with EXPORT_HAWK_FIXTURE=1 to refresh hawk/internal/catalogtest/testdata/minimal_v1.json -func TestExportHawkCatalogFixture(t *testing.T) { +// Run with EXPORT_RHO_FIXTURE=1 to refresh rho/internal/catalogtest/testdata/minimal_v1.json +func TestExportRhoCatalogFixture(t *testing.T) { t.Parallel() - if os.Getenv("EXPORT_HAWK_FIXTURE") != "1" { - t.Skip("set EXPORT_HAWK_FIXTURE=1 to export") // TODO: https://github.com/GrayCodeAI/flux/issues/30 + if os.Getenv("EXPORT_RHO_FIXTURE") != "1" { + t.Skip("set EXPORT_RHO_FIXTURE=1 to export") // TODO: https://github.com/GrayCodeAI/flux/issues/30 } c := SeedCatalog() data, err := json.MarshalIndent(c, "", " ") if err != nil { t.Fatal(err) } - out := filepath.Join("..", "..", "hawk", "internal", "catalogtest", "testdata", "minimal_v1.json") + out := filepath.Join("..", "..", "rho", "internal", "catalogtest", "testdata", "minimal_v1.json") if err := os.MkdirAll(filepath.Dir(out), 0o755); err != nil { t.Fatal(err) } diff --git a/catalog/v1.go b/catalog/v1.go index adf37be5..2cbab446 100644 --- a/catalog/v1.go +++ b/catalog/v1.go @@ -630,7 +630,7 @@ func LoadCatalog(ctx context.Context, opts LoadCatalogOptions) (*CompiledCatalog return compiled, nil } if opts.RequireCache { - return nil, fmt.Errorf("%w (%s missing or invalid; run: hawk models refresh)", ErrCatalogCacheRequired, opts.CachePath) + return nil, fmt.Errorf("%w (%s missing or invalid; run: rho models refresh)", ErrCatalogCacheRequired, opts.CachePath) } bootstrap := BootstrapCatalog() compiled, err := CompileCatalog(&bootstrap) @@ -639,7 +639,7 @@ func LoadCatalog(ctx context.Context, opts LoadCatalogOptions) (*CompiledCatalog } compiled.Diagnostics = append(compiled.Diagnostics, CatalogDiagnostic{ Code: "bootstrap_only", - Message: "no model catalog cache; run hawk models refresh or flux catalog discover", + Message: "no model catalog cache; run rho models refresh or flux catalog discover", }) return compiled, nil } diff --git a/catalog/zai/endpoints.go b/catalog/zai/endpoints.go index 67040ba5..cfc86e37 100644 --- a/catalog/zai/endpoints.go +++ b/catalog/zai/endpoints.go @@ -1,6 +1,6 @@ // Package zai resolves Z.AI (Zhipu GLM) API base URLs for General (pay-as-you-go) // and Coding Plan subscriptions across International vs China regions. -// Hawk uses the OpenAI-compatible surface only. +// Rho uses the OpenAI-compatible surface only. package zai import ( diff --git a/client/adapters/concentrate_responses.go b/client/adapters/concentrate_responses.go index ae4eb562..b1e516f4 100644 --- a/client/adapters/concentrate_responses.go +++ b/client/adapters/concentrate_responses.go @@ -329,7 +329,7 @@ func (c *ConcentrateResponsesClient) buildRequest(messages []core.FluxMessage, o if err := json.Unmarshal([]byte(opts.ResponseFormat.Schema), &schema); err != nil { return responsesRequest{}, fmt.Errorf("concentrate: invalid response schema: %w", err) } - format["name"] = "hawk_response" + format["name"] = "rho_response" format["schema"] = schema } req.Text = &responsesTextConfig{Format: format} diff --git a/client/adapters/concentrate_responses_test.go b/client/adapters/concentrate_responses_test.go index a1156acc..516953c5 100644 --- a/client/adapters/concentrate_responses_test.go +++ b/client/adapters/concentrate_responses_test.go @@ -170,7 +170,7 @@ func TestConcentrateResponsesClient_StructuredOutputUsesTextFormat(t *testing.T) if req.Text == nil || req.Text.Format["type"] != "json_schema" { t.Fatalf("text format = %#v", req.Text) } - if req.Text.Format["name"] != "hawk_response" { + if req.Text.Format["name"] != "rho_response" { t.Fatalf("schema name = %#v", req.Text.Format["name"]) } if _, ok := req.Text.Format["schema"].(map[string]interface{}); !ok { diff --git a/client/adapters/poolside.go b/client/adapters/poolside.go index b9a3d7cc..c97bb583 100644 --- a/client/adapters/poolside.go +++ b/client/adapters/poolside.go @@ -42,7 +42,7 @@ func (c *PoolsideClient) StreamChat(ctx context.Context, messages []core.FluxMes } func (c *PoolsideClient) reasoningOnlyFallbackChat(ctx context.Context, messages []core.FluxMessage, opts core.ChatOptions) (*core.FluxResponse, error) { - // A Laguna stream can exhaust itself in reasoning when Hawk's large tool + // A Laguna stream can exhaust itself in reasoning when Rho's large tool // catalog is attached. Preserve tools on the primary request, but make the // one-shot recovery text-only so the model emits its final answer. opts.Tools = nil diff --git a/client/continuation.go b/client/continuation.go index 297514f7..f45af06a 100644 --- a/client/continuation.go +++ b/client/continuation.go @@ -89,7 +89,7 @@ func ChatWithContinuation(ctx context.Context, p Provider, messages []FluxMessag // It returns a StreamResult whose Events channel transparently continues across // multiple LLM calls, emitting a "continuation" event at each boundary. // -// DEPRECATION NOTE: hawk's Session loop has its own max_tokens recovery +// DEPRECATION NOTE: rho's Session loop has its own max_tokens recovery // (internal/engine/stream.go around the `recoveryCount` loop) that doesn't // add a synthetic "Continue." user message, and the flux conversation // engine (flux/conversation.Engine) has its own OutputGroupID-based @@ -97,7 +97,7 @@ func ChatWithContinuation(ctx context.Context, p Provider, messages []FluxMessag // conversation shapes (no synthetic user turns) and are the recommended // pattern for new code. This client-level helper remains for // backwards-compatibility with the embedded flux HTTP server and -// non-hawk consumers; new code should implement continuation at the +// non-rho consumers; new code should implement continuation at the // engine or call-site level instead. // // Will be removed in flux v0.3.0. See flux/CHANGELOG.md for the diff --git a/client/core/image.go b/client/core/image.go index 3498dd93..20b9a7ce 100644 --- a/client/core/image.go +++ b/client/core/image.go @@ -37,7 +37,7 @@ var extToMediaType = map[string]string{ // encoded → (mediaType, data, true) // // It is the single entry point for image handling so the provider clients and -// hawk no longer each carry their own divergent encoder. Local files and +// rho no longer each carry their own divergent encoder. Local files and // data-URLs are validated against supportedImageMediaTypes; HTTP URLs are left // for the provider to fetch (avoiding an SSRF surface inside flux). func NormalizeImageSource(src string) (mediaType, data string, isBase64 bool, err error) { diff --git a/client/extract.go b/client/extract.go index 5db26d07..7382932a 100644 --- a/client/extract.go +++ b/client/extract.go @@ -76,8 +76,8 @@ Rules: // ExtractRelationships extracts subject-predicate-object triples from text using // schema-validated structured output with retry. It is a typed convenience layer -// over ChatWithStructuredOutput, modeled on CocoIndex's ExtractByLlm; Harrier and -// other knowledge-graph consumers can call it instead of hand-rolling extraction +// over ChatWithStructuredOutput, modeled on CocoIndex's ExtractByLlm; +// knowledge-graph consumers can call it instead of hand-rolling extraction // prompts and JSON parsing. func (c *FluxClient) ExtractRelationships(ctx context.Context, text string, opts ExtractOptions) ([]Relationship, error) { if strings.TrimSpace(text) == "" { diff --git a/client/extract_test.go b/client/extract_test.go index 8a0933f4..8d620ab2 100644 --- a/client/extract_test.go +++ b/client/extract_test.go @@ -8,7 +8,7 @@ import ( func TestFilterRelationships_DropsEmpty(t *testing.T) { t.Parallel() in := []Relationship{ - {Subject: "flux", Predicate: "part_of", Object: "hawk-eco"}, + {Subject: "flux", Predicate: "part_of", Object: "rho-eco"}, {Subject: "", Predicate: "x", Object: "y"}, // empty subject {Subject: "a", Predicate: " ", Object: "b"}, // blank predicate {Subject: "c", Predicate: "rel", Object: ""}, // empty object diff --git a/client/media.go b/client/media.go index 32f1490d..9a714fab 100644 --- a/client/media.go +++ b/client/media.go @@ -17,7 +17,7 @@ import ( // // These are provider-agnostic backends for the two well-defined, broadly // supported public APIs (OpenAI Images: POST /v1/images/generations; OpenAI -// Audio: POST /v1/audio/transcriptions). They give hawk's pluggable +// Audio: POST /v1/audio/transcriptions). They give rho's pluggable // MediaEngine / Transcriber seams a concrete default backend while staying // testable against an httptest server. A future provider (xAI image-gen, // etc.) can replace the endpoint/credentials without touching callers. diff --git a/client/token_utils.go b/client/token_utils.go index e3ccf9e5..0344555c 100644 --- a/client/token_utils.go +++ b/client/token_utils.go @@ -75,7 +75,7 @@ func fallbackTokenCount(text string) int { } // compressForSummary keeps PromptOptimizer self-contained. It performs a small -// whitespace-normalizing reduction instead of depending on shrike's full pipeline. +// whitespace-normalizing reduction instead of depending on a full tokenizer pipeline. func compressForSummary(text string) string { text = strings.TrimSpace(text) if text == "" { diff --git a/config/category.go b/config/category.go index baf1d965..e4b4a057 100644 --- a/config/category.go +++ b/config/category.go @@ -99,7 +99,7 @@ func DefaultCategories() map[ModelCategory]CategoryConfig { } // GetCategoryRegistry returns the global category registry. -// It loads overrides from Hawk user config if present. +// It loads overrides from Rho user config if present. func GetCategoryRegistry() *CategoryRegistry { registryOnce.Do(func() { globalRegistry = &CategoryRegistry{ diff --git a/config/discovery_env.go b/config/discovery_env.go index a07b4bc2..e3aeefae 100644 --- a/config/discovery_env.go +++ b/config/discovery_env.go @@ -11,7 +11,7 @@ import ( ) // DiscoveryCredentials loads API keys from the OS secret store (not process env or .env files), -// merged with non-secret routing from ~/.hawk/provider.json (e.g. MiMo Token Plan region/base URL). +// merged with non-secret routing from ~/.rho/provider.json (e.g. MiMo Token Plan region/base URL). func DiscoveryCredentials(ctx context.Context) catalog.Credentials { if ctx == nil { ctx = context.Background() diff --git a/config/provider_env.go b/config/provider_env.go index b1f5b950..fe918525 100644 --- a/config/provider_env.go +++ b/config/provider_env.go @@ -13,7 +13,7 @@ import ( "github.com/GrayCodeAI/flux/catalog/registry" ) -// ProviderConfig mirrors the Hawk provider.json file. +// ProviderConfig mirrors the Rho provider.json file. type ProviderConfig struct { ConfigVersion int `json:"config_version,omitempty"` Version string `json:"_version,omitempty"` diff --git a/config/routing_build.go b/config/routing_build.go index c778a0c3..c7a5f8ad 100644 --- a/config/routing_build.go +++ b/config/routing_build.go @@ -5,7 +5,7 @@ import ( ) // BuildRoutingPolicyFromDeployments builds deployment routing from configured deployments. -// Hawk should not author routing rules — consume this JSON from flux only. +// Rho should not author routing rules — consume this JSON from flux only. func BuildRoutingPolicyFromDeployments(deployments map[string]DeploymentConfig) *RoutingPolicy { if len(deployments) == 0 { return &RoutingPolicy{} @@ -109,7 +109,7 @@ func longcatProviderStages(deployments map[string]DeploymentConfig) []RoutingSta return nil } // Single OpenAI-compatible endpoint only (longcat-direct). - // Official LongCat also documents /anthropic; hawk does not require it when OpenAI works. + // Official LongCat also documents /anthropic; rho does not require it when OpenAI works. return singleDeploymentStages("longcat-direct", 1) } diff --git a/credentials/combined_test.go b/credentials/combined_test.go index 860ad3dd..484709b3 100644 --- a/credentials/combined_test.go +++ b/credentials/combined_test.go @@ -29,11 +29,11 @@ func TestCombinedStore_WritesKeychainOnly(t *testing.T) { func TestMigrateEnvFileCredentials(t *testing.T) { dir := t.TempDir() t.Setenv("HOME", dir) - hawkDir := filepath.Join(dir, ".hawk") - if err := os.MkdirAll(hawkDir, 0o700); err != nil { + rhoDir := filepath.Join(dir, ".rho") + if err := os.MkdirAll(rhoDir, 0o700); err != nil { t.Fatal(err) } - envPath := filepath.Join(hawkDir, "env") + envPath := filepath.Join(rhoDir, "env") if err := os.WriteFile(envPath, []byte("export ANTHROPIC_API_KEY=sk-ant-test\n"), 0o600); err != nil { t.Fatal(err) } @@ -47,7 +47,7 @@ func TestMigrateEnvFileCredentials(t *testing.T) { t.Fatalf("migrated = %d, want 1", n) } if _, err := os.Stat(envPath); !os.IsNotExist(err) { - t.Fatal("old ~/.hawk/env should be removed after migration") + t.Fatal("old ~/.rho/env should be removed after migration") } store := NewCombinedStore() got, err := store.Get(ctx, AccountForEnv("ANTHROPIC_API_KEY")) diff --git a/credentials/health.go b/credentials/health.go index bb4b975c..8da588d7 100644 --- a/credentials/health.go +++ b/credentials/health.go @@ -30,9 +30,9 @@ func KeychainWriteAvailable(ctx context.Context) (ok bool, detail string) { if !okStore || cs.Keychain == nil { return false, PlatformSecretStoreName() + " unavailable" } - if err := cs.Keychain.Set(ctx, "___hawk_write_probe___", "probe"); err != nil { + if err := cs.Keychain.Set(ctx, "___rho_write_probe___", "probe"); err != nil { return false, err.Error() } - _ = cs.Keychain.Delete(ctx, "___hawk_write_probe___") + _ = cs.Keychain.Delete(ctx, "___rho_write_probe___") return true, PlatformSecretStoreName() + " writable" } diff --git a/credentials/migrate.go b/credentials/migrate.go index a0c2b3cc..233f40d5 100644 --- a/credentials/migrate.go +++ b/credentials/migrate.go @@ -11,7 +11,7 @@ import ( // once. The marker file name is stable so upgraded installs do not re-import. func envFileMigrationMarkerPath() string { home, _ := os.UserHomeDir() - return filepath.Join(home, ".hawk", ".legacy-env-migrated") + return filepath.Join(home, ".rho", ".legacy-env-migrated") } func envFileMigrationDone() bool { @@ -25,7 +25,7 @@ func markEnvFileMigrationDone() { } // MigrateEnvFileCredentials imports API keys from plaintext credential files -// (~/.hawk/env, ~/.hawk/.env) into the OS secret store and removes them. +// (~/.rho/env, ~/.rho/.env) into the OS secret store and removes them. func MigrateEnvFileCredentials(ctx context.Context) (int, error) { if ctx == nil { ctx = context.Background() @@ -34,7 +34,7 @@ func MigrateEnvFileCredentials(ctx context.Context) (int, error) { return 0, nil } total := 0 - for _, path := range []string{hawkEnvPath(), hawkDotEnvPath()} { + for _, path := range []string{rhoEnvPath(), rhoDotEnvPath()} { n, err := migrateEnvFileAt(ctx, path) if err != nil && !os.IsNotExist(err) { return total, err @@ -83,18 +83,18 @@ func migrateEnvFileAt(ctx context.Context, path string) (int, error) { return migrated, nil } -func hawkEnvPath() string { +func rhoEnvPath() string { home, _ := os.UserHomeDir() - return filepath.Join(home, ".hawk", "env") + return filepath.Join(home, ".rho", "env") } -func hawkDotEnvPath() string { +func rhoDotEnvPath() string { home, _ := os.UserHomeDir() - return filepath.Join(home, ".hawk", ".env") + return filepath.Join(home, ".rho", ".env") } func readEnvFile(path string) (map[string]string, error) { - data, err := os.ReadFile(path) // #nosec G304 -- path is built from os.UserHomeDir() in hawkDotEnvPath, not untrusted input + data, err := os.ReadFile(path) // #nosec G304 -- path is built from os.UserHomeDir() in rhoDotEnvPath, not untrusted input if err != nil { return nil, err } diff --git a/credentials/migrate_test.go b/credentials/migrate_test.go index 7fa6e780..d02887e0 100644 --- a/credentials/migrate_test.go +++ b/credentials/migrate_test.go @@ -278,14 +278,14 @@ func TestMigrateEnvFileCredentials_BothPaths(t *testing.T) { dir := t.TempDir() t.Setenv("HOME", dir) - hawkDir := filepath.Join(dir, ".hawk") - if err := os.MkdirAll(hawkDir, 0o700); err != nil { + rhoDir := filepath.Join(dir, ".rho") + if err := os.MkdirAll(rhoDir, 0o700); err != nil { t.Fatal(err) } // Write both env files. - envPath := filepath.Join(hawkDir, "env") - dotEnvPath := filepath.Join(hawkDir, ".env") + envPath := filepath.Join(rhoDir, "env") + dotEnvPath := filepath.Join(rhoDir, ".env") if err := os.WriteFile(envPath, []byte("ANTHROPIC_API_KEY=sk-from-env\n"), 0o600); err != nil { t.Fatal(err) } @@ -304,10 +304,10 @@ func TestMigrateEnvFileCredentials_BothPaths(t *testing.T) { // Both files should be removed. if _, err := os.Stat(envPath); !os.IsNotExist(err) { - t.Error("~/.hawk/env should be removed") + t.Error("~/.rho/env should be removed") } if _, err := os.Stat(dotEnvPath); !os.IsNotExist(err) { - t.Error("~/.hawk/.env should be removed") + t.Error("~/.rho/.env should be removed") } } diff --git a/credentials/platform.go b/credentials/platform.go index 625f66a8..1fe5d837 100644 --- a/credentials/platform.go +++ b/credentials/platform.go @@ -26,7 +26,7 @@ func KeyringUnavailableHelp() string { return "install and unlock a Secret Service provider (e.g. gnome-keyring or KWallet). " + "Ensure DBUS_SESSION_BUS_ADDRESS is set in your shell; on headless systems run: eval $(gnome-keyring-daemon --start --components=secrets)" case "darwin": - return "allow Keychain access when macOS prompts for Hawk" + return "allow Keychain access when macOS prompts for Rho" case "windows": return "ensure Windows Credential Manager is available" default: diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index ac1ce063..7b53971a 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -14,9 +14,9 @@ ## target Overview -flux is the LLM provider runtime for the hawk ecosystem. It sits between the application and LLM APIs, handling **authentication**, **model resolution**, **streaming**, **retries**, **rate limiting**, and **caching**. +flux is the LLM provider runtime for the rho ecosystem. It sits between the application and LLM APIs, handling **authentication**, **model resolution**, **streaming**, **retries**, **rate limiting**, and **caching**. -> lightbulb No hawk ecosystem component talks to an LLM API directly — all communication goes through flux. +> lightbulb No rho ecosystem component talks to an LLM API directly — all communication goes through flux. --- diff --git a/docs/architecture/HOST-ENGINE-BOUNDARY.md b/docs/architecture/HOST-ENGINE-BOUNDARY.md index d935306f..a7bb1dba 100644 --- a/docs/architecture/HOST-ENGINE-BOUNDARY.md +++ b/docs/architecture/HOST-ENGINE-BOUNDARY.md @@ -5,7 +5,7 @@ Status: accepted. The host-facing compatibility contract is ## Decision -Hawk is the product face. It owns the terminal UI, agent loop, tool execution, +Rho is the product face. It owns the terminal UI, agent loop, tool execution, permissions, conversation history, checkpoints, and product semantics. Flux is the engine. It owns credentials, provider/deployment metadata, model discovery, catalog compilation, selection, transport construction, provider request and @@ -15,7 +15,7 @@ stream normalization, resilience, normalized usage, and provider telemetry. User | v -Hawk (face: UX, session, tools, permissions) +Rho (face: UX, session, tools, permissions) | | stable DTOs and methods v @@ -30,14 +30,14 @@ github.com/GrayCodeAI/flux/engine [contract v2] Provider model APIs ``` -The dependency is one-way: Flux must not import Hawk. Hawk's integration layer -may import `flux/engine`; Hawk command, conversation, and UI packages must not +The dependency is one-way: Flux must not import Rho. Rho's integration layer +may import `flux/engine`; Rho command, conversation, and UI packages must not assemble Flux's `catalog`, `client`, `config`, `credentials`, `router`, `runtime`, or `setup` packages. ## Composition root -Hawk constructs one `engine.Engine` from host-owned dependencies: +Rho constructs one `engine.Engine` from host-owned dependencies: ```go e, err := engine.New(engine.Options{ @@ -53,7 +53,7 @@ e, err := engine.New(engine.Options{ `StateDir` derives `model_catalog.json` and `provider.json` when explicit paths are absent. Explicit paths win. The store, paths, remote catalog URL, and custom gateways belong to the Engine instance; production behavior does not depend on -ambient Hawk paths or a process-global custom-gateway registry. The global +ambient Rho paths or a process-global custom-gateway registry. The global registry remains an opt-in compatibility path through `UseRegisteredCustomGateways`. @@ -77,7 +77,7 @@ MigrateProviderSecretsContext Provider-specific wire types, authentication headers, retry behavior, and raw stream events do not cross this boundary. `Model` keeps distinct `Owner`, `ProviderID`, `GatewayID`, `CanonicalID`, `Source`, and `LiveMetadata` fields so -Hawk does not reconstruct catalog meaning. +Rho does not reconstruct catalog meaning. ## Credential-to-conversation flow @@ -98,10 +98,10 @@ Engine.ApplyCredentials / ListLiveModels +--> pass a provider-scoped environment to its live fetcher +--> merge/compile catalog and atomically update model_catalog.json v -Engine.ListModels --> Hawk picker --> Engine.SetSelection +Engine.ListModels --> Rho picker --> Engine.SetSelection | v -Hawk builds provider-neutral GenerateRequest from its conversation +Rho builds provider-neutral GenerateRequest from its conversation | +--> Engine.Generate `--> Engine.Stream --> normalized route/content/thinking/tool/usage events @@ -125,7 +125,7 @@ Legacy provider files may contain credential-shaped fields. The explicit `MigrateProviderSecretsContext` flow maps every recognized secret to the injected store before writing a sanitized provider file. An unmapped secret or store failure aborts the migration and restores the original state; no -plaintext backup is created. Hawk should run security status/migration before +plaintext backup is created. Rho should run security status/migration before normal provider-state writes. ## Selection and generation @@ -136,10 +136,10 @@ explicit model is a hard constraint unless the host enables fallback. Flux owns canonicalization, gateway ownership, deployment routing, and capability matching. -Flux generation is stateless from Hawk's point of view: +Flux generation is stateless from Rho's point of view: ```text -Hawk owns Flux owns +Rho owns Flux owns ---------- ----------- conversation history route decision tool permission and execution provider transport @@ -151,7 +151,7 @@ session lifecycle normalized usage/telemetry `Stream` is pull-based, cancellable, and must be closed. It emits the selected route before provider events and normalizes content, thinking, tool calls, usage, retry/continuation, TTFT, and completion. Unknown future event types are -additive and must be ignored safely. Flux emits tool requests; Hawk authorizes +additive and must be ignored safely. Flux emits tool requests; Rho authorizes and executes tools, appends results to its history, and begins the next model turn. @@ -176,20 +176,20 @@ The boundary is delivered Flux-first: ```text 1. Change and verify standalone Flux 2. Commit Flux and publish a resolvable release/commit -3. Update Hawk's Flux module version when required -4. Update Hawk's Flux module pin to that exact published commit -5. Verify Hawk integration, boundary checks, and clean-clone/module builds -6. Commit the Hawk module-pin update in Hawk's repository +3. Update Rho's Flux module version when required +4. Update Rho's Flux module pin to that exact published commit +5. Verify Rho integration, boundary checks, and clean-clone/module builds +6. Commit the Rho module-pin update in Rho's repository ``` -Hawk must never depend on an uncommitted Flux worktree. The parent workspace +Rho must never depend on an uncommitted Flux worktree. The parent workspace uses a sibling checkout for source identity during local development; a resolvable published module version is also required for workflows that build -Hawk with `GOWORK=off`. +Rho with `GOWORK=off`. ## Compatibility policy -Lower-level Flux packages remain public for non-Hawk consumers and staged -migration, but they are not part of Hawk's product boundary. Additive fields +Lower-level Flux packages remain public for non-Rho consumers and staged +migration, but they are not part of Rho's product boundary. Additive fields and stream events are allowed within contract v2. Removing or changing stable DTO semantics requires a contract-version and semantic-version boundary. diff --git a/docs/design/FLUX-ENTERPRISE.md b/docs/design/FLUX-ENTERPRISE.md index 7860ed97..d61d70c5 100644 --- a/docs/design/FLUX-ENTERPRISE.md +++ b/docs/design/FLUX-ENTERPRISE.md @@ -58,7 +58,7 @@ it is treated here as a multi-month effort. ("run prompt vX against models A/B/C"). 5. **Canary / blue-green model testing** promoted from the existing weighted/preview routing primitives into a named, observable production-traffic flow. -6. **A2A protocol** so hawk agents can call external agents (LangGraph, Vertex Agent Engine, +6. **A2A protocol** so rho agents can call external agents (LangGraph, Vertex Agent Engine, Azure AI Foundry, Bedrock AgentCore) as tool calls through the flux proxy. 7. **Fine-tuning workflow client** that submits training data, polls jobs, and registers the resulting model in flux's catalog. @@ -75,7 +75,7 @@ it is treated here as a multi-month effort. (the existing `internal/grpc/README.md` policy of not adding `google.golang.org/grpc` speculatively is preserved). - **No model training** — only orchestration of provider-side fine-tuning APIs. -- The browser/IDE/cloud-execution gaps belong to hawk, not this doc. +- The browser/IDE/cloud-execution gaps belong to rho, not this doc. --- @@ -372,7 +372,7 @@ Exit: full enterprise parity with LiteLLM/Portkey gateway feature set per the co | Redis (distributed state, priority across instances) | **Adopt opt-in** `redis/go-redis` (BSD-2) | Behind interface; not default. | | gRPC | **Defer** — keep skeleton, do not add `google.golang.org/grpc` until demanded | Per `internal/grpc/README.md` policy. | -**Licensing:** flux is MIT (`LICENSE`, "Copyright (c) 2026 Hawk Contributors"). All proposed +**Licensing:** flux is MIT (`LICENSE`, "Copyright (c) 2026 Rho Contributors"). All proposed default deps (SQLite, go-keyring, OTel, uuid) are already MIT/BSD/Apache-2.0 (`go.mod`). Any opt-in adds (go-oidc Apache-2.0, pgx MIT, go-redis BSD) are MIT-compatible. **No GPL/AGPL.** A UI build toolchain (Vite/esbuild, MIT) is a dev-time dependency only — it does not ship in the diff --git a/docs/guides/CREDENTIAL-SETUP-FLOW.md b/docs/guides/CREDENTIAL-SETUP-FLOW.md index 84b4a015..c999d485 100644 --- a/docs/guides/CREDENTIAL-SETUP-FLOW.md +++ b/docs/guides/CREDENTIAL-SETUP-FLOW.md @@ -1,6 +1,6 @@ -# Credential setup: hawk (face) + flux (brain) +# Credential setup: rho (face) + flux (brain) -**Principle:** Hawk renders UI only. Flux owns providers, keys, validation, catalog, models. +**Principle:** Rho renders UI only. Flux owns providers, keys, validation, catalog, models. See also: [DYNAMIC-MODEL-DISCOVERY.md](./DYNAMIC-MODEL-DISCOVERY.md) @@ -35,7 +35,7 @@ MiMo exposes **OpenAI-compatible** and **Anthropic-compatible** APIs on the same | Pay-as-you-go | `xiaomi_mimo_payg` | `XIAOMI_MIMO_PAYG_API_KEY` | `sk-*` | `https://api.xiaomimimo.com/v1` | `https://api.xiaomimimo.com/anthropic` | | Token Plan | `xiaomi_mimo_token_plan` | `XIAOMI_MIMO_TOKEN_PLAN_API_KEY` | `tp-*` | `https://token-plan-{cn,sgp,ams}.xiaomimimo.com/v1` | `https://token-plan-{cn,sgp,ams}.xiaomimimo.com/anthropic` | -Token Plan region (`cn`, `sgp`, `ams`) is stored in `~/.hawk/provider.json` as `xiaomi_mimo_token_plan_region`. Hawk `/config` prompts for region before key paste on the Token Plan row. +Token Plan region (`cn`, `sgp`, `ams`) is stored in `~/.rho/provider.json` as `xiaomi_mimo_token_plan_region`. Rho `/config` prompts for region before key paste on the Token Plan row. **Auth:** `api-key` header on probe, live fetch, and chat; OpenAI paths also retry once with `Authorization: Bearer` on HTTP 401 (per [OpenAI API](https://platform.xiaomimimo.com/docs/en-US/api/chat/openai-api)). @@ -50,7 +50,7 @@ Flux stores Anthropic **base** as `…/anthropic` (no `/v1`); `AnthropicClient` **Legacy:** `xiaomi_mimo` / `XIAOMI_MIMO_API_KEY` / keychain account `xiaomi_mimo_api_key` migrate to pay-as-you-go (`XIAOMI_MIMO_PAYG_API_KEY` / `xiaomi_mimo_payg_api_key`) on load and startup. -**Code:** `flux/catalog/xiaomi/` (URLs), `flux/client/mimo.go` (dual-protocol client), `hawk/cmd/chat_config_region.go` (region UI). +**Code:** `flux/catalog/xiaomi/` (URLs), `flux/client/mimo.go` (dual-protocol client), `rho/cmd/chat_config_region.go` (region UI). **Not implemented (out of scope):** ASR/TTS ([Speech Recognition](https://platform.xiaomimimo.com/docs/en-US/api/audio/Speech-Recognition), speech synthesis guides), web-search billing plugins, user toggle for Anthropic-primary routing. @@ -69,7 +69,7 @@ Setup is **gateway-first**: pick the gateway on the Gateways tab, paste any non- → Pick model → ListModels (auto) when credentials exist ``` -## Host API (hawk uses `internal/fluxclient` only) +## Host API (rho uses `internal/fluxclient` only) - `ResolveCredentialForHost` / `SaveCredentialForHost` - `ApplyFluxCredentials` @@ -82,4 +82,4 @@ Setup is **gateway-first**: pick the gateway on the Gateways tab, paste any non- 1. Add one `ProviderSpec` row in `catalog/registry/providers.go` 2. Implement fetcher in `catalog/live/fetchers.go` and register in `Registry` 3. Add deployment row to remote catalog JSON (metadata only; picker uses live list) -4. No hawk changes (registry-driven `/config`) +4. No rho changes (registry-driven `/config`) diff --git a/docs/guides/DYNAMIC-MODEL-DISCOVERY.md b/docs/guides/DYNAMIC-MODEL-DISCOVERY.md index 3888b2bd..19e0e155 100644 --- a/docs/guides/DYNAMIC-MODEL-DISCOVERY.md +++ b/docs/guides/DYNAMIC-MODEL-DISCOVERY.md @@ -2,13 +2,13 @@ Status: implemented through the `flux/engine` contract v2. -This guide describes the host-facing path used by Hawk. Hawk is the face; Flux +This guide describes the host-facing path used by Rho. Rho is the face; Flux is the engine and source of truth for provider metadata, credentials, live model discovery, catalog compilation, selection, and provider transport. ## Ownership -| Hawk owns | Flux owns | +| Rho owns | Flux owns | |---|---| | credential and model-picker UX | safe credential resolution and persistence | | conversation/session state | provider registry and deployment metadata | @@ -17,17 +17,17 @@ model discovery, catalog compilation, selection, and provider transport. | product settings and lifecycle | model ownership, aliases, selection, and routing | | normalized request construction | provider adapters, streams, usage, and errors | -Hawk calls its integration wrapper, which delegates to `flux/engine`. Hawk UI, +Rho calls its integration wrapper, which delegates to `flux/engine`. Rho UI, command, and conversation packages do not call Flux's lower-level runtime or client packages. ## End-to-end path ```text -User enters API key or custom-gateway settings in Hawk +User enters API key or custom-gateway settings in Rho | v -Hawk integration --> Engine.ResolveCredential +Rho integration --> Engine.ResolveCredential | v Engine.SaveCredential @@ -47,10 +47,10 @@ Engine.ApplyCredentials / Engine.ListLiveModels `--> atomically compile the injected catalog path | v -Engine.ListModels --> Hawk picker --> Engine.SetSelection +Engine.ListModels --> Rho picker --> Engine.SetSelection | v -Hawk conversation --> Engine.Generate or Engine.Stream --> provider API +Rho conversation --> Engine.Generate or Engine.Stream --> provider API | `--> normalized route, content, thinking, tool-call, usage, and done events ``` @@ -61,7 +61,7 @@ exist in the same store. ## Engine construction and isolation -Create the Engine once at Hawk's composition root and inject all host-owned +Create the Engine once at Rho's composition root and inject all host-owned state: ```go @@ -116,7 +116,7 @@ The stable model DTO intentionally distinguishes: - `GatewayID`: selected/listed gateway or deployment identity. - `Source` and `LiveMetadata`: origin and provider-native metadata. -Hawk should render these fields; it should not infer ownership from model-name +Rho should render these fields; it should not infer ownership from model-name prefixes or parse raw provider responses. ## Provider registry @@ -134,7 +134,7 @@ ProviderSpec Provider-specific HTTP parsing remains inside registered fetchers/adapters. Adding a built-in provider should normally require registry data, its adapter -or live fetcher, and tests—not new branches in Hawk UI code. +or live fetcher, and tests—not new branches in Rho UI code. Custom OpenAI-compatible gateways are invocation-scoped Engine options rather than registry mutations. Their URLs must be HTTP(S) with a host and must not @@ -181,14 +181,14 @@ failed live response is not silently represented as successful live readiness. ## Selection and conversation handoff -Hawk persists a choice through `Engine.SetSelection(provider, model)`. Flux +Rho persists a choice through `Engine.SetSelection(provider, model)`. Flux validates provider/model ownership, preserves custom model IDs, canonicalizes built-in aliases, and stores routing metadata at the injected provider path. -At generation time Hawk passes provider-neutral messages, tools, +At generation time Rho passes provider-neutral messages, tools, requirements, preferences, limits, and metadata. `Resolve`, `Generate`, and `Stream` use the same Engine-owned catalog, provider state, credentials, and -custom-gateway snapshot. Hawk neither constructs a provider client nor exports +custom-gateway snapshot. Rho neither constructs a provider client nor exports credentials into the process environment. ## Local and live preflight @@ -211,7 +211,7 @@ Live (VerifyLive=true) Local preflight is safe for normal startup and offline diagnostics. Live preflight is an explicit network check and should be labeled accordingly in -Hawk. +Rho. ## State and secret safety @@ -230,7 +230,7 @@ Engine provider-state mutations: `MigrateProviderSecretsContext` is the explicit legacy migration. If mapping or store persistence fails, it aborts and restores the original provider state. -Hawk diagnostics can use `ProviderStateSecurityStatus`, `CatalogHealth`, and +Rho diagnostics can use `ProviderStateSecurityStatus`, `CatalogHealth`, and the safe credential/gateway reports without reading either file directly. ## Failure handling @@ -246,26 +246,26 @@ the safe credential/gateway reports without reading either file directly. | custom gateway URL contains embedded data | reject configuration | | stream caller exits | close/cancel the Engine stream | -Provider-specific friendly error formatting remains Flux-owned; Hawk decides +Provider-specific friendly error formatting remains Flux-owned; Rho decides where and how to display it. -## Release order for Hawk +## Release order for Rho -Flux is changed and released before Hawk advances its dependency: +Flux is changed and released before Rho advances its dependency: ```text standalone Flux change --> Flux tests (two passes) --> signed Flux commit --> publish a resolvable Flux module release/commit - --> update Hawk module dependency when needed - --> update Hawk's Flux module pin to the same published commit - --> Hawk integration + boundary + clean-clone verification (two passes) - --> commit Hawk code and gitlink together + --> update Rho module dependency when needed + --> update Rho's Flux module pin to the same published commit + --> Rho integration + boundary + clean-clone verification (two passes) + --> commit Rho code and gitlink together ``` The parent workspace must use a committed Flux checkout, never working-tree- -only code, and Hawk's module pin must resolve to that same published commit. +only code, and Rho's module pin must resolve to that same published commit. Both workspace builds and `GOWORK=off` builds must expose the same Engine contract. @@ -274,4 +274,4 @@ contract. - `docs/architecture/HOST-ENGINE-BOUNDARY.md` — ownership and compatibility policy. - `CREDENTIAL-SETUP-FLOW.md` — product setup flow. -- Hawk's dynamic-model and architecture docs — host integration and UI behavior. +- Rho's dynamic-model and architecture docs — host integration and UI behavior. diff --git a/docs/plans/fix-critical-and-high-review.md b/docs/plans/fix-critical-and-high-review.md index 0ea3a8ab..58226f26 100644 --- a/docs/plans/fix-critical-and-high-review.md +++ b/docs/plans/fix-critical-and-high-review.md @@ -22,12 +22,12 @@ ## Context -A deep code review of `flux` and `hawk` (see `docs/plans/review-2026-06-summary.md` +A deep code review of `flux` and `rho` (see `docs/plans/review-2026-06-summary.md` — to be created if you want it archived here) surfaced 7 critical and 9 high items. This plan covers **all flux items** (C1, C2, C6, C7, H1, H2, H3, H4) broken into a sequence of small, reviewable PRs. -The hawk-side companion plan lives at `../hawk/docs/plans/fix-critical-and-high-review.md`. +The rho-side companion plan lives at `../rho/docs/plans/fix-critical-and-high-review.md`. ## Scope (flux) @@ -314,7 +314,7 @@ instead of using the structured type. 2. `doWithRetry` checks `var fluxErr *FluxError; if errors.As(err, &fluxErr) { … }` instead of string-matching status codes. 3. All provider error returns flow through `formatAPIError`. -4. Public API consumers (hawk) can now use `errors.As` for typed errors. +4. Public API consumers (rho) can now use `errors.As` for typed errors. **Files**: - `client/errors.go` (extend `FluxError` with `Unwrap()`, helpers) diff --git a/engine/control_plane_test.go b/engine/control_plane_test.go index 365ad0db..5a235e03 100644 --- a/engine/control_plane_test.go +++ b/engine/control_plane_test.go @@ -50,7 +50,7 @@ func TestControlPlaneUsesInjectedCredentialStore(t *testing.T) { if eng.catalogPath != filepath.Join(filepath.Dir(eng.providerConfigPath), "model_catalog.json") { // Both paths must derive from the injected StateDir. The exact assertion - // catches accidental fallback to process-global Hawk paths. + // catches accidental fallback to process-global Rho paths. t.Fatalf("control-plane paths escaped injected state dir: catalog=%q provider=%q", eng.catalogPath, eng.providerConfigPath) } } diff --git a/engine/host_control.go b/engine/host_control.go index eac47923..757c1c49 100644 --- a/engine/host_control.go +++ b/engine/host_control.go @@ -24,7 +24,7 @@ func SecretStoreName() string { return credentials.PlatformSecretStoreName() } // SetSecretStoreServiceName overrides the OS secret-store service name (default // "flux"). Hosts call this once at startup so existing credentials filed under -// their product name (e.g. "hawk") stay readable. +// their product name (e.g. "rho") stay readable. func SetSecretStoreServiceName(name string) { credentials.SetServiceName(name) } // -- Test-fixture re‑exports ------------------------------------------------- diff --git a/internal/observability/genai_semconv.go b/internal/observability/genai_semconv.go index 4f4c4504..a7048ead 100644 --- a/internal/observability/genai_semconv.go +++ b/internal/observability/genai_semconv.go @@ -3,7 +3,7 @@ // These exported constants are the canonical, ecosystem-wide attribute keys for // describing LLM / AI agent operations. They follow the OpenTelemetry GenAI // semantic conventions (gen_ai.*) and are shared as the reference set that the -// other graycode-eco repos (hawk, harrier, shrike, swift) should mirror when emitting +// other graycode-eco repos (rho, swift) should mirror when emitting // spans, so dashboards and exporters can correlate cost/usage/identity across // the whole ecosystem. // diff --git a/internal/probehttp/probehttp.go b/internal/probehttp/probehttp.go index 3379a63e..9e644280 100644 --- a/internal/probehttp/probehttp.go +++ b/internal/probehttp/probehttp.go @@ -26,7 +26,7 @@ const DefaultRequestTimeout = 15 * time.Second var DefaultClient = &http.Client{Timeout: DefaultRequestTimeout} // ProbeError builds a credential-probe error message for a non-2xx response. -// The wording is part of the public surface that hawk surfaces to users when +// The wording is part of the public surface that rho surfaces to users when // /config probe fails, so the strings here are stable. // // status is the HTTP status code returned by the provider. The function diff --git a/lefthook.yml b/lefthook.yml index 7a981614..da4010b7 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -1,4 +1,4 @@ -# Canonical lefthook config for hawk-eco Go repos. +# Canonical lefthook config for rho-eco Go repos. # Source of truth: .shared-templates/lefthook.yml.tmpl # # Install lefthook: diff --git a/llm/provider.go b/llm/provider.go index 0b5d949c..f33431fd 100644 --- a/llm/provider.go +++ b/llm/provider.go @@ -6,9 +6,9 @@ import ( "time" ) -// Provider is hawk's hawk-owned view of the provider engine: a composition of -// the role interfaces below. It is the single integration surface — hawk never -// holds an *fluxengine.Engine, and flux never imports hawk/internal. +// Provider is rho's rho-owned view of the provider engine: a composition of +// the role interfaces below. It is the single integration surface — rho never +// holds an *fluxengine.Engine, and flux never imports rho/internal. // // Callers that need only a subset depend on the relevant role interface // directly (e.g. session_factory depends only on Generator), keeping the diff --git a/llm/types.go b/llm/types.go index d36c83b1..c0a4c5b7 100644 --- a/llm/types.go +++ b/llm/types.go @@ -1,11 +1,11 @@ -// Package llm is the canonical provider port contract for the hawk ecosystem. +// Package llm is the canonical provider port contract for the rho ecosystem. // // It is the single source of truth for the conversation DTOs and the Provider -// interface that hawk (product face) and flux (provider engine) speak across +// interface that rho (product face) and flux (provider engine) speak across // their boundary. Both sides alias to these types, so there is exactly one // definition of each DTO and no per-call conversion. // -// hawk owns the product vocabulary (hence names like FluxMessage); flux +// rho owns the product vocabulary (hence names like FluxMessage); flux // implements the port. flux's internal transport types stay flux-scoped and // never appear here. package llm diff --git a/plans/client-package-decomposition.md b/plans/client-package-decomposition.md index 618fa267..3be5759a 100644 --- a/plans/client-package-decomposition.md +++ b/plans/client-package-decomposition.md @@ -3,7 +3,7 @@ **Status:** In Progress — Phases 1–3 implemented 2026-07-13; layering guard live **Author:** Claude (architecture review session) **Date:** 2026-07-12 -**Repos affected:** flux (all changes), hawk (no code changes required; update +**Repos affected:** flux (all changes), rho (no code changes required; update the published Flux module pin) ## Problem Statement @@ -42,8 +42,8 @@ and a public API surface far larger than what consumers use. `buildAnthropicCachedRequest`, `defaultTimeout`, `emit`, `openAIImageURL`, `parseImageString`, `parseSSEStream`, `processAnthropicStream`, `processOpenAIStream`, `userAgent`. -- hawk (the primary consumer) accesses `flux/client` from **4 files only** — - it maintains its own DTO layer (`hawk/internal/types/client.go`) and converts +- rho (the primary consumer) accesses `flux/client` from **4 files only** — + it maintains its own DTO layer (`rho/internal/types/client.go`) and converts at the boundary. Entry points consumed: `Client`, `FluxClient` methods (`Chat`, `StreamChat`, `StreamChatContinue`, `SetAPIKey`, `Ping`, `GetProviders`), `StreamChatWithContinuation`, `ParseInlineToolCalls`, @@ -88,7 +88,7 @@ inside the tree. - **Big-bang rename (`client/v2`)** — breaks every consumer including examples and SDK bindings; rejected. -- **Move whole package to `internal/`** — hawk and examples import it; rejected. +- **Move whole package to `internal/`** — rho and examples import it; rejected. - **Split without a core package** (e.g., extract embeddings directly) — impossible without import cycles: subpackages need client types while the facade re-exports subpackage API. The core extraction is the unlock; everything else follows. @@ -107,7 +107,7 @@ Phase 1 is DONE (2026-07-12): adapters phase — embeddings did not need them.) - [x] In `client`, every moved name is aliased (`client/aliases.go`); internal call sites bridge through unexported vars (`doWithRetry = core.DoWithRetry`). -- [x] `go test ./...` green in flux; hawk builds + tests green. +- [x] `go test ./...` green in flux; rho builds + tests green. ### Phase 2: embeddings (smallest proven cluster, 4 deps) @@ -173,7 +173,7 @@ Learned in Phases 1–2 (apply to later phases): - [ ] One sub-move per PR, same alias recipe. ### Phase 5: enforcement + deprecation -- [x] Add `scripts/check-client-layering.sh` (mirror of hawk's +- [x] Add `scripts/check-client-layering.sh` (mirror of rho's `check-flux-client-imports.sh`) to CI: fail on any sibling→sibling import that bypasses `core`, and on any in-tree import of the facade. - [ ] Mark facade aliases `// Deprecated:` pointing at the subpackage; migrate @@ -184,9 +184,9 @@ Learned in Phases 1–2 (apply to later phases): - Unit tests: move with their files; each phase must keep `go test ./...` green with zero test-logic edits (rename-only diffs). -- Integration tests: `catalogtest` + hawk `internal/engine` suite against the +- Integration tests: `catalogtest` + rho `internal/engine` suite against the branch via `go.work` replace. -- E2E tests: `hawk path` smoke + one live streamed chat per protocol family +- E2E tests: `rho path` smoke + one live streamed chat per protocol family (anthropic-messages, openai-chat-completions, gemini-generate-content) before each merge. @@ -197,11 +197,11 @@ Learned in Phases 1–2 (apply to later phases): | Hidden unexported coupling beyond the measured sets | med | Phases are one-cluster-at-a-time; the compiler finds every missed reference at move time; abort/expand `core` rather than weaken boundaries | | Type identity breakage for consumers doing type switches | high | Use aliases (`=`), never new named types, for everything that already exists | | Method sets split from their types | high | Methods move with their receiver's file into the same subpackage — never leave methods behind | -| Flux module-pin drift in Hawk during the refactor | low | Land phases as individual PRs; update Hawk after each; `make sync` reports drift | +| Flux module-pin drift in Rho during the refactor | low | Land phases as individual PRs; update Rho after each; `make sync` reports drift | | Facade grows stale re-exports | low | Phase 5 CI check + deprecation comments | ## References -- hawk's boundary script: `hawk/scripts/check-flux-client-imports.sh` -- hawk's DTO layer (proof the consumer surface is narrow): `hawk/internal/types/client.go` -- Session decomposition precedent: `hawk/docs/session-decomposition.md` +- rho's boundary script: `rho/scripts/check-flux-client-imports.sh` +- rho's DTO layer (proof the consumer surface is narrow): `rho/internal/types/client.go` +- Session decomposition precedent: `rho/docs/session-decomposition.md` diff --git a/runtime/preflight.go b/runtime/preflight.go index f45cc816..4498637f 100644 --- a/runtime/preflight.go +++ b/runtime/preflight.go @@ -26,7 +26,7 @@ type PreflightCheck struct { Detail string `json:"detail"` } -// PreflightReport summarizes whether hawk can chat. +// PreflightReport summarizes whether rho can chat. type PreflightReport struct { Ready bool `json:"ready"` Checks []PreflightCheck `json:"checks"` @@ -45,7 +45,7 @@ func Preflight(ctx context.Context) PreflightReport { if !exists || size == 0 { checks = append(checks, PreflightCheck{ Name: "catalog", Status: PreflightWarn, - Detail: "model catalog cache missing — hawk will discover on /config or refresh automatically", + Detail: "model catalog cache missing — rho will discover on /config or refresh automatically", }) } else { compiled, err := catalog.LoadCatalog(ctx, catalog.LoadCatalogOptions{ diff --git a/runtime/runtime.go b/runtime/runtime.go index db4c0732..97e62fc1 100644 --- a/runtime/runtime.go +++ b/runtime/runtime.go @@ -1,10 +1,10 @@ // Package runtime is the **recommended entry point** for host applications -// (e.g. hawk). Start by calling runtime.Load to get a *Runtime, then +// (e.g. rho). Start by calling runtime.Load to get a *Runtime, then // rt.ChatProvider to obtain a client.Provider that you can hand to your // agent loop. // // Note: the "stable" surface of flux is actually a set of cooperating -// subpackages, not just this one. The full list hawk (and other host +// subpackages, not just this one. The full list rho (and other host // applications) actually import is: // // github.com/GrayCodeAI/flux/runtime (this package — bootstrap facade) diff --git a/scripts/check-ecosystem-boundaries.sh b/scripts/check-ecosystem-boundaries.sh index 6cf7642f..a40d9eba 100755 --- a/scripts/check-ecosystem-boundaries.sh +++ b/scripts/check-ecosystem-boundaries.sh @@ -4,27 +4,27 @@ set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$ROOT_DIR" -# Flux is host-neutral: it must not depend on any Hawk package. -# Shared ecosystem vocabulary lives in hawk/internal/contracts, which +# Flux is host-neutral: it must not depend on any Rho package. +# Shared ecosystem vocabulary lives in rho/internal/contracts, which # hosts vendor rather than import from here. -FORBIDDEN_HAWK='github\.com/GrayCodeAI/hawk(/|")' -FORBIDDEN_ENGINES='github\.com/GrayCodeAI/(harrier|shrike|swift|kestrel|merlin)(/|")' +FORBIDDEN_RHO='github\.com/GrayCodeAI/rho(/|")' +FORBIDDEN_ENGINES='github\.com/GrayCodeAI/swift(/|")' exit_code=0 if command -v rg >/dev/null 2>&1; then - violations="$(rg -n "$FORBIDDEN_HAWK" --glob '*.go' . || true)" + violations="$(rg -n "$FORBIDDEN_RHO" --glob '*.go' . || true)" engine_violations="$(rg -n "$FORBIDDEN_ENGINES" --glob '*.go' . || true)" else - violations="$(grep -rn --include='*.go' -E "$FORBIDDEN_HAWK" . || true)" + violations="$(grep -rn --include='*.go' -E "$FORBIDDEN_RHO" . || true)" engine_violations="$(grep -rn --include='*.go' -E "$FORBIDDEN_ENGINES" . || true)" fi if [[ -n "${violations}" ]]; then - echo "forbidden Hawk host imports found:" + echo "forbidden Rho host imports found:" echo "${violations}" echo - echo "flux must use local contracts, never the Hawk product module" + echo "flux must use local contracts, never the Rho product module" exit_code=1 fi diff --git a/setup/apply_credentials.go b/setup/apply_credentials.go index f5b9e064..7f15a27d 100644 --- a/setup/apply_credentials.go +++ b/setup/apply_credentials.go @@ -56,7 +56,7 @@ func ApplyCredentialsForProvider(ctx context.Context, providerID string, creds c } // ApplyCredentials discovers the model catalog from env API keys, then writes -// ~/.hawk/provider.json deployments and routing derived from the catalog. +// ~/.rho/provider.json deployments and routing derived from the catalog. func ApplyCredentials(ctx context.Context, creds catalog.Credentials) (*ApplyCredentialsResult, error) { catResult, err := DiscoverModelCatalog(ctx, creds) if err != nil { diff --git a/setup/catalog.go b/setup/catalog.go index 8753a446..8e67f510 100644 --- a/setup/catalog.go +++ b/setup/catalog.go @@ -20,7 +20,7 @@ func DiscoverModelCatalog(ctx context.Context, creds catalog.Credentials) (*cata return DiscoverModelCatalogWithOptions(ctx, creds, DiscoverModelCatalogOptions{}) } -// DiscoverModelCatalogWithOptions runs discover with optional force refresh (manual hawk models refresh). +// DiscoverModelCatalogWithOptions runs discover with optional force refresh (manual rho models refresh). func DiscoverModelCatalogWithOptions(ctx context.Context, creds catalog.Credentials, opts DiscoverModelCatalogOptions) (*catalog.RefreshResult, error) { cachePath := catalog.DefaultCachePath() refreshRemote := opts.ForceRefresh diff --git a/setup/deployment.go b/setup/deployment.go index ac249ff3..255189b1 100644 --- a/setup/deployment.go +++ b/setup/deployment.go @@ -1,4 +1,4 @@ -// Package setup wires catalog-backed deployment routing for hawk and flux CLIs. +// Package setup wires catalog-backed deployment routing for rho and flux CLIs. package setup import ( diff --git a/setup/setup_ui.go b/setup/setup_ui.go index b7851b0e..6f9f5f9f 100644 --- a/setup/setup_ui.go +++ b/setup/setup_ui.go @@ -22,7 +22,7 @@ type ProviderUI struct { Models []ModelUI `json:"models"` } -// SetupUI is JSON-safe metadata returned to hawk (no secrets). +// SetupUI is JSON-safe metadata returned to rho (no secrets). type SetupUI struct { Providers []ProviderUI `json:"providers"` } diff --git a/setup/status.go b/setup/status.go index e2729b4a..dc741edf 100644 --- a/setup/status.go +++ b/setup/status.go @@ -132,7 +132,7 @@ func FormatStatus(report StatusReport) string { fmt.Fprintf(&b, " cached: no (using embedded catalog: %d models)\n", report.CatalogModels) } if report.CatalogStale { - b.WriteString(" stale: yes — hawk refreshes automatically; use `hawk models refresh` or `/refresh-model-catalog` for a manual run\n") + b.WriteString(" stale: yes — rho refreshes automatically; use `rho models refresh` or `/refresh-model-catalog` for a manual run\n") } if report.ActiveModel != "" { fmt.Fprintf(&b, "Active canonical model: %s\n", report.ActiveModel) diff --git a/setup/status_test.go b/setup/status_test.go index af37a521..31010fbc 100644 --- a/setup/status_test.go +++ b/setup/status_test.go @@ -15,7 +15,7 @@ import ( func TestFormatStatus_DisabledRouting(t *testing.T) { report := StatusReport{ DeploymentRouting: false, - ProviderConfig: "/home/user/.hawk/provider.json", + ProviderConfig: "/home/user/.rho/provider.json", ConfigVersion: 2, Configured: []string{}, CatalogCache: "/home/user/.flux/model_catalog.json", @@ -40,7 +40,7 @@ func TestFormatStatus_DisabledRouting(t *testing.T) { func TestFormatStatus_EnabledRouting(t *testing.T) { report := StatusReport{ DeploymentRouting: true, - ProviderConfig: "/home/user/.hawk/provider.json", + ProviderConfig: "/home/user/.rho/provider.json", ConfigVersion: 2, Configured: []string{"anthropic-direct", "openai-direct"}, CatalogCache: "/home/user/.flux/model_catalog.json", @@ -71,7 +71,7 @@ func TestFormatStatus_EnabledRouting(t *testing.T) { func TestFormatStatus_StaleCatalog(t *testing.T) { report := StatusReport{ DeploymentRouting: true, - ProviderConfig: "/home/user/.hawk/provider.json", + ProviderConfig: "/home/user/.rho/provider.json", CatalogCache: "/home/user/.flux/model_catalog.json", CatalogExists: true, CatalogModified: time.Now().UTC().Add(-1 * time.Hour), @@ -86,7 +86,7 @@ func TestFormatStatus_StaleCatalog(t *testing.T) { func TestFormatStatus_ActiveModel(t *testing.T) { report := StatusReport{ DeploymentRouting: true, - ProviderConfig: "/home/user/.hawk/provider.json", + ProviderConfig: "/home/user/.rho/provider.json", CatalogCache: "/home/user/.flux/model_catalog.json", ActiveModel: "anthropic/claude-sonnet-4", RoutingSource: "model", @@ -104,7 +104,7 @@ func TestFormatStatus_ActiveModel(t *testing.T) { func TestFormatStatus_NoActiveModel(t *testing.T) { report := StatusReport{ DeploymentRouting: true, - ProviderConfig: "/home/user/.hawk/provider.json", + ProviderConfig: "/home/user/.rho/provider.json", CatalogCache: "/home/user/.flux/model_catalog.json", } out := FormatStatus(report) @@ -116,7 +116,7 @@ func TestFormatStatus_NoActiveModel(t *testing.T) { func TestFormatStatus_ConfigVersion(t *testing.T) { report := StatusReport{ DeploymentRouting: false, - ProviderConfig: "/home/user/.hawk/provider.json", + ProviderConfig: "/home/user/.rho/provider.json", ConfigVersion: 2, } out := FormatStatus(report) diff --git a/tools/versioning.go b/tools/versioning.go index 9d4f3cea..18882f08 100644 --- a/tools/versioning.go +++ b/tools/versioning.go @@ -33,7 +33,7 @@ func BehaviorPresetFrom(s string) (BehaviorPreset, error) { } // FinalizeErrorCode classifies a finalize warning or violation, mirroring the -// FINALIZE_ERROR_CODE enum in proto/hawk/contracts/v1/tool.proto. +// FINALIZE_ERROR_CODE enum in proto/rho/contracts/v1/tool.proto. type FinalizeErrorCode int const ( @@ -90,7 +90,7 @@ func (r FinalizeResult) Ok() bool { } // ToolMeta is the canonical identity envelope attached to tool-call events, -// mirroring the ToolMeta message in proto/hawk/contracts/v1/tool.proto. +// mirroring the ToolMeta message in proto/rho/contracts/v1/tool.proto. // version is an additive-only bump: new additive fields do NOT change it. type ToolMeta struct { Version string `json:"version"` @@ -102,21 +102,21 @@ type ToolMeta struct { } // ToolNamespace is a CLOSED enum identifying the harness that owns a tool, -// mirroring the ToolNamespace enum in proto/hawk/contracts/v1/tool.proto. A new +// mirroring the ToolNamespace enum in proto/rho/contracts/v1/tool.proto. A new // unknown namespace is a wire-breaking change that intentionally fails // ToolNamespaceFrom (forward-safety): a deploy that rolls the contract forward // before the consumer code cannot silently mis-route a tool it doesn't -// understand. ToolNamespaceAcp is reserved for the forthcoming hawk-acp repo. +// understand. ToolNamespaceAcp is reserved for the forthcoming rho-acp repo. type ToolNamespace string const ( - ToolNamespaceUnspecified ToolNamespace = "" // unspecified - ToolNamespaceHawkBuild ToolNamespace = "hawk_build" // hawk - ToolNamespaceHawkBuildConcise ToolNamespace = "hawk_build_concise" - ToolNamespaceCodex ToolNamespace = "codex" // codex harness - ToolNamespaceOpencode ToolNamespace = "opencode" // opencode harness - ToolNamespaceMcp ToolNamespace = "mcp" // MCP servers (falcon) - ToolNamespaceAcp ToolNamespace = "acp" // reserved: hawk-acp + ToolNamespaceUnspecified ToolNamespace = "" // unspecified + ToolNamespaceRhoBuild ToolNamespace = "rho_build" // rho + ToolNamespaceRhoBuildConcise ToolNamespace = "rho_build_concise" + ToolNamespaceCodex ToolNamespace = "codex" // codex harness + ToolNamespaceOpencode ToolNamespace = "opencode" // opencode harness + ToolNamespaceMcp ToolNamespace = "mcp" // MCP servers (falcon) + ToolNamespaceAcp ToolNamespace = "acp" // reserved: rho-acp ) // ToolNamespaceFrom parses a namespace string into a ToolNamespace. The set is @@ -125,8 +125,8 @@ const ( // typed deserialization (see the closed-enum forward-safety rule above). func ToolNamespaceFrom(s string) (ToolNamespace, error) { switch ToolNamespace(s) { - case ToolNamespaceUnspecified, ToolNamespaceHawkBuild, - ToolNamespaceHawkBuildConcise, ToolNamespaceCodex, + case ToolNamespaceUnspecified, ToolNamespaceRhoBuild, + ToolNamespaceRhoBuildConcise, ToolNamespaceCodex, ToolNamespaceOpencode, ToolNamespaceMcp, ToolNamespaceAcp: return ToolNamespace(s), nil default: diff --git a/verify/cases.go b/verify/cases.go index fbddb61e..b71e8163 100644 --- a/verify/cases.go +++ b/verify/cases.go @@ -2,7 +2,7 @@ package verify import "github.com/GrayCodeAI/flux/client" -// CanonicalCases is a small, provider-neutral suite covering the behaviors hawk +// CanonicalCases is a small, provider-neutral suite covering the behaviors rho // depends on: basic chat, deterministic content, and tool calling with valid // arguments. It is intentionally minimal so it is cheap to run against a live // endpoint; extend it per provider as needed.