This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Orbit Code is the terminal-based coding agent for the Orbit ecosystem. A fork of OpenAI's Codex CLI, rebuilt to connect to the Orbit backend. Rich TUI for AI-powered coding directly from the terminal.
Parent project: Orbit — AI-native desktop IDE This repo: Orbit Code — Terminal agent
Keep docs/tracked/orbit-code-roadmap.md up to date. Whenever a new feature is added, a bug is fixed, or work moves between stages, update the kanban table in that file. Move items from Todo → Done or add new items to the appropriate column. This is the single source of truth for what's shipped, in progress, and planned.
| Directory | Purpose |
|---|---|
codex-rs/ |
Primary codebase — Rust implementation (67+ crates) |
codex-cli/ |
npm wrapper — thin JS launcher resolving platform-specific Rust binaries |
sdk/ |
Client SDKs (Python + TypeScript) for programmatic access |
shell-tool-mcp/ |
MCP server exposing shell tool capabilities |
scripts/ |
Repo-wide utility scripts (release, install) |
docs/ |
Documentation (contributing, install, config) |
tools/ |
Developer tooling (argument-comment linting via Dylint) |
patches/ |
pnpm patch overrides for dependencies |
third_party/ |
Vendored third-party code (Meriyah, WezTerm) |
Important: The justfile sets working-directory := "codex-rs", so all just commands run from codex-rs/ regardless of your shell's cwd. Cargo commands (cargo test -p ...) must be run from codex-rs/.
# Core development
just codex # Run Orbit Code from source (alias: just c)
just test # Run Rust tests (nextest, --no-fail-fast) — see docs/test-suite/test.md
# macOS-safe test run (avoids syspolicyd CPU storm):
# cd codex-rs && cargo nextest run --no-fail-fast -P slow
just fmt # Format Rust code
just fix # Run clippy fixes
just fix -p <crate> # Clippy fix scoped to one crate
# Running a single test
cargo test -p <crate> -- <test_name> # Run one test by name
cargo test -p <crate> -- <module>::<test> # Run test in specific module
cargo nextest run -p <crate> -E 'test(name)' # Via nextest filter
# Schema regeneration (required after type changes)
just write-config-schema # After any ConfigToml change
just write-app-server-schema # After API shape changes (add --experimental for experimental)
just write-hooks-schema # After hooks schema changes
# Snapshot tests (TUI changes)
cargo insta pending-snapshots -p orbit-code-tui # Check pending snapshots
cargo insta show -p orbit-code-tui <path.snap.new> # Preview a snapshot
cargo insta accept -p orbit-code-tui # Accept all pending
# Other
just mcp-server-run # Run the MCP server
just log # Tail logs from state SQLite database
just bazel-lock-update # Update MODULE.bazel.lock after dep changes
just bazel-lock-check # Verify lockfile is in sync
just argument-comment-lint # Run /*param*/ comment lint
# SDK development
cd sdk/typescript && pnpm install && pnpm test # TypeScript SDK
cd sdk/python && pip install -e . && pytest -q # Python SDK
# Crate analysis (on-demand deep dive into any Rust crate)
./scripts/crate-map.sh codex-rs/<crate> # Full crate map to stdoutRun ./scripts/crate-map.sh <crate-dir> to generate a full analysis of any Rust crate. Use this whenever you need to understand a crate before making changes. Output includes:
- Dependency graph — workspace crates this depends on + who depends on it (blast radius)
- Module tree — public (▸) and private modules with sub-module hierarchy
- Public API surface — re-exports, types, functions, constants
- Test map — unit test files with counts, integration tests, total
- Call graph — entry points, internal dispatch targets, cross-module references
# Examples
./scripts/crate-map.sh codex-rs/core # Engine crate (the big one)
./scripts/crate-map.sh codex-rs/protocol # Foundation types
./scripts/crate-map.sh codex-rs/tui # Terminal UI
./scripts/crate-map.sh codex-rs/hooks # Lifecycle hooksThe workspace has a clear dependency hierarchy. Understanding these layers prevents circular dependencies and tells you which crates to rebuild after changes.
┌─────────────────────────────────────────────────────────────────┐
│ CONSUMER LAYER │
│ tui Full TUI (ratatui) │
│ tui_app_server TUI variant for IDE integration (app-server) │
│ cli Binary entry point, subcommand dispatch │
│ exec Headless/non-interactive CLI │
│ app-server JSON-RPC WebSocket API for IDE integrations │
│ mcp-server MCP protocol server │
└───────────────────────────┬─────────────────────────────────────┘
│ depends on
┌───────────────────────────▼─────────────────────────────────────┐
│ ENGINE LAYER │
│ core Agent loop, tool execution, config, auth, │
│ sandboxing, sessions, multi-agent, MCP mgmt │
│ app-server-protocol JSON-RPC types (v1 + v2) │
└───────────────────────────┬─────────────────────────────────────┘
│ depends on
┌───────────────────────────▼─────────────────────────────────────┐
│ FOUNDATION LAYER │
│ protocol Op, EventMsg, TurnItem, SandboxPolicy, etc. │
│ config TOML config parsing and layer merging │
│ hooks Lifecycle hook execution engine │
│ secrets Encrypted secrets (keyring backend) │
│ execpolicy Execution policy types │
│ anthropic Anthropic API client │
│ login OAuth/auth login flows │
│ otel OpenTelemetry instrumentation │
│ utils/* ~20 utility crates (path, git, pty, etc.) │
└─────────────────────────────────────────────────────────────────┘
The fundamental pattern is a bidirectional async channel between consumers (TUI, app-server) and the core engine:
Consumer (TUI/app-server) orbit-code-core (Session)
│ │
│──── Op::UserTurn { items, cwd, ... } ────▶│
│ │── model API call
│◀── EventMsg::TurnStarted ─────────────────│
│◀── EventMsg::AgentMessage ────────────────│
│◀── EventMsg::ExecApprovalRequest ─────────│
│──── Op::ExecApprovalDecision ────────────▶│
│ │── execute tool
│◀── EventMsg::ExecOutput ──────────────────│
│◀── EventMsg::TurnCompleted ───────────────│
Openum (protocol/src/protocol.rs) = submissions from consumer to engine (user input, approval decisions, interrupts)EventMsgenum (protocol/src/protocol.rs) = events from engine to consumer (agent messages, tool calls, approvals, errors)Session(core/src/codex.rs) = the agent loop that processes Ops and emits EventMsgsCodexThread(core/src/orbit_code_thread.rs) = public wrapper around Session for external consumers
There are two nearly identical TUI crates:
tui/— Standalone terminal TUI (usesorbit-code-coredirectly)tui_app_server/— TUI variant that goes through the app-server protocol (for IDE integration)
Convention 54: Mirror all tui/ changes in tui_app_server/ unless there is a documented reason not to. These crates share ~90% of their code but have different session management paths.
Unit tests live in sibling *_tests.rs files, not inline #[cfg(test)] modules. For example:
auth.rs→auth_tests.rscodex.rs→orbit_code_tests.rs
Integration tests follow: tests/all.rs → tests/suite/mod.rs → tests/suite/*.rs
Build systems: Cargo (local dev) + Bazel (CI/release). TypeScript: pnpm + tsup. Task runner: just (working dir = codex-rs/).
Toolchain: Rust 1.93.0 (edition 2024), pinned in codex-rs/rust-toolchain.toml.
These rules are mandatory. All code in this repo must follow these conventions exactly. They are derived from the original OpenAI team's patterns and enforced by tooling (clippy, rustfmt, prettier, eslint). Full evidence and file references:
docs/pattern/CODING_CONVENTIONS.md.
- Never add or modify code related to
CODEX_SANDBOX_NETWORK_DISABLED_ENV_VARorCODEX_SANDBOX_ENV_VAR. These are set by the sandbox runtime and existing code was authored with this in mind.CODEX_SANDBOX_NETWORK_DISABLED=1is set whenever theshelltool runs in sandbox.CODEX_SANDBOX=seatbeltis set on child processes spawned under macOS Seatbelt (/usr/bin/sandbox-exec). Existing checks for these env vars are intentional early-exit guards — do not remove or modify them. - Never mutate process environment in tests. Prefer passing environment-derived flags or dependencies from above.
- If you add
include_str!,include_bytes!, orsqlx::migrate!, update the crate'sBUILD.bazel(compile_data,build_script_data, or test data) or Bazel will fail even when Cargo passes. - Install any commands the repo relies on (e.g.,
just,rg,cargo-insta,cargo-nextest) if they aren't already available before running instructions.
- Declare modules private by default with
mod foo;. Re-export only needed types viapub use foo::Type;in lib.rs. - Use
pub modonly for major subsystem modules that form the crate's public API surface. Protocol crates (protocol,app-server-protocol) export everything publicly. - Use a single
.rsfile for focused modules. Use a subdirectory withmod.rswhen a module has 3+ sub-modules. - Place integration tests in
tests/all.rs->tests/suite/mod.rs->tests/suite/*.rs. Usetests/common/for shared test utilities as a library crate. Never create multiple top-level test binaries. - Target modules under 500 LoC excluding tests. At ~800 LoC, add new functionality in a new module instead of extending the existing file. Do not create single-use helper methods. This applies especially to high-touch files:
tui/src/app.rs,tui/src/bottom_pane/chat_composer.rs,tui/src/bottom_pane/footer.rs,tui/src/chatwidget.rs,tui/src/bottom_pane/mod.rs, and similarly central orchestration modules. - When extracting code from a large module, move the related tests and module/type docs toward the new implementation so invariants stay close to the code that owns them.
- Define error types with
#[derive(Debug, Error)]from thiserror. Every variant must have an#[error(...)]attribute. Use#[error(transparent)]for wrapped errors. - Define
pub type Result<T> = std::result::Result<T, YourError>;alongside each crate-level error type. - Prefer
#[from]for direct error wrapping. Use manualFromimpls only when conversion requires custom logic. - Add domain-specific query methods to error types (e.g.,
is_retryable(),to_protocol_error()). Use exhaustive matches, not wildcards. - Never use
unwrap()orexpect()in library code. Use?or explicit error handling. Tests may useexpect("descriptive message").
- Tokio is the sole async runtime.
#[tokio::test]for async tests,tokio::spawnfor background tasks,Handle::current()only when you need async work in Drop impls. - Channel selection:
broadcastfor fan-out notifications,oneshotfor single request/response,async_channelfor MPMC. - Shared state:
tokio::sync::Mutexfor async locking,tokio::sync::RwLockfor read-heavy state. Always wrap inArc<>. - Use
CancellationTokenwith.child_token()for hierarchical, coordinated shutdown of subsystems. - Use
JoinSetfor parallel Tokio tasks. UseFuturesUnorderedfor stream-based concurrent futures. - Retries: exponential backoff (
2^(attempt-1)) with +/-10% jitter viarandom_range(0.9..1.1). Use saturating arithmetic. Only retry transient errors (429, 5xx, connection failures).
- Derive sets by type category:
- Config:
Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq, JsonSchema - Protocol: add
TS - App-server v2: add
TS+ExperimentalApiwhere needed
- Config:
rename_allby context:kebab-casefor config TOML,snake_casefor protocol,camelCasefor app-server v2. Exception: config RPC payloads usesnake_caseto mirror TOML keys.- NEVER use
skip_serializing_ifon v2Option<T>payload fields — use#[ts(optional = nullable)]instead. For v2 booleans defaulting to false:#[serde(default, skip_serializing_if = "std::ops::Not::not")] pub field: bool. - Always add
#[ts(export_to = "v2/")]on v2 types. Keep#[serde(rename)]and#[ts(rename)]aligned. For tagged unions:#[serde(tag = "type")]and#[ts(tag = "type")].
- Add
Send + Syncbounds to traits used behindArc<dyn Trait>or across thread boundaries. Add+ 'staticwhen the trait object must outlive its scope. - Use
#[async_trait]for any trait with async methods. Place it directly above the trait definition. - Provide default implementations for optional trait methods. Use no-op defaults for lifecycle hooks (abort, cleanup). Document the default behavior.
- Use
pub(crate)for crate-internal types,pub(super)for parent-module-only types. Private by default; selective re-exports viapub use.
- One import per
usestatement (enforced byimports_granularity = "Item"in rustfmt.toml). Runjust fmtto enforce ordering automatically. - Package names:
orbit-code-<name>(hyphens). Library names:orbit_code_<name>(underscores). Binary names:orbit-codeororbit-code-<tool>(hyphens). - App-server types:
*Paramsfor requests,*Responsefor responses,*Notificationfor notifications. RPC methods:<singular-resource>/<camelCaseMethod>(e.g.,thread/start,fs/readFile).
- Avoid bool or ambiguous
Optionparameters that force callers to writefoo(false)orbar(None). Prefer enums, named methods, or newtypes to keep callsites self-documenting. - When you cannot change the API and have opaque literal arguments (booleans,
None, numbers), use/*param_name*/comments before them. The name must exactly match the callee's parameter. String/char literals are exempt unless the comment adds real clarity. - Use
#[derive(Debug, Parser)]with#[clap(flatten)]for shared option groups and#[clap(visible_alias)]for subcommand aliases. - Prefer plain
StringIDs at API boundaries. Do UUID parsing/conversion internally. Timestamps: integer Unix seconds (i64) named*_at. - When making exhaustive
matchstatements, avoid wildcard arms. Prefer listing all variants so the compiler catches new additions.
- Add
//!module docs to every module describing its purpose and key types. - Document all public items with
///. Use [TypeName] syntax for cross-references. Skip docs for trivial getters and self-evident enum variants. - Use
//inline comments only for non-obvious logic, invariants, or "why" explanations. Never restate what the code does. - When a change adds or modifies an API, update documentation in the
docs/folder if applicable. At minimum updateapp-server/README.mdfor app-server changes.
- Use
pretty_assertions::assert_eq!in every test module. Compare entire objects withassert_eq!, not individual fields. - Add
instasnapshot tests for any UI-affecting change. Snapshot workflow:- Run tests:
cargo test -p orbit-code-tui - Check pending:
cargo insta pending-snapshots -p orbit-code-tui - Preview:
cargo insta show -p orbit-code-tui path/to/file.snap.new - Accept:
cargo insta accept -p orbit-code-tui - Install if missing:
cargo install cargo-insta
- Run tests:
- Use
wiremock::MockServerand helpers fromcore_test_support::responsesfor HTTP mocking. Prefermount_sse_onceovermount_sse_once_matchormount_sse_sequence. Allmount_sse*helpers return aResponseMock— hold onto it to assert against outbound requests. UseResponseMock::single_request()for single-POST tests,ResponseMock::requests()to inspect all captured requests.ResponsesRequestexposes:body_json,input,function_call_output,custom_tool_call_output,call_output,header,path,query_param. Build SSE payloads withev_*constructors andsse(...). Typical pattern:let mock = responses::mount_sse_once(&server, responses::sse(vec![ responses::ev_response_created("resp-1"), responses::ev_function_call(call_id, "shell", &serde_json::to_string(&args)?), responses::ev_completed("resp-1"), ])).await; codex.submit(Op::UserTurn { ... }).await?; let request = mock.single_request(); // assert using request.function_call_output(call_id) or request.body_json()
- Use
TestCodexBuilderfluent API for integration test setup. Chain.with_config(),.with_model(),.with_auth(),.with_home(),.with_pre_build_hook(). - Use
wait_for_event(codex, predicate)for async event assertions. Prefer it overwait_for_event_with_timeout. - Use
orbit_code_utils_cargo_bin::cargo_bin()for binary resolution (works with Cargo and Bazel). Usefind_resource!instead ofenv!("CARGO_MANIFEST_DIR"). - Use
#[ctor]intests/common/lib.rsfor process-startup initialization (deterministic IDs, insta workspace root). - Avoid boilerplate tests that only assert experimental field markers for individual request fields in
common.rs— rely on schema generation/tests and behavioral coverage instead.
- 33 clippy lints are denied workspace-wide. Key rules enforced:
unwrap_used,expect_used— no panics in library code (allowed in tests)uninlined_format_args— alwaysformat!("{var}")notformat!("{}", var)redundant_closure_for_method_calls— use method references over closurescollapsible_if— always collapse nested ifs- All
manual_*rules — use idiomatic Rust - All
needless_*rules — no unnecessary borrows, collects, late inits
- Disallowed ratatui methods (enforced in clippy.toml):
Color::Rgb,Color::Indexed,.white(),.black(),.yellow(). Use ANSI colors only. - Large-error-threshold: 256 bytes. Box large payloads if an error variant exceeds this.
- Crates with TUI output must add
#![deny(clippy::print_stdout, clippy::print_stderr)]at the top of lib.rs.
- Use Stylize trait helpers:
"text".red(),"text".dim(),"text".bold(),"text".cyan(). Chain:url.cyan().underlined(). UseSpan::styledonly for runtime-computed styles. - Basic spans:
"text".into(). Lines:vec![span1, span2].into(). UseLine::from(vec![...])only when the target type isn't obvious. Prefer the form that stays on one line after rustfmt. - Color palette from
tui/styles.md: Headers = bold. Secondary = dim. Selection/tips = cyan. Success = green. Errors = red. Branding = magenta. Never use blue, yellow, white, black, Rgb, or Indexed. - Text wrapping:
adaptive_wrap_lines()for content with URLs,word_wrap_lines()for plain text,textwrap::wrap()for raw strings. Useprefix_linesfromline_utilsfor indented multi-line output. For indented wrapped lines, useinitial_indent/subsequent_indentoptions fromRtOptionsrather than writing custom logic. - Mirror all
tui/changes intui_app_server/unless there is a documented reason not to. - Don't refactor between equivalent forms (
Span::styled<->set_style,Line::from<->.into()) without a clear readability or functional gain. Follow file-local conventions. Do not introduce type annotations solely to satisfy.into().
- Config types must derive
JsonSchema. Runjust write-config-schemaafter anyConfigTomlchange. - Run
just write-app-server-schema(and--experimentalwhen needed) after API shape changes. Validate withcargo test -p orbit-code-app-server-protocol. - Add all dependencies to
[workspace.dependencies]in rootCargo.toml. Per-crate:{ workspace = true }with crate-specific feature overrides only. - After any dependency change: run
just bazel-lock-updatethenjust bazel-lock-check. Include the lockfile update in the same change. - Standard dev-dependencies:
pretty_assertions(diffs),tempfile(temp dirs),wiremock(HTTP mocking),insta(snapshots).
- ESM-first:
"type": "module"in package.json. Useimport/exportsyntax exclusively. - Always use
node:prefix for built-in imports:import from "node:fs",import from "node:path". - Target ES2022 with ESNext modules. Enable
strict: trueandnoUncheckedIndexedAccess: true. export typefor type-only re-exports from index.ts.export classfor concrete implementations.- Prefix unused parameters with
_. - tsup for bundling (ESM output for SDK, CJS for MCP servers). Jest with ts-jest for testing.
- Prettier with project config (
trailingComma: "all"). ESLint flat config with typescript-eslint.
- Hatchling build system. Pydantic v2 models.
src/layout. - pytest with
-q. ruff for linting. Auto-generate models from JSON schema.
- Run
just fmtafter every Rust change. Do not ask for approval — just run it. - Run
just fix -p <crate>before finalizing large changes. Scope with-pto avoid slow workspace-wide builds. Only runjust fixwithout-pif you changed shared crates. - Test the changed crate first:
cargo test -p <crate>. Project-specific or individual tests can be run without asking the user. Ask the user before running the complete test suite (just test). Run full suite only if core, common, or protocol crates changed. Avoid--all-featuresfor routine runs — it expands the build matrix and increasestarget/disk usage. - Do not re-run tests after running
just fixorjust fmt. - All active API development happens in app-server v2. Do not add new API surface area to v1.
- For experimental API surface: use
#[experimental("method/or/field")], deriveExperimentalApiwhen field-level gating is needed, and useinspect_params: trueincommon.rswhen only some fields of a method are experimental.
- Payloads:
*Params(request),*Response(response),*Notification(notification) - Wire format:
camelCasevia#[serde(rename_all = "camelCase")] - Optional fields in
*Params:#[ts(optional = nullable)]. Do not use#[ts(optional = nullable)]outside*Params. - Optional collections in
*Params: useOption<Vec<...>>+#[ts(optional = nullable)]. Never use#[serde(default)]for optional collections, and do not useskip_serializing_ifon v2 payload fields. - Boolean defaults-to-false:
#[serde(default, skip_serializing_if = "std::ops::Not::not")] pub field: bool - No-params exception: client->server requests with no params may use
params: #[ts(type = "undefined")] #[serde(skip_serializing_if = "Option::is_none")] Option<()> - Cursor pagination for list methods: request
cursor: Option<String>+limit: Option<u32>, responsedata: Vec<...>+next_cursor: Option<String> - TypeScript export:
#[ts(export_to = "v2/")]on all v2 types - Validate with
cargo test -p orbit-code-app-server-protocol - Key files:
app-server-protocol/src/protocol/common.rs,app-server-protocol/src/protocol/v2.rs,app-server/README.md
This section is non-negotiable. Every rule below applies to all code in this repository — Rust, TypeScript, and Python. There are no exceptions, no "fix later", and no workarounds.
We do not suppress lint issues. We fix them. If a linter, compiler, or type checker flags a problem, the only acceptable response is to resolve the underlying issue. Suppression annotations, disable comments, and workaround patterns are categorically prohibited.
The following attributes and patterns are never permitted in any Rust code (library or test):
| Forbidden | What to do instead |
|---|---|
#[allow(dead_code)] |
Delete the dead code. If it's planned for future use, it doesn't belong in the codebase yet. |
#[allow(unused_imports)] |
Remove the unused import. |
#[allow(unused_variables)] |
Prefix with _ if the variable is intentionally unused (e.g., _guard), or remove it. Do not blanket-allow. |
#[allow(unused_mut)] |
Remove the unnecessary mut. |
#[allow(unused_assignments)] |
Restructure the code so the assignment is used. |
#[allow(unreachable_code)] |
Delete the unreachable code or fix the control flow. |
#[allow(unreachable_patterns)] |
Fix the match arms. |
#[allow(clippy::*)] |
Fix what clippy is complaining about. Every workspace-denied lint exists for a reason. |
#[cfg_attr(test, allow(...))] |
Tests follow the same rules. Fix the issue in test code too. |
#![allow(...)] at crate root |
Never. Crate-level allows mask problems across the entire crate. |
The only exception: #[allow(unused_imports)] or #[allow(unused_variables)] inside #[cfg(...)] blocks where the import/variable is used on one platform but not another — and even then, prefer #[cfg]-gating the import itself rather than suppressing the warning.
| Forbidden | What to do instead |
|---|---|
// eslint-disable-next-line |
Fix the ESLint violation. |
// eslint-disable (block or file) |
Fix all violations in the block/file. |
// @ts-ignore |
Fix the type error. |
// @ts-expect-error |
Fix the type error. The only acceptable use is in test files asserting that incorrect usage produces a type error. |
// @ts-nocheck |
Never. This disables all type checking for the file. |
as any |
Use proper types. If the type is complex, define it. If it's from an external library, use the library's types or declare a minimal interface. |
as unknown as T |
This is a double-cast hack. Fix the actual type mismatch. |
! (non-null assertion) |
Use proper null checks, optional chaining, or narrow the type. |
@ts-ignore in JSDoc |
Same as above — fix the type. |
| Forbidden | What to do instead |
|---|---|
# type: ignore |
Fix the type error. If mypy/pyright is wrong, file an issue upstream. |
# noqa |
Fix the linting issue. |
# noinspection |
Fix what the inspector flagged. |
# pylint: disable=* |
Fix the pylint violation. |
# ruff: noqa |
Fix the ruff violation. |
typing.Any as escape hatch |
Use proper types. Define TypeVar, Protocol, or a concrete type. Any is acceptable only at true system boundaries (e.g., JSON deserialization of unknown external input). |
- Rust: All types must be fully specified. No
implreturn types that hide the concrete type from callers unless the function is private and the return type is genuinely complex (e.g., iterator chains). Prefer concrete types at API boundaries. - TypeScript:
strict: trueandnoUncheckedIndexedAccess: trueare mandatory. Every function must have explicit parameter types and return types. No implicitany. No untyped destructuring. - Python: All function signatures must have type annotations (parameters and return types). Use
from __future__ import annotationsfor forward references.
- Dead code: Delete it. If it's speculative future code, it belongs in a branch or issue, not in
main. - Unused import: Remove it. If you need it later, add it later.
- Type mismatch: Change the code or the type — do not cast or suppress.
- Clippy lint: Refactor to satisfy the lint. The 33 workspace-denied clippy lints exist because the patterns they flag are genuinely problematic.
- Complex type: Define a named type alias or struct. Complexity is not an excuse for
anyor suppression. - Third-party type issue: Wrap the third-party call in a properly typed function. Do not let bad external types leak into the codebase.
Code that ships with type suppressions, lint disables, or "fix later" comments is incomplete code. It does not get merged. If a type is hard to get right, that's a signal to design the type correctly — not to defer it.
just fix -p <crate>must pass with zero warnings for any changed crate.cargo test -p <crate>must compile without warnings.- TypeScript
npm run typecheckmust pass with zero errors. - Python
ruff checkand type checking must pass clean. - PRs with any suppression annotation will be rejected.