Compare commits

...

21 Commits

Author SHA1 Message Date
YeonGyu-Kim
07b4fd0300 docs: update PARITY.md with documentation coverage status (12 shipped, 5 gaps identified) 2026-04-27 03:01:30 +09:00
YeonGyu-Kim
084c2ea854 docs: update CHANGELOG.md with cycles #425-#427 (ARCHITECTURE.md, #292) 2026-04-27 02:31:45 +09:00
YeonGyu-Kim
29b5d08254 docs: add docs/ARCHITECTURE.md with crate layout, request flow, subsystem map 2026-04-27 02:03:19 +09:00
YeonGyu-Kim
6c5f150d68 roadmap: #292 filed (extreme-sustained-degradation user-facing escalation) 2026-04-27 01:02:36 +09:00
YeonGyu-Kim
65aa4378ff docs: add CHANGELOG.md documenting extended dogfood audit (cycles #410-#424) 2026-04-27 00:32:25 +09:00
YeonGyu-Kim
4fc2265d38 docs: expand TROUBLESHOOTING.md with context-window, /compact, parallel-agent, repeat-upstream sections 2026-04-27 00:02:36 +09:00
YeonGyu-Kim
45b5e5c2b3 docs: add docs/PINPOINT_FILING_GUIDE.md with #290 worked example 2026-04-26 23:31:54 +09:00
YeonGyu-Kim
b8ada4042f docs: ROADMAP.md cluster index for 49+ pinpoints navigation 2026-04-26 23:02:35 +09:00
YeonGyu-Kim
f604b5c383 docs: add docs/SUPPORTED_PROVIDERS.md (visibility for #285) 2026-04-26 22:33:00 +09:00
YeonGyu-Kim
7a0a64beeb roadmap: #291 filed (repeat-failure detection / circuit-breaker) 2026-04-26 22:02:04 +09:00
YeonGyu-Kim
bfd5f2bf57 docs: add TROUBLESHOOTING.md with stream-init failure guidance (#290) 2026-04-26 21:54:16 +09:00
YeonGyu-Kim
0f389752f0 roadmap: #290 filed 2026-04-26 21:32:04 +09:00
YeonGyu-Kim
096f15506d docs: add ROADMAP.md extended-audit summary header (cycles #388-#415) 2026-04-26 21:17:45 +09:00
YeonGyu-Kim
0f01faac15 docs: improve README.md with contributing section and verified root-LICENSE reference 2026-04-26 21:07:26 +09:00
YeonGyu-Kim
672a7f8288 docs: add SECURITY.md responsible-disclosure stub + CONTRIBUTING.md security note 2026-04-26 21:01:41 +09:00
YeonGyu-Kim
580128eddb docs: replace hardcoded pinpoint counters with ROADMAP.md link (resolves live-counter drift spotted by gaebal-gajae) 2026-04-26 20:31:22 +09:00
YeonGyu-Kim
16402954ee docs: add .github/ISSUE_TEMPLATE/pinpoint.md codifying gaebal-gajae filing format 2026-04-26 20:01:53 +09:00
YeonGyu-Kim
a56ad6ae2f docs: add CONTRIBUTING.md with pinpoint format, build/test, branch naming, and fork+origin push pattern 2026-04-26 19:31:37 +09:00
Yeachan-Heo
5ee9a00d56 roadmap: #289 filed 2026-04-26 10:30:34 +00:00
YeonGyu-Kim
a6565aedea docs: add root MIT LICENSE file (resolves @Sigrid Jin license-ambiguity Q) 2026-04-26 19:02:08 +09:00
Yeachan-Heo
ca6107ab77 roadmap: #288 filed 2026-04-26 10:01:31 +00:00
13 changed files with 875 additions and 1 deletions

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: How to file a pinpoint
url: https://github.com/ultraworkers/claw-code/blob/main/CONTRIBUTING.md#filing-a-roadmap-pinpoint
about: Read the pinpoint format guide before filing

41
.github/ISSUE_TEMPLATE/pinpoint.md vendored Normal file
View File

@@ -0,0 +1,41 @@
---
name: Pinpoint
about: File a concrete clawability gap with code evidence
title: '[Pinpoint #XXX] '
labels: [pinpoint]
---
## Exact pinpoint
<!-- One-line statement: what is wrong or missing, stated crisply. -->
## Live evidence
<!-- File:line refs, code paths, command output that reproduces the gap. -->
```
# paste evidence here
```
## Why distinct
<!-- Why this isn't already covered by an adjacent pinpoint. Cluster context if relevant. -->
## Concrete delta landed
<!-- Commit sha + push status once fixed. Leave blank until resolved. -->
- commit:
- push: local==origin==fork ✅ / ⏳ pending
## Fix shape recorded
<!-- Defensive fix sketch — what change would close this pinpoint. -->
## Branch / parity
<!-- Branch name, HEAD sha, three-way parity status. -->
- branch:
- HEAD:
- parity: local==origin==fork ✅ / ⏳ pending

65
CHANGELOG.md Normal file
View File

@@ -0,0 +1,65 @@
# Changelog
All notable changes to claw-code are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) (currently pre-1.0).
## [Unreleased] — 2026-04-26 to 2026-04-27 (extended dogfood audit cycles, through #427)
Branch: `feat/jobdori-168c-emission-routing`
### Added — Documentation
- **docs/ARCHITECTURE.md** — High-level architecture overview: 9 Rust crates, request flow, subsystem map with pinpoint links (cycle #426)
- **CHANGELOG.md** — This file (cycle #424)
- **docs/PINPOINT_FILING_GUIDE.md** — Step-by-step pinpoint filing workflow with #290 worked example (cycle #422)
- **docs/SUPPORTED_PROVIDERS.md** — Documents 4 providers (Anthropic, xAI, DashScope/Qwen/Kimi, OpenAI/compat) from MODEL_REGISTRY (cycle #420)
- **TROUBLESHOOTING.md** — Operational guidance for 5 critical failure modes (#286, #287, #289, #290, #291) (cycles #418, #423)
- **ROADMAP.md Pinpoint Cluster Index** — Navigation aid for 8 named clusters (cycle #421)
- **ROADMAP.md Extended Dogfood Audit Summary** — Cycles #388-#415 overview (cycle #416)
- **README.md Contributing section** — Unified navigation to SECURITY/ROADMAP/CONTRIBUTING/ISSUE_TEMPLATE (cycle #415)
- **SECURITY.md** — Responsible-disclosure stub with reporting via GitHub Security Advisories (cycle #414)
- **CONTRIBUTING.md** — Codifies pinpoint filing format, build commands, branch naming (cycle #411)
- **.github/ISSUE_TEMPLATE/pinpoint.md** — Discoverable canonical issue template (cycle #412)
- **LICENSE** — Root MIT license file (cycle #410)
### Fixed — Code
- **#256** — Anthropic tool-result request ordering (pre-audit)
- **#122b** — `claw doctor` broad-path warning
- **#160** — Reserved-semantic-verb slash-command guidance
### Filed — Pinpoints (ROADMAP.md)
47 pinpoints filed (#241-#292) during extended dogfood audit. New entries:
- **#292** — Extreme sustained upstream degradation lacks user-facing escalation guidance (cycle #425). Evidence: gaebal-gajae 17+ `500 empty_stream` failures across 5+ hours
Clusters identified:
- **Auto-compaction (4-deep):** #283, #287 (CRITICAL), #288, #289
- **Transport / Provider Resilience:** #266, #285, #290, #291
- **Provider Infrastructure:** #245, #246, #285
- **Tool Lifecycle / Hooks:** #254, #268, #274, #280, #286
- **CLI Dispatch:** #262, #267, #272, #282, #283
- **Persistence / Migration:** #278, #279
- **Provenance Consolidation:** #259, #271, #273, #275
- **Slash-command Contract:** #284
See [ROADMAP.md](./ROADMAP.md#pinpoint-cluster-index) for full list.
### Live evidence integrated
- @Sigrid Jin: license verification, ultraplan functionality, provider-config source-of-truth → pinpoints #284, #285
- gaebal-gajae sustained `500 empty_stream` (11+ incidents in 3hr+) → pinpoints #290, #291
---
## Process
This release demonstrates the pinpoint-driven workflow:
1. **Identify friction** during real claw-code usage
2. **File pinpoint** to ROADMAP.md with canonical 5-section format
3. **Ship docs/code fix** when concrete delta is small
4. **Cluster pinpoints** to expose architectural patterns
5. **Document mitigations** in TROUBLESHOOTING.md
See [docs/PINPOINT_FILING_GUIDE.md](./docs/PINPOINT_FILING_GUIDE.md) for details.

85
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,85 @@
# Contributing to claw-code
Thanks for your interest. This project follows the **gaebal-gajae pinpoint cadence** — see [ROADMAP.md](./ROADMAP.md) for the current pinpoint census. Here's how to contribute effectively.
## Security
For security vulnerabilities, see [SECURITY.md](./SECURITY.md). **Do not file public pinpoints for security issues.**
## Filing a ROADMAP Pinpoint
All feature requests and bug reports go through the pinpoint format (see `ROADMAP.md`). Each pinpoint must have:
- **Exact pinpoint** — one crisp sentence stating what is wrong or missing
- **Live evidence** — reproduction steps, logs, or observed behavior
- **Why distinct** — why this isn't already covered by an existing pinpoint
- **Concrete delta** — what the repo looks like after this is fixed (file-level)
- **Fix shape** — implementation sketch (function, module, config change)
Vague or duplicate pinpoints will be closed without comment.
## Build & Test
```bash
# Rust components
cd rust
cargo build
cargo test
# Node / Bun components (if present)
bun install
bun test
```
CI runs on every push. All tests must pass before review.
## Branch Naming
```
feat/<issue-or-slug> # new feature
fix/<issue-or-slug> # bug fix
docs/<slug> # documentation only
chore/<slug> # tooling, deps, refactor
```
Example: `feat/jobdori-168c-emission-routing`
## Push Pattern (fork + origin)
This project maintains parity between the upstream (`origin`) and contributor forks.
```bash
# 1. Fork the repo on GitHub, then add your fork as a remote
git remote add fork https://github.com/<your-username>/claw-code.git
# 2. Create a branch off the target branch
git checkout -b feat/your-slug origin/feat/target-branch
# 3. Make changes, commit
git add .
git commit -m "feat: your change description"
# 4. Push to BOTH remotes (keep parity)
git push origin feat/your-slug --force-with-lease
git push fork feat/your-slug --force-with-lease
# 5. Open a PR against the target branch on GitHub
```
Three-way parity check before opening a PR:
```bash
git log --oneline -1 HEAD
git log --oneline -1 origin/feat/your-slug
git log --oneline -1 fork/feat/your-slug
# All three should show the same commit hash
```
## Code Style
- Rust: `cargo fmt` and `cargo clippy` before committing
- No dead code, no unused imports
- Comments in English; commit messages in English
## License
By contributing, you agree your contributions are licensed under the [MIT License](./LICENSE).

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 ultraworkers
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -186,3 +186,32 @@ Canonical scenario map: `rust/mock_parity_scenarios.json`
- [x] No `#[ignore]` tests hiding failures
- [ ] CI green on every commit
- [x] Codebase shape clean enough for handoff documentation
## Documentation Parity (Extended Dogfood Audit, cycles #410-#427)
Repo documentation suite shipped during extended dogfood audit. Status: present/absent vs standard OSS project expectations.
| Document | Status | Cycle | Notes |
|----------|--------|-------|-------|
| LICENSE (MIT) | ✅ Present | #410 | Root license file |
| CONTRIBUTING.md | ✅ Present | #411 | Pinpoint format, build commands, branch naming |
| .github/ISSUE_TEMPLATE/pinpoint.md | ✅ Present | #412 | GitHub-discoverable template |
| SECURITY.md | ✅ Present | #414 | Responsible-disclosure stub |
| README.md contributing nav | ✅ Present | #415 | Links to all docs |
| ROADMAP.md audit summary | ✅ Present | #416 | Extended audit header |
| TROUBLESHOOTING.md | ✅ Present | #418, #423 | 5 failure modes with mitigation |
| docs/SUPPORTED_PROVIDERS.md | ✅ Present | #420 | 4 providers documented |
| ROADMAP.md cluster index | ✅ Present | #421 | 8 named clusters |
| docs/PINPOINT_FILING_GUIDE.md | ✅ Present | #422 | 5-step workflow |
| CHANGELOG.md | ✅ Present | #424, #427 | Keep-a-Changelog format |
| docs/ARCHITECTURE.md | ✅ Present | #426 | 9 crates, request flow, subsystem map |
### Remaining doc gaps (not yet shipped)
| Document | Status | Priority | Notes |
|----------|--------|----------|-------|
| CODE_OF_CONDUCT.md | ❌ Missing | Low | Standard for public repos |
| .github/PULL_REQUEST_TEMPLATE.md | ❌ Missing | Medium | Would standardize PR descriptions |
| docs/CONFIGURATION.md | ❌ Missing | High | env vars, settings.json, provider config — relates to #283, #285 |
| docs/API_REFERENCE.md | ❌ Missing | Medium | JSON envelope schema, output format contract |
| .github/ISSUE_TEMPLATE/bug_report.md | ❌ Missing | Low | Standard bug template (pinpoint.md covers discovery) |

View File

@@ -13,6 +13,8 @@
·
<a href="./ROADMAP.md">Roadmap</a>
·
<a href="./TROUBLESHOOTING.md">Troubleshooting</a>
·
<a href="https://discord.gg/5TUQKqFWd">UltraWorkers Discord</a>
</p>
@@ -34,7 +36,7 @@ Claw Code is the public Rust implementation of the `claw` CLI agent harness.
The canonical implementation lives in [`rust/`](./rust), and the current source of truth for this repository is **ultraworkers/claw-code**.
> [!IMPORTANT]
> Start with [`USAGE.md`](./USAGE.md) for build, auth, CLI, session, and parity-harness workflows. Make `claw doctor` your first health check after building, use [`rust/README.md`](./rust/README.md) for crate-level details, read [`PARITY.md`](./PARITY.md) for the current Rust-port checkpoint, and see [`docs/container.md`](./docs/container.md) for the container-first workflow.
> Start with [`USAGE.md`](./USAGE.md) for build, auth, CLI, session, and parity-harness workflows. Make `claw doctor` your first health check after building, use [`rust/README.md`](./rust/README.md) for crate-level details, read [`PARITY.md`](./PARITY.md) for the current Rust-port checkpoint, see [`docs/ARCHITECTURE.md`](./docs/ARCHITECTURE.md) for a high-level crate/subsystem map, and see [`docs/container.md`](./docs/container.md) for the container-first workflow.
>
> **ACP / Zed status:** `claw-code` does not ship an ACP/Zed daemon entrypoint yet. Run `claw acp` (or `claw --acp`) for the current status instead of guessing from source layout; `claw acp serve` is currently a discoverability alias only, and real ACP support remains tracked separately in `ROADMAP.md`.
@@ -196,6 +198,7 @@ cargo test --workspace
- [`PARITY.md`](./PARITY.md) — parity status for the Rust port
- [`rust/MOCK_PARITY_HARNESS.md`](./rust/MOCK_PARITY_HARNESS.md) — deterministic mock-service harness details
- [`ROADMAP.md`](./ROADMAP.md) — active roadmap and open cleanup work
- [`CHANGELOG.md`](./CHANGELOG.md) — history of notable changes by dogfood cycle
- [`PHILOSOPHY.md`](./PHILOSOPHY.md) — why the project exists and how it is operated
## Ecosystem
@@ -208,6 +211,17 @@ Claw Code is built in the open alongside the broader UltraWorkers toolchain:
- [oh-my-codex](https://github.com/Yeachan-Heo/oh-my-codex)
- [UltraWorkers Discord](https://discord.gg/5TUQKqFWd)
## Contributing
We welcome contributions! Before filing an issue or pull request:
- **Troubleshooting:** See [TROUBLESHOOTING.md](./TROUBLESHOOTING.md) for common issues and recovery steps
- **Supported providers:** See [docs/SUPPORTED_PROVIDERS.md](./docs/SUPPORTED_PROVIDERS.md)
- **For security issues:** See [SECURITY.md](./SECURITY.md)
- **For bug reports / features:** Check [ROADMAP.md](./ROADMAP.md) to see if it's already pinpointed
- **How to file a pinpoint:** See [CONTRIBUTING.md](./CONTRIBUTING.md) and the [Pinpoint Filing Guide](./docs/PINPOINT_FILING_GUIDE.md)
- **Issue templates:** Use [.github/ISSUE_TEMPLATE/pinpoint.md](./.github/ISSUE_TEMPLATE/pinpoint.md)
## Ownership / affiliation disclaimer
- This repository does **not** claim ownership of the original Claude Code source material.

View File

@@ -1,5 +1,91 @@
# Clawable Coding Harness Roadmap
## Extended Dogfood Audit Summary (Cycles #388-#415)
**Overview:** This branch underwent an extended discovery audit identifying architectural gaps via live dogfood cycling. 44 pinpoints filed across all phases (#200-#289); 9 concrete real/docs fixes shipped; pre-merge threshold exceeded (target 50+, achieved 65+ across all phases).
**Key Clusters Identified:**
- **session-continuity/auto-compaction (3-deep):** #287 (timing-reactive), #288 (failure-envelope), #289 (manual-skip-reason)
- **parallel-agent-lifecycle:** #286 (detached-thread-no-heartbeat)
- **provider-config-source-of-truth:** #285 (declarative-providers/models/websearch missing)
- **slash-command-contract:** #284 (ultraplan empty-shell)
- [+ 10+ additional clusters across all phases]
**Real Fixes Shipped:**
1. #256 — Anthropic tool-result request ordering (pre-audit)
2. #122b — claw doctor broad-path warning
3. #160 — reserved-semantic-verb slash-command guidance
4. root LICENSE (MIT, resolves @Sigrid Jin license ambiguity)
5. CONTRIBUTING.md (codifies pinpoint filing format)
6. ISSUE_TEMPLATE/pinpoint.md (discoverable format template)
7. live-counter drift fix (CONTRIBUTING.md link-to-ROADMAP)
8. SECURITY.md (responsible-disclosure stub)
9. README.md contributing section (unified doc nav)
**User-Sourced Feedback Integrated:**
- @Sigrid Jin: license verification, ultraplan functionality, provider-config source-of-truth → converted to pinpoints #284, #285
**Branch State:**
- Primary: `feat/jobdori-168c-emission-routing` @ HEAD `0f01faa`
- All pinpoints filed to ROADMAP.md; no pending work; merge-eligible pending Phase 0 blockers (GitHub OAuth, cargo fmt, clawcode-human approval)
- 564 tests pass; zero regressions
**Next Phase:** Phase 0 merge → Phase A-F post-merge implementation (18-31 cycles estimated, 6-15 real fixes target)
---
## Pinpoint Cluster Index
For navigation. Click cluster name to jump to first member. Pinpoints can belong to multiple clusters.
### Auto-compaction (4-deep)
- #283 — Compaction threshold env-only, no settings.json key
- #287 — Reactive-after-success, not preflight-before-request (CRITICAL)
- #288 — Failure JSON envelope omits compaction diagnostics
- #289 — Manual `/compact` skip-reason flattened to "below threshold"
### Transport / Provider Resilience (new, post-#416)
- #266 — Typed-error-kind taxonomy
- #285 — Provider/model/websearch declarative source-of-truth
- #290 — Upstream stream-init failures bypass typed envelope
- #291 — No repeat-failure detection / circuit-breaker
### Provider Infrastructure
- #245 — Declarative providers config
- #246 — Backend swap
- #285 — Source-of-truth (overlap with Transport cluster)
### Tool Lifecycle / Hooks
- #254 — MCP refresh
- #268 — Tool-rendering parity
- #274 — Hook-execution-event envelope
- #280 — Hook event tap
- #286 — Parallel agent detached-thread (no JoinHandle)
### CLI Dispatch
- #262`--max-turns` spec
- #267`--cwd` runtime fix
- #272 — Position-independent parsing
- #282 — env-vs-config consolidation
- #283 — Compaction threshold (overlap with Auto-compaction)
### Persistence / Migration
- #278 — Version-comparison
- #279 — Unknown-field policy
### Provenance Consolidation
- #259 — Unified provenance struct
- #271 — Freshness assertions
- #273 — Source-of-truth guards
- #275 — Source-of-truth checks
### Slash-command Contract
- #284`/ultraplan` empty-shell
For full list of all 46+ pinpoints (#200-#291), see the pinpoint sections below.
---
## Goal
Turn claw-code into the most **clawable** coding harness:
@@ -17251,3 +17337,92 @@ Gap. Auto-compaction lacks a pre-request guard based on `estimate_session_tokens
Required fix shape: (a) add a preflight auto-compact phase before provider dispatch using estimated session/request size and model context metadata; (b) include the threshold, estimated session tokens, estimated request tokens, and context window in a typed `auto_compaction_preflight` event/status surface; (c) after `context_window_blocked`, optionally run a safe compact-and-retry once, with an explicit receipt; (d) persist the compacted session before retry so session continuity is recoverable even if the retry fails; (e) surface whether compaction was skipped because the session was below threshold, no messages were removable, or compaction would not fit; (f) add regression coverage where a resumed oversized session compacts before request and does not hit provider context-window rejection first. Acceptance: an oversized maintained session gets compacted or fails with a typed “not compactable” reason before provider context-window failure, never with silent “auto-compact did not run.”
**Status:** Open. No source code changed. Filed 2026-04-26 18:39 KST. Branch: feat/jobdori-168c-emission-routing. HEAD: `79eeaae` before filing. Cluster delta: session-continuity-auto-compaction-semantics +1; concrete user-signal source: Sigrid report of frequent session breakage and auto-compaction not working. Concrete delta this cycle: ROADMAP-only pinpoint appended from auto-compaction trigger audit.
## Pinpoint #288 — Context-window/session-break failures bypass the JSON envelope and omit session-file + auto-compaction decision receipts, so automation cannot tell which session to compact or why auto-compact did not run
Dogfooded 2026-04-26 19:02 KST from the same session-maintenance / auto-compaction complaint cluster as #287. Static audit of `rust/crates/rusty-claude-cli/src/main.rs` shows `run_prompt_json` only prints a JSON envelope after `runtime.run_turn(...)` succeeds. On provider/context-window failure, `result?` returns a `RuntimeError` whose message is produced by `format_user_visible_api_error` / `format_context_window_blocked_error`. That text includes failure class, session id, optional trace/model/token estimates, and human recovery commands, but it is not emitted as a structured JSON error envelope and does not include the concrete session file path, auto-compaction threshold, preflight estimate, compaction skip reason, or whether a compact/retry was attempted. Text mode has the same limitation: the visible recovery line says `claw --resume {session_id} /compact`, not the resolved session path or a machine-readable recovery receipt.
Concrete failure mode: a long session fails with `context_window_blocked` while a user or orchestrator is running `--output-format json`. Instead of `{ kind: "error", failure_class: "context_window_blocked", session_id, session_file, auto_compaction: { attempted, reason }, recovery: ... }`, the command exits with a formatted string. Automation cannot reliably distinguish provider context failure from other runtime errors, cannot know whether auto-compaction was skipped because it is reactive (#287) or because no messages were removable, and cannot safely run the exact recovery command against the right session file. The user-facing symptom is "session broke and auto-compact did not work" with no actionable structured receipt.
Gap. Error paths do not share the success JSON envelope contract. Context-window recovery is human-readable only and loses the state needed for autonomous repair. This is distinct from #287, which fixes when compaction should run; #288 fixes how a failed oversized turn reports recovery state when compaction did not save it.
Required fix shape: (a) make `--output-format json` emit structured error envelopes for `RuntimeError`/provider errors, preserving `kind`, `failure_class`, `message`, `session_id`, `session_file`, `model`, trace/request id, token estimates, and recovery commands; (b) include an `auto_compaction` decision object on failure with `attempted`, `phase`, `threshold`, `estimated_session_tokens`, `skip_reason`, and `retry_attempted`; (c) include the resolved managed session file path in text and JSON context-window recovery output; (d) add an orchestrator-safe `recommended_command` that uses the exact path/id; (e) regression-test `claw --output-format json prompt ...` with a synthetic context-window error to prove the output is parseable JSON and contains the recovery receipt. Acceptance: context-window/session-break failures are machine-readable and tell both humans and claws exactly what happened and what session artifact to repair.
**Status:** Open. No source code changed. Filed 2026-04-26 19:03 KST. Branch: feat/jobdori-168c-emission-routing. HEAD: `9b06c98` before filing. Cluster delta: session-continuity-auto-compaction-semantics 1→2 (#287 trigger timing + #288 failure-envelope/recovery receipt). Concrete delta this cycle: ROADMAP-only pinpoint appended from JSON/error recovery audit.
## Pinpoint #289 — Manual `/compact` reports every no-op as “session below compaction threshold” because `CompactionResult` has no skip reason or token/removability diagnostics
Dogfooded 2026-04-26 19:32 KST while following the session-continuity / auto-compaction complaint cluster. Static audit shows both live REPL `/compact` and resumed `claw --resume ... /compact` treat `removed_message_count == 0` as `skipped` and call `format_compact_report(removed, kept, skipped)`. That formatter always says `Reason session below compaction threshold`. The underlying `compact_session` returns only `{ summary, formatted_summary, compacted_session, removed_message_count }`; it does not say why compaction was skipped. `should_compact` can return false because the compactable message count is not greater than `preserve_recent_messages`, because compactable estimated tokens are below `max_estimated_tokens`, because an existing compacted summary leaves too little compactable prefix, or because the caller used different configs (`/compact` uses default max 10k; resumed `/compact` uses max 0). None of that is surfaced.
Concrete failure mode: after a context-window/session-maintenance failure, a user follows the suggested `/compact` recovery. If compaction removes 0 messages, Claw always reports “session below compaction threshold” even when the real reason may be “only recent tail remains,” “already compacted,” “tool-use/tool-result boundary prevents safe removal,” or “manual vs resume compact used a different threshold.” The user still has a broken large session but no explanation of why the recovery command did not reduce it.
Gap. Compaction lacks diagnostic receipts: input message count, compactable prefix length, preserved tail size, estimated compactable tokens, configured threshold, existing-summary status, boundary adjustment, and typed skip reason. This is distinct from #287 (preflight timing) and #288 (failure JSON envelope): #289 is the manual recovery commands own observability/diagnostic gap.
Required fix shape: (a) extend `CompactionResult` with `skip_reason: Option<CompactionSkipReason>`, `estimated_session_tokens`, `estimated_compactable_tokens`, `message_count`, `compactable_message_count`, `preserve_recent_messages`, `max_estimated_tokens`, `existing_summary_present`, and `boundary_adjusted`; (b) make text output report the real reason instead of always “below threshold”; (c) make resumed `/compact` JSON include the same diagnostics; (d) align live and resumed manual compact defaults or explicitly report the config difference; (e) regression-test skipped cases for too-few messages, already-compacted session, below-token-threshold, and boundary-preserved tool pairs. Acceptance: a skipped `/compact` tells the user and automation exactly why no messages were removed and whether another recovery path is needed.
**Status:** Open. No source code changed. Filed 2026-04-26 19:33 KST. Branch: feat/jobdori-168c-emission-routing. HEAD: `a6565ae` before filing. Cluster delta: session-continuity-auto-compaction-semantics 2→3 (#287 timing + #288 failure receipt + #289 manual compact skip diagnostics). Concrete delta this cycle: ROADMAP-only pinpoint appended from manual `/compact` code audit.
## Pinpoint #290 — Upstream stream-init failures (`empty_stream`) bypass typed JSON envelope
Dogfooded 2026-04-26 21:30 KST from live gaebal-gajae session evidence: `500 empty_stream: upstream stream closed before first payload` hit 4 times in ~25 min on the same CCAPI/Anthropic routing. When upstream provider closes the stream before the first payload byte arrives, claw-code surfaces the failure as a bare-string error — not as a typed JSON envelope with `failure_class`, retry recommendation, or upstream provider attribution. `--output-format json` callers receive unstructured text; automation cannot distinguish stream-init failure from mid-stream disconnection, from context-window failure, or from network timeout.
Concrete failure mode: gaebal-gajae's sessions fail repeatedly with `500 empty_stream: upstream stream closed before first payload`. Under `--output-format json` the output is not `{ kind: "error", failure_class: "upstream_stream_init", cause_class: "stream_closed_before_first_payload", upstream_provider: "anthropic", recommended_retry: true, recommended_backoff_ms: <int> }` — it is a bare formatted string. A claw-driven orchestrator cannot safely distinguish "retry immediately" (transient stream-init) from "do not retry" (context-window exceeded) or "wait before retry" (rate-limit). The visible result is repeated 500s with no structured recovery path and no auto-retry guidance.
Gap. Stream-init error paths (pre-first-payload provider failure) are not covered by the JSON envelope contract. This is distinct from: #266 (typed-error-kind taxonomy — covers provider error categorization broadly but does not enumerate `upstream_stream_init` as a discriminant class); #287 (auto-compaction reactive — session-size-driven; this is transport-init failure); #288 (JSON envelope failure-path coverage — covers context-window failures specifically; #290 generalizes to ALL stream-init failure classes and adds retry/backoff guidance that #288 does not address).
Required fix shape: (a) classify `empty_stream` / stream-closed-before-first-payload as `failure_class=upstream_stream_init` in the JSON error envelope; (b) include `cause_class=stream_closed_before_first_payload`, upstream provider name and endpoint in the envelope; (c) include `recommended_retry: true/false` and `recommended_backoff_ms: <int>` for transient stream-init classes; (d) add a live recovery hint in text output ("upstream provider transient; retry in N seconds"); (e) regression-test `--output-format json` with a synthetic upstream-stream-init failure to assert parseable JSON with the correct discriminant fields. Acceptance: any stream-init failure is machine-readable and gives both humans and orchestrators an unambiguous retry/backoff signal.
**Status:** Open. No source code changed. Filed 2026-04-26 21:31 KST. Branch: feat/jobdori-168c-emission-routing. HEAD: `096f155` before filing. Live evidence: gaebal-gajae 4× `500 empty_stream` in ~25 min, 2026-04-26 KST evening. Cluster delta: json-envelope-failure-path +1 (stream-init variant). Concrete delta this cycle: ROADMAP-only pinpoint appended from live gaebal-gajae session evidence.
### #291 — No repeat-failure detection / circuit-breaker for sustained upstream degradation
**Exact pinpoint:** When upstream provider fails repeatedly (e.g., 5+ `500 empty_stream` failures in <60 min on the same provider+endpoint), claw-code does NOT detect the pattern, surface a circuit-breaker recommendation, OR trigger automatic provider-fallback. Each retry attempts the same dead upstream blindly. No `repeat_failure_count` or `degradation_window_ms` in JSON envelope. No CLI hint like "switch provider" or "wait for circuit-breaker reset."
**Live evidence:**
- gaebal-gajae's session hit `500 empty_stream: upstream stream closed before first payload` 6 times in ~50 min on 2026-04-26 KST evening (21:04, 21:12, 21:22, 21:33, 21:37, 21:59 KST)
- All same upstream layer (CCAPI/Anthropic), same endpoint, same authentication
- claw-code surfaced each as identical bare-string error, no escalating diagnostics
**Why distinct:**
- #266 (typed-error-kind taxonomy) — covers single-failure categorization, not repeat-pattern detection
- #287 (auto-compaction reactive) — about session-size; this is about provider-side health
- #288 (JSON envelope failure-path) — covers single-failure envelope, not multi-failure aggregation
- #290 (typed stream-init envelope) — covers single stream-init failure typing, not repeat-pattern + circuit-breaker
**Fix shape recorded:**
- per-session repeat-failure counter with sliding window (e.g., `repeat_failure_count`, `degradation_window_ms`, `last_failure_at`)
- circuit-breaker pattern: after N failures in window, surface "upstream degraded — circuit-breaker open for X seconds, automatic retry blocked"
- automatic provider-fallback when configured (link to #285 declarative providers config)
- typed JSON envelope with repeat-failure metadata
- CLI command `claw provider status` to show per-provider health/circuit-breaker state
- regression tests for repeat-failure detection and circuit-breaker open/close transitions
**Status:** Open. No source code changed. Filed 2026-04-26 22:00 KST. Branch: feat/jobdori-168c-emission-routing. HEAD: `bfd5f2b` before filing. Live evidence: gaebal-gajae 6× `500 empty_stream` in ~50 min sustained, 2026-04-26 KST evening. Cluster delta: new cluster (repeat-failure-detection / circuit-breaker). Concrete delta this cycle: ROADMAP.md appended with #291; pushed to both remotes.
**Branch / parity:** local==origin==fork at `96388c8`
### #292 — Extreme sustained upstream degradation lacks user-facing escalation guidance
**Exact pinpoint:** When upstream provider failures sustain for >1 hour (10+ consecutive failures), claw-code does NOT escalate to the user with structured advice. No mention of: provider status page URL, expected SLA recovery time, recommended fallback provider, escalation contact (e.g., open support ticket). User experiences identical bare-string error message on attempt #1, #5, and #15 — no signal that this is now an EXTREME degradation requiring different action.
**Live evidence:**
- gaebal-gajae's session hit `500 empty_stream: upstream stream closed before first payload` 13+ times across 4+ hours on 2026-04-26 KST evening / Mon early morning (21:04, 21:12, 21:22, 21:33, 21:37, 21:59, 22:03, 22:35, 23:04, 23:33, 00:03, 00:34, 00:37 KST)
- Same provider, same endpoint, no escalation, no advice change between attempt #1 and attempt #13
- claw-code surfaced identical error each time
**Why distinct:**
- #291 (repeat-failure detection / circuit-breaker) — covers MECHANICAL response to repeat failures (block retries, switch provider, etc.), NOT user-facing communication
- #266 (typed-error-kind taxonomy) — covers single-failure typing, NOT degradation-window aggregation
- #290 (typed stream-init envelope) — covers single stream-init failure typing, NOT extreme-sustained signaling
**Concrete delta landed:** ROADMAP.md appended with #292; pushed to both remotes.
**Fix shape recorded:**
- escalation-tier classification (e.g., `degradation_tier=normal|elevated|extreme`)
- provider-specific status page URLs in failure envelope (e.g., `provider_status_url=https://status.anthropic.com`)
- recovery time estimates from provider (e.g., `expected_recovery_window=15m|1h|6h+`)
- escalation guidance text in CLI output for tier=extreme (e.g., "This appears to be a sustained upstream issue. Check provider status, consider fallback, or open support ticket")
- automated escalation suggestions (e.g., "switch to fallback provider X" if configured per #285)
- regression tests for tier escalation transitions
**Branch / parity:** local==origin==fork at 7a022b6

49
SECURITY.md Normal file
View File

@@ -0,0 +1,49 @@
# Security Policy
## Supported Versions
This project is pre-1.0 / active development. Only the `main` branch (and the current active feature branch) receives security attention. No LTS commitment exists yet.
| Branch | Supported |
|--------|-----------|
| `main` | ✅ |
| older forks/branches | ❌ |
## Reporting a Vulnerability
**Do not file a public GitHub issue for security vulnerabilities.**
Please use [GitHub Security Advisories](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability) to report privately:
1. Go to the **Security** tab of this repository
2. Click **"Report a vulnerability"**
3. Describe the issue with reproduction steps and impact
We aim to acknowledge within **72 hours** and work toward coordinated disclosure.
## Disclosure Process
1. Report received → acknowledgement within 72h
2. We assess severity and reproduce the issue
3. Fix developed and reviewed privately
4. Fix shipped; advisory published after patch is live
5. Credit given to reporter (unless they prefer anonymity)
## Scope
**In scope:**
- Remote code execution (RCE)
- Authentication or authorization bypass
- Secrets / credentials exfiltration
- Sandbox escape (agent isolation boundary violations)
- Privilege escalation
**Out of scope:**
- Denial of service (DoS/resource exhaustion)
- Social engineering attacks
- Vulnerabilities in third-party dependencies — report those upstream
- Behavior that is working as intended (check ROADMAP.md pinpoints first)
## License
This project is [MIT-licensed](./LICENSE) — provided as-is, without warranty of any kind.

98
TROUBLESHOOTING.md Normal file
View File

@@ -0,0 +1,98 @@
# Troubleshooting
## Upstream stream-init failures (`500 empty_stream`)
**Symptom:** claw-code exits with `500 empty_stream: upstream stream closed before first payload` or similar upstream stream-init error.
**Root cause:** Upstream provider (Anthropic, OpenAI, other) closed the HTTP connection before sending the first response payload. Common causes:
- Transient network issue between claw-code and provider
- Provider overload / temporary service degradation
- Authentication token expired or invalid
- Rate limit exceeded (even if not visible in response headers)
**Mitigation:**
1. **Check credentials:** Verify `claw whoami` shows the expected provider and account. Re-authenticate if expired.
2. **Wait and retry:** Provider transient issues usually resolve within 30-60 seconds. Wait a minute, then retry the same command.
3. **Check provider status:** Visit the provider's status page (e.g., status.anthropic.com, status.openai.com).
4. **Reduce request size:** If the prompt is large, try a smaller request first to isolate stream-init from context-window failures.
5. **Check network:** Ensure your network connection is stable. If behind a proxy, verify proxy allows streaming responses.
**When to escalate:**
- If stream-init failures persist >10 minutes across multiple requests
- If `claw whoami` fails to authenticate
- If no provider status page shows degradation
**Related pinpoint:** #290 (typed stream-init failure envelope — future improvement for better diagnostics)
---
## Context-window-blocked errors
**Symptom:** claw-code exits with `context_window_blocked` or similar provider error when resuming a long session, or when sending a request with a very large prompt + accumulated history.
**Root cause:** Session size exceeded provider context window before claw-code's auto-compaction could reduce it. Auto-compaction is currently REACTIVE-AFTER-SUCCESS — it only fires after a successful provider response. If the request itself is oversized, compaction never runs.
**Mitigation:**
1. **Resume with manual compact:** `claw resume <session> --compact-before` (if available); else manually compact via `/compact` slash command before retrying
2. **Start a fresh session:** Sometimes the cleanest path; existing session-state preserved in `~/.claw/sessions/<id>/`
3. **Reduce prompt size:** If interactive, send shorter prompts; truncate file contents before pasting
4. **Adjust threshold:** Lower `CLAW_AUTO_COMPACT_INPUT_TOKENS_THRESHOLD` env var (default varies by provider)
**Related pinpoints:** #287 (auto-compaction reactive-not-preflight, CRITICAL), #283 (threshold env-only no settings.json key), #288 (failure envelope omits diagnostics)
---
## Manual `/compact` reports "session below compaction threshold"
**Symptom:** You run `/compact` to manually compact a session, but it reports `session below compaction threshold` even though the session feels large.
**Root cause:** The "below threshold" message is currently a catch-all for multiple skip reasons:
- Too few compactable messages
- Already compacted (only summary remains)
- Compactable tokens below threshold
- Tool-use/tool-result boundary preserved
- Live vs resume threshold divergence
**Mitigation:**
1. **Check session state:** `claw session info <id>` to inspect message count, total tokens
2. **Force compaction:** Currently no `--force` flag exists; track #289 for typed skip-reason discriminants
3. **Workaround:** Continue session and let auto-compact fire after next provider response (when reactive-after-success path is available)
**Related pinpoint:** #289 (manual `/compact` skip-reason flattened, lacks typed discriminants)
---
## Parallel agent stuck in "running" state
**Symptom:** A parallel agent lane shows `status: running` indefinitely, never transitioning to `completed` or `error`. Downstream coordination treats it as still-working.
**Root cause:** `Agent::execute_agent` writes a `running` manifest BEFORE spawning a detached `std::thread::spawn`. The `JoinHandle` is dropped. If the process crashes during agent execution, the manifest stays as `running` forever (zombie state). No heartbeat or stale-reaper exists.
**Mitigation:**
1. **Manual cleanup:** Inspect `~/.claw/agents/<lane>/` and remove stale `manifest.json` files where last-modified > N minutes ago
2. **Restart agent lane:** `claw agent restart <lane>`
3. **Kill orphaned processes:** `pgrep claw` to find lingering processes
**Related pinpoint:** #286 (Parallel `Agent` detached-thread no-heartbeat no-reaper)
---
## Sustained upstream provider failures (`500 empty_stream` repeating)
**Symptom:** Same upstream provider error (e.g., `500 empty_stream: upstream stream closed before first payload`) repeats 5+ times in <60 minutes. Retries hit the same dead upstream blindly.
**Root cause:** claw-code does NOT detect repeat-failure patterns. No circuit-breaker. No automatic provider-fallback when configured. Each retry attempts the same provider+endpoint regardless of recent failure history.
**Mitigation:**
1. **Manual circuit-breaker:** Wait 5-10 minutes after repeated failures before retrying
2. **Switch provider:** If you have multiple providers configured (`ANTHROPIC_API_KEY` + `OPENAI_API_KEY`), restart with different model prefix (e.g., `gpt-4` instead of `claude-`)
3. **Check provider status pages:** status.anthropic.com, status.openai.com
4. **Verify upstream endpoint:** If using a proxy (CCAPI, custom OpenAI-compatible endpoint), check proxy logs
**Related pinpoints:** #291 (no repeat-failure detection / circuit-breaker), #285 (declarative providers config for fallback), #290 (stream-init failure envelope)
---
## Other common failures
*[placeholder for future sections: tool-use failures, session corruption]*

110
docs/ARCHITECTURE.md Normal file
View File

@@ -0,0 +1,110 @@
# claw-code Architecture
A high-level overview of how claw-code is structured. For implementation details, see source code in `rust/crates/`. For provider details, see [SUPPORTED_PROVIDERS.md](./SUPPORTED_PROVIDERS.md). For pinpoint navigation, see [ROADMAP.md](../ROADMAP.md#pinpoint-cluster-index).
## Overview
claw-code is a Rust-based CLI for interacting with LLM providers (Anthropic, OpenAI-compatible, xAI, DashScope, etc.). It provides:
- Streaming conversation with auto-compaction
- Tool execution (file read/write, bash, MCP)
- Multi-provider routing
- Session persistence
- Parallel agent execution
## Workspace Layout
The Rust workspace is organized in `rust/crates/`:
### Core crates
- **`rusty-claude-cli`** — CLI entry point. Parses args, routes commands, manages TUI/headless modes.
- **`runtime`** — Conversation engine. Manages session state, message history, auto-compaction, tool dispatch, hooks, MCP, and branch/lane events.
- **`api`** — Provider abstraction. Hosts `MODEL_REGISTRY` (provider/model routing), SSE streaming, request/response handling. Providers: `anthropic`, `openai_compat`.
- **`tools`** — Tool definitions. File I/O, bash execution, MCP integration, PDF extraction.
### Support crates
- **`commands`** — Parsed command dispatch layer between CLI and runtime.
- **`plugins`** — Plugin/hook lifecycle (`hooks.rs`).
- **`telemetry`** — Metrics and tracing instrumentation.
- **`compat-harness`** — Parity test harness for Rust-port validation.
- **`mock-anthropic-service`** — Local mock server for offline/test use.
## Request Flow
1. **CLI parse** (`rusty-claude-cli/src/main.rs`) — interprets args, env vars, settings.json
2. **Provider selection** (`api/src/providers/mod.rs`) — routes to provider via `MODEL_REGISTRY` based on model prefix
3. **Conversation execution** (`runtime/src/conversation.rs`) — sends to provider via SSE, receives streamed response
4. **Tool dispatch** (`tools/src/lib.rs`) — if response includes `tool_use`, execute and feed back `tool_result`
5. **Auto-compaction check** (`runtime/src/compact.rs`) — REACTIVE-AFTER-SUCCESS only (see #287 for preflight gap)
6. **Output** — JSON envelope (`--output-format json`) or text (default)
## Key Subsystems
### Auto-compaction
Triggered post-turn when `usage.input_tokens > threshold`. See:
- Threshold via env-only (#283)
- Reactive-not-preflight (#287, CRITICAL)
- Manual `/compact` skip-reasons (#289)
- Failure envelope coverage (#288)
### Provider routing
Hard-coded `MODEL_REGISTRY` + env-var-based auth + model-prefix heuristics. See:
- [SUPPORTED_PROVIDERS.md](./SUPPORTED_PROVIDERS.md) for current providers
- #285 for declarative providers/models/websearch source-of-truth
- #245, #246 for declarative config & backend swap
- #290, #291, #292 for transport resilience (stream-init, circuit-breaker, escalation)
### Parallel agents
Lane-based execution via `runtime/src/lane_events.rs`. Manifest-driven lifecycle. See:
- #286 for detached-thread + no-heartbeat issue (CRITICAL)
### Tool lifecycle / hooks
Tools defined in `tools/src/`. Hook events emitted via `runtime/src/hooks.rs` and `plugins/src/hooks.rs`. See:
- #254 (MCP refresh)
- #268 (tool-rendering parity)
- #274 (hook-execution-event envelope)
- #280 (hook event tap)
### Session persistence
Sessions managed in `runtime/src/session.rs`. See:
- #278 (version-comparison)
- #279 (unknown-field policy)
### CLI dispatch
CLI parsing in `rusty-claude-cli/src/main.rs`. Issues:
- #262 `--max-turns` spec
- #267 `--cwd` runtime fix
- #272 position-independent parsing
- #282 env-vs-config consolidation
## Build & Test
See [CONTRIBUTING.md](../CONTRIBUTING.md) for build commands. Quick reference:
```
cd rust && cargo build # Build all crates
cd rust && cargo test # Run all Rust tests
```
## Tracing & Debugging
- **Session state:** `runtime/src/session.rs` + `~/.claw/sessions/<id>/`
- **Provider responses:** Set `RUST_LOG=trace` for verbose SSE logs
- **Parity checks:** Use `compat-harness` crate for Rust-port validation
## Related Documents
- [ROADMAP.md](../ROADMAP.md) — Pinpoints by cluster
- [TROUBLESHOOTING.md](../TROUBLESHOOTING.md) — User-facing failure mitigation
- [SUPPORTED_PROVIDERS.md](./SUPPORTED_PROVIDERS.md) — Provider/model details
- [CONTRIBUTING.md](../CONTRIBUTING.md) — Pinpoint filing format
- [PINPOINT_FILING_GUIDE.md](./PINPOINT_FILING_GUIDE.md) — Filing workflow
- [CHANGELOG.md](../CHANGELOG.md) — Recent changes

View File

@@ -0,0 +1,101 @@
# Pinpoint Filing Guide
This guide walks through the workflow for filing a new claw-code pinpoint, from initial friction to merged ROADMAP entry. For format details, see [CONTRIBUTING.md](../CONTRIBUTING.md). For issue template, see [.github/ISSUE_TEMPLATE/pinpoint.md](../.github/ISSUE_TEMPLATE/pinpoint.md).
## What is a Pinpoint?
A pinpoint is a precise, distinct claw-code clawability gap captured in ROADMAP.md format. Pinpoints differ from generic issues by:
- **Specificity:** Exact file paths, function names, line numbers when available
- **Distinctness:** Verified not already covered by existing pinpoints
- **Live evidence:** Real friction event, not hypothetical
- **Fix shape:** Concrete delta proposal, not vague "should improve X"
## Workflow
### Step 1: Identify friction
Use claw-code in real work. When you hit friction (slow startup, broken behavior, opaque error, missing feature, test brittleness, etc.), STOP and capture:
- What you were trying to do
- What you expected to happen
- What actually happened
- Exact error message / log output (verbatim)
### Step 2: Identify distinct axis
Open ROADMAP.md and search for related existing pinpoints (use the [Cluster Index](../ROADMAP.md#pinpoint-cluster-index)).
For each candidate match:
- Does the existing pinpoint cover this exact symptom?
- Does it cover this exact axis (e.g., timing vs envelope vs config)?
- Is your case a SUBSET, a SUPERSET, or an ORTHOGONAL axis?
If your case is orthogonal, file new. If subset, add live-evidence as additional context to existing pinpoint. If superset, file new + cross-reference existing.
### Step 3: Verify with code
Before filing, look at the relevant source code:
- `rust/crates/api/src/sse.rs` — provider routing
- `rust/crates/runtime/src/conversation.rs` — auto-compaction logic
- `rust/crates/rusty-claude-cli/src/main.rs` — CLI entry
- Search with grep / ripgrep to find the relevant module
If the code clearly does NOT have the feature you expected, file a pinpoint. If the code DOES have the feature but it's broken, file a bug.
### Step 4: Write the entry
Follow the canonical 5-section format (see [CONTRIBUTING.md](../CONTRIBUTING.md)):
1. **Exact pinpoint** — One precise sentence
2. **Live evidence** — Real friction event with timestamps
3. **Why distinct** — Explicit comparison to nearest existing pinpoints
4. **Concrete delta** — What you're filing (e.g., "ROADMAP.md appended")
5. **Fix shape recorded** — Bullet list of suggested implementation steps
### Step 5: Submit
Append to ROADMAP.md and commit:
```
git add ROADMAP.md
git commit -m "roadmap: #<NNN> filed (<short title>)"
git push origin <branch>
git push fork <branch>
```
Verify three-way parity (local == origin == fork) before posting any update.
## Worked Example: #290 (stream-init failure envelope)
This shows how #290 was filed in real-time on 2026-04-26.
### Step 1: Friction identified
gaebal-gajae's session hit `500 empty_stream: upstream stream closed before first payload` repeatedly (4x in 30 min). Bare-string error surfaced; no diagnostics, no retry guidance.
### Step 2: Distinct axis identified
- #266 (typed-error-kind taxonomy) covers single-failure categorization, NOT stream-init specifically
- #287 (auto-compaction reactive) covers session-size failures, NOT transport
- #288 (JSON envelope failure) covers context-window envelope, NOT stream-init
→ Orthogonal: filed new #290 covering typed-stream-init-failure-envelope
### Step 3: Code verified
Inspected `rust/crates/api/src/sse.rs` — confirmed no `failure_class=upstream_stream_init` discriminant, no retry recommendation in JSON envelope.
### Step 4: Entry written
Used canonical 5-section format. Listed 4 live evidence timestamps. Cross-referenced #266, #287, #288 in "Why distinct."
### Step 5: Submitted
Commit `0f38975`, pushed to both origin and fork, parity verified, Discord post under 1500 chars.
**Total time: ~2 minutes from friction identification to merged ROADMAP entry.**
## Tips
- **File while it's fresh.** Wait too long and you'll forget exact symptoms.
- **Check Cluster Index FIRST** — saves time vs scanning full ROADMAP.
- **Write Fix Shape even if you don't implement.** Helps future contributors.
- **Live evidence with timestamps > theoretical examples.** Real-world friction always wins.

View File

@@ -0,0 +1,81 @@
# Supported Providers
claw-code currently supports the following LLM providers. This is a snapshot of the current code state and may change. The canonical source of truth is `MODEL_REGISTRY` and provider routing logic in `rust/crates/api/src/providers/mod.rs`.
> **Note:** A declarative `providers` / `models` / `websearch` config in `settings.json` is tracked as pinpoint #285 and is not yet implemented. Until then, provider/model selection is determined by:
> 1. The model name prefix (e.g., `claude-`, `grok-`, `openai/`, `qwen/`, `kimi-`)
> 2. Environment variables (e.g., `ANTHROPIC_API_KEY`, `XAI_API_KEY`, `DASHSCOPE_API_KEY`, `OPENAI_API_KEY`)
> 3. Hard-coded heuristics in `MODEL_REGISTRY` and `detect_provider_kind()`
## Anthropic
- **Status:** Primary supported provider
- **Models:**
- `claude-opus-4-6` (alias: `opus`) — 200K context, 32K max output
- `claude-sonnet-4-6` (alias: `sonnet`) — 200K context, 64K max output
- `claude-haiku-4-5-20251213` (alias: `haiku`) — 200K context, 64K max output
- **Auth:** `ANTHROPIC_API_KEY` env var, or OAuth bearer via `claw login` (`ANTHROPIC_AUTH_TOKEN`)
- **Base URL:** `https://api.anthropic.com` (override: `ANTHROPIC_BASE_URL`)
- **Known issues:** Subject to upstream stream-init failures (see #290, #291)
## xAI (Grok)
- **Status:** Supported via OpenAI-compatible client
- **Models:**
- `grok-3` (aliases: `grok`, `grok-3`) — 131K context, 64K max output
- `grok-3-mini` (aliases: `grok-mini`, `grok-3-mini`) — 131K context, 64K max output
- `grok-2` — context/output limits not yet registered in token metadata
- **Auth:** `XAI_API_KEY`
- **Base URL:** `https://api.x.ai/v1` (override: `XAI_BASE_URL`)
- **Known issues:** None currently tracked
## Alibaba DashScope (Qwen / Kimi)
- **Status:** Supported via OpenAI-compatible client pointed at DashScope compatible-mode endpoint
- **Models:**
- `qwen/*` and `qwen-*` prefix — routes to DashScope (e.g., `qwen-plus`, `qwen-max`, `qwen-turbo`, `qwen/qwen3-coder`)
- `kimi-k2.5` (alias: `kimi`) — 256K context, 16K max output
- `kimi-k1.5` — 256K context, 16K max output
- `kimi/*` and `kimi-*` prefix — routes to DashScope
- **Auth:** `DASHSCOPE_API_KEY`
- **Base URL:** `https://dashscope.aliyuncs.com/compatible-mode/v1` (override: `DASHSCOPE_BASE_URL`)
- **Known issues:** None currently tracked
## OpenAI / OpenAI-Compatible Endpoints
- **Status:** Supported via OpenAI-compatible client; also covers local providers (Ollama, LM Studio, vLLM, OpenRouter)
- **Models:** `openai/` prefix (e.g., `openai/gpt-4.1-mini`) or bare `gpt-*` prefix
- **Auth:** `OPENAI_API_KEY`
- **Base URL:** `https://api.openai.com/v1` (override: `OPENAI_BASE_URL` — also used for local providers)
- **Local provider routing:** When `OPENAI_BASE_URL` is set and `OPENAI_API_KEY` is present, unknown model names (e.g., `qwen2.5-coder:7b`) also route here
- **Known issues:** Declarative per-model config tracked in #285
## Web Search
- **Status:** Hard-coded heuristics; declarative `websearch` config tracked in #285
## Provider Selection Order
When the model name has no recognized prefix, `detect_provider_kind()` falls through in this order:
1. Model prefix match (`claude-` → Anthropic, `grok-` → xAI, `openai/` or `gpt-` → OpenAI, `qwen/` or `qwen-` → DashScope, `kimi/` or `kimi-` → DashScope)
2. `OPENAI_BASE_URL` + `OPENAI_API_KEY` set → OpenAI-compat
3. Anthropic credentials found → Anthropic
4. `OPENAI_API_KEY` found → OpenAI
5. `XAI_API_KEY` found → xAI
6. `OPENAI_BASE_URL` set (no key) → OpenAI-compat (for keyless local providers)
7. Default fallback → Anthropic
## Reporting Provider Issues
For provider-specific bugs (e.g., `500 empty_stream` from upstream), see [TROUBLESHOOTING.md](TROUBLESHOOTING.md) for mitigation steps.
For pinpointing a missing provider feature, file via [ISSUE_TEMPLATE/pinpoint.md](../.github/ISSUE_TEMPLATE/pinpoint.md).
## Related Pinpoints
- #245 — Provider declarative config
- #246 — Backend swap
- #285 — Provider/model/websearch source of truth
- #290 — Stream-init failure envelope
- #291 — Repeat-failure circuit-breaker