You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Privacy.CODING_SH_PURGE_WAIT_MS sets how long purge waits for another process's read of the index or the blob pack before it says which file still holds the old bytes. The defaults stay 10 s before the VACUUM and 5 s after it. Configuration.
Trace format. A JSON Schema (draft 2020-12) for AgentEvent and Session, generated from the TypeScript types, ships as coding.sh/schema.json and is served at https://coding.sh/schema.json. Every adapter and OTLP fixture validates against it. Trace format
Serve.CODING_SH_FORWARD_URL (or [serve.forward]) makes coding.sh serve forward every trace it commits to an OTLP/HTTP collector, with the same trace and span ids plus coding_sh.project. Native batches go out as invoke_agent, execute_tool and chat spans. Metadata mode sends no messages, tool arguments or results; a down collector never slows ingest, spans wait in a bounded buffer, and overflow is counted in coding_sh_forward_spans_total. Forward and sinks
Sinks.[[sinks]] now mirror events from the OTLP receiver (coding.sh collector) and from coding.sh serve, so a team can set one sink on serve instead of on every laptop. Config
Serve.createFetchHandler() from coding.sh/server runs serve's ingest routes (OTLP, /v1/ingest, /readyz) as a Request → Response function for Vercel Functions, Deno, Bun or Workers. With coding.sh-store-postgres, several instances can write one session at once: each session rebuild takes pg_advisory_xact_lock on the session id. Serverless
Evals. Cases and tool-eval tasks take an optional kind: bad (fails before the change, passes after), guard or control (pass on both). exp run, exp compare, toolevals run and toolevals compare split results by kind and name broken controls as overcorrection, and toolevals validate --against <variant> reports a bad task that passes on the old variant. See Case kinds and Task kinds.
Tool evals.coding.sh toolevals traces <server> --sessions 'since:30d' (or --from <experiment>) prints each MCP tool's calls, errors, repeats and retries after an error, and --out <dir> writes the failing traces first (at most 3 passing), an index.jsonl, tool-health.json and tools.json for an improver to read. Held-out trials are never exported. Tool evals
Tool evals.toolevals run --shell-model <provider/model> has a model play the shell for a model driver on a CLI target, with a fixed date; the shell model is part of the arm name and compare refuses arms with different shells. Tool evals
Tool evals. The model driver's MCP client reads resources and prompts, counts progress notifications, runs task-augmented tool calls, answers sampling with the driver's model, elicitation with a task's scripted [mcp] answers and roots with the sandbox, and runs OAuth (discovery, client registration, PKCE or client credentials) on a 401. calls checks can match resources/read by uri and prompts/get by name. MCP client
Tool evals. The model driver caches the prompt on Anthropic (top-level cache_control; promptCache = false turns it off) and reads the final cache counts from the stream; the report shows cost with cache prices beside flat prices, the cache hit share, and says when the cheaper arm flips. Tool evals
Cache.diff-calls gives the line where a system prompt edit starts and the share of the prompt after it that the cache could no longer read (system.firstChangeLine, system.wastedPrefixFrac in --json and the viewer API). When over 20% is lost, Why says to move dynamic content such as timestamps to the end of the system prompt. Capture with the proxy
Experiments.compare --signals checks whether each session flag and tool errors predict failure beyond task difficulty: pooled, within-task and within-task-and-bundle AUROC with a task-cluster CI, beside difficulty, bundle and length references, and a verdict (adds-run-signal, tracks-difficulty, no-signal, too-few-pairs). Evals guide
Experiments.exp sweep and a matrix spec in exp run, with three or more configs or cells, name the plausibly best set: the configs not significantly worse than the best, by a paired-bootstrap multiple comparison with the best, which holds the truly best config 95% of the time. Evals guide
Experiments.compare --pick N --pick-by irt fits a Rasch (or 2PL) model on stored runs and runs first the tasks with the most information at the baseline's ability: mid difficulty, sharp discrimination. Evals guide
Experiments.exp run --record saves each case-trial's Anthropic and OpenAI calls, and exp run --replay <EXP> serves them again up to the first changed call (--replay-until N stops after call N), so a late change re-runs only the calls it touches. System-prompt and cache_control edits still replay; API keys are never stored; with one task, the recorded config runs as a control arm and compare prints its noise floor. See docs/how-to/replay-llm-calls.md.
Experiments.exp run --seq K --feedback bit|reasons|critic=<grader> tries a failing case-trial again with feedback on its earlier attempts, up to K attempts, and reports Seq@1..K with intervals, EGS/LGS, unchanged revisions, cost to solve and, with 2+ trials, pass@k against seq@k by cost. The pass rate stays the first attempt's; feedback never shows the expected answer; exp compare adds a seq@K row and --verdict seq (arXiv 2610.37859). Evals guide.
Experiments.exp run --failing <EXP>, --errors-from, --case <PATTERN>, --sample N --seed S and --first-n run part of a dataset. When B ran only on A's failures, exp compare warns of regression to the mean, says inconclusive and --gate holds until A's config runs on the same cases. Evals guide.
Experiments.exp run stores the experiment so far while it runs; after a crash exp list marks it (partial), and exp run … --resume <experiment> runs only what is left (--retry-errors also re-runs its task errors). A resume with other graders, trials, task, dataset version or case selection is refused and names what changed. Evals guide.
Experiments.exp sweep --guard <dataset>|prior re-runs the start and winning configs on earlier suites and keeps the start config, exit 1, when the winner breaks more than --guard-tau of what the start solved there, even when the target suite ships. Shipped sweeps are remembered in adoptions.jsonl for --guard prior. Evals guide.
Experiments.exp compare takes --pairwise more than once: it reports each judge, Cohen's κ between judges, and replicated-better, judges-disagree or unresolved, screens out a judge whose calibration failed, and with --gate holds a ship when any judge prefers A or two judges do not both find B better (arXiv 2611.04090). Evals guide.
Experiments.exp compare --labels-a --labels-b corrects each LLM judge grader's B − A with human labels of each arm's outputs (PPI++), and warns when the judge errs differently on the two arms. Evals guide.
Refine.coding.sh refine mine ranks failure patterns across sessions with no model call: session flags, normalized error lines (20 TS2307 errors in 5 sessions are one pattern), instructions you typed again and again, and failed eval runs, each with its count, sessions and example events, redacted. refine propose --mined FILE shows the top patterns to the proposer. Mining failure patterns.
Refine.coding.sh refine diagnose asks a model what went wrong in recent sessions and groups the answers into Signals with stable ids; refine signals lists them. Every problem needs a citation that code checks against the redacted trace, severity is computed by code, replies are cached so a rerun makes no call, and with no API key it prints a $0 plan of the sessions and tokens it would send. Diagnosing sessions into Signals.
Refine.refine test|run --suite --canary-model <model> re-tests a kept edit that deletes or rewords lines (--canary all: every kept edit) under a cheaper model and rejects it as canary-regression when the pass rate falls there; refine recheck <r_…> --model runs the same check later. A subtractive edit kept without a canary gets a note. Wrapper agents take a {model} slot in their flags. Canary re-test.
Refine.coding.sh refine distill writes an experiment's runs (or recent sessions) as a redacted corpus, leaving out held-out tasks, and has Claude Code or Codex analyze it with its own code and write one skill in an isolated directory. The skill is size-capped, checked by the critics and ledgered as a proposed candidate with its provenance for refine test. Distilling a skill.
Refine. The proposal prompt lists, per earlier edit that was not kept, the tasks it fixed, regressed and left failing, read from the ledger, and asks for lines aimed at the still-failing tasks. With no such rounds the prompt is unchanged. Refine loop.
Export.coding.sh export --evidence <dir> writes each matching session as a folder of files: index.md with stats and a timeline, session.json, events.jsonl, and one file per tool call with its input and full output. Everything is redacted first, files are size-capped, and the same store gives the same bytes. Query and export.
Privacy. An opt-in PII pack: capture.redact = ["secrets", "pii"] also redacts email addresses, phone numbers, card numbers (issuer prefix and Luhn check), IBANs (country length and mod 97) and national ids (US SSN, UK NINO, Canadian SIN). Each kind (phone, card, iban, national-id, email) can be turned on alone. Privacy.
Evals. Typed scores: a number, true or false, a category or text on a session, event, dataset case or eval run, from a person, judge, code, the API or a monitor. Score configs fix a name's type and range, and a value outside it is refused. Add and list them with coding.sh score, POST/GET /api/scores and /api/score-configs, or the score_add and score_list MCP tools. Existing labels move into scores as human pass or fail scores, and labels stays readable as a view. Scores
Capture.coding.sh doctor --conformance runs each agent's backfill over the transcripts on this machine and checks the events: duplicate ids, timestamps, tool and subagent pairing, parent links, double-counted usage, sessions without a prompt and failed commands marked ok. It only reads, never opens the store, and exits 1 on a violation. Troubleshooting.
Explore.coding.sh stats and the viewer's new Explore page (#/explore) show sessions, failure rate, cost, tokens, tool error rate and p95 model-call time per day or week, split by agent, model, repo or flag, from one engine that GET /api/metrics also serves. Explore sessions, API.
Viewer. A model call in coding.sh ui opens in a playground: the call is rebuilt as system prompt, messages and tools, you edit it, run it against Anthropic, OpenAI or any OpenAI-compatible server, see the answer beside the recorded one, and save it as a dataset case. Explore sessions, API.
API.GET /api/sessions/{id}/rows pages through one turn of a long session, with runs of routine events folded and failures always shown; the outline adds turns, failures, compactions, subagents and a minimap; GET /api/events/{id} returns one event; and GET /api/blobs/{sha256}?range=a-b reads part of a blob. API.
Viewer. The viewer page arrives with the first sessions page drawn and its first responses embedded, so the list shows before the script runs (on Slow 4G with a 4x slower CPU, the first row shows about 2.7 s sooner, 95% CI 2.71 to 2.75 s), and a session the pointer rests on, the keyboard moves to, or a press lands on loads in the background, so it opens without a request. Explore sessions.
Harness A/B.compare grades each run in a fresh copy of the task's start tree plus the agent's source changes. A conftest.py, sitecustomize.py, .pth or .npmrc the agent wrote, an edited test config or Makefile, and a changed test script in package.json no longer reach the verifier, and each run records what was left out in isolation. --no-isolation grades the agent's own tree. Verifier isolation
Harness A/B. The compare report adds cost and tokens per solved task, pass@k, pass^k and the flaky tasks with --k 2 or more, and how many paired tasks would detect the observed effect at 80% power. Efficiency, reliability and tasks needed
Harness A/B.compare --otel gives each agent an OTLP endpoint, a TRACEPARENT and coding_sh.run_id in its resource attributes, so the spans it exports are stored with the run and join its session. OpenTelemetry per run
Harness A/B.compare --sequential runs each arm's tasks in order and carries the agent's home (or --carry <path>) from one task to the next, and the report adds the pass rate by position. Sequential runs
Attribution.coding.sh attribution matches the lines each commit added to the captured session that wrote them, from the session's snapshots or its edit tool calls; a rebased commit still matches, and a session is credited only for files it could have written. coding.sh blame <path>[:line] shows it per line, and coding.sh attribution export writes Agent Trace (agent-trace.dev, RFC 0.1.0) records. git-ai notes are read as a second source. Read-only on git. Attribute commits.
Harness A/B.compare --pick N and --budget <USD> run the tasks that best tell harnesses apart in stored runs first and tasks every run passed last. --budget fits the tasks to an estimated cost, caps the spend and shows the estimate in the consent prompt; --dry-run lists the picks and runs no agent. Picking tasks and a budget
Judges.judge grade --trace reads codex exec --json, Cursor stream-json and OpenAI chat or Responses request bodies, and exits 2 with trace_incomplete when tool calls in the file did not reach the judge; --allow-partial-trace grades anyway with a warning, and --json carries traceCoverage. Checklists and trace checks
Judges."abstain": true on an llm-checklist lets the model answer cannot_decide and name what is missing; the item leaves the score, a critical abstention fails the case as undecided, and judge calibrate counts undecided cases apart. Without it, prompts and version ids are unchanged. Checklists and trace checks
Judges. An llm-panel grader: one judge per provider scores 1-10 and the median decides, the pass target never reaches the prompt, anchor cases are re-scored fresh to report drift per member, and advisory members are shown but not counted. Judge panels
Judges.pairedDiscrimination from coding.sh/judge measures whether a judge reads the trace: each passing case gets children with the same output and a failure in the trace (skipped verification, failing final test, ignored tool error, destructive command, skipped test), and the report gives the flag-rate difference per kind with an interval. Does the judge read the trace?
Judges.createWasteJudge from coding.sh/judge asks a model which spans of a session were restated, padding, duplicate fetches or detours, drops fabricated quotes and misread streams, and prices the waste in output tokens. Waste judge
Evals.coding.sh eval candidates (and the MCP tool eval_candidates) ranks captured sessions as eval tasks. Subagents, runs, and sessions with no git start, no prompt or no edits are left out; the rest are ordered by failure flags, pushback, a guessable verifier and recency. eval init --sessions drafts from that ranking and says how many it left out. Your agent's failed sessions.
Evals.eval init --where '<query>' --validate drafts tasks from the sessions a query matches and validates each one. A session diff that passes the verifier becomes the reference and the task is marked validated. Tasks from flagged sessions are tagged captured-failure, and eval run (and the GitHub Action's comment) says which of them now pass. Your agent's failed sessions.
Evals.eval new --statement ledger writes the task instruction from every user turn and approved proposal, as cited obligations, instead of the first prompt only. With --judge a model merges them and drops the ones a later turn replaced, and code checks every citation and the leakage of the reference patch. Session to eval.
Evals.eval trigger <skill> --draft writes triggers.toml. It starts from the prompts of this repo's captured sessions that loaded the skill (should) or a sibling skill (should_not), then has a model fill each side to 8. Mined prompts are redacted, each prompt records its source, and the reply is cached. Evaluate an Agent Skill.
Capture. A tool call that loads a skill names it on its tool.start (payload.skill, and payload.skills when it loaded several): a Skill tool call, a read of a file under an agent's skills/<name>/ folder, a cat, head or sed of one by a literal path, or an MCP read of a skill:// resource. Every adapter goes through the same check. Adapters.
Capture. Copilot CLI hook events keep the OpenTelemetry trace from the traceparent Copilot 1.0.107 passes its hooks, and ingest records which session the trace belongs to, so an OTLP span of that trace that names no conversation lands in the hook session. Adapters.
Export.eval export --format atif writes the task's source session as an ATIF-v1.8 trajectory (redacted, with subagents embedded). --format harbor now writes task.toml schema 1.4 with an explicit verifier mode, and the trajectory under solution/. Both pass Harbor 0.25's loaders. Session to eval.
Compare.coding.sh compare --parity <A> <B> reads two pages (URLs, or commands that print one) and lists the fields that differ: status, redirects, title, description, canonical, robots, og: and twitter: tags, the hreflang count and JSON-LD types. It exits 0 on parity, 1 otherwise. Page parity.
Cost.coding.sh cache doctor grades the prompt cache (hit rate, A to F) and ranks what broke the cached prefix by extra cost: model switches, tool set changes, a volatile line such as a timestamp in the system prompt, other system prompt changes, rewritten history, idle gaps. Each cause has its break count, sessions, tokens re-billed, the fix and a diff-calls example. Prompt cache health.
Cost.coding.sh usage --baseline and the MCP usage tool's baseline compare each agent's cache hit rate with Requesty's published rate for that agent (April 2026), as a signed point delta, - for an agent it does not list. Without the flag the output is unchanged. Prompt cache health.
Experiments.codingShReporter (from coding.sh/eve) is an eve eval reporter: each eve eval run becomes a dataset version and an experiment with a grade per assertion, sent to coding.sh collector or to coding.sh serve with an ingest key. Skipped evals are listed, repeats become trials, the server redacts before storing, and a re-sent run is stored once. eve guide.
OpenTelemetry. The receiver reads reasoning tokens (gen_ai.usage.reasoning.output_tokens, the AI SDK's reasoningTokens, Codex's reasoning_token_count, Gemini CLI's thoughts_token_count) into payload.reasoningTokens on the llm.call; skills (gen_ai.skill.name, Claude Code's skill_activated, Codex's codex.skill_invocation) as payload.skill and a skill:<name> tag; gen_ai.conversation.compacted and Claude Code's compaction event as context.compact; and gen_ai.main_agent.name, Claude Code's agent_id/parent_agent_id and Codex's codex.agent_response for the agent and its subagents. Spans without them map as before. OpenTelemetry.
OpenTelemetry. An eve or durable-harness agent can send its Agent Runs spans to coding.sh collector as well as to Vercel, with one extra span processor; each run becomes a session with its turn, model calls, tool calls and usage, under the agent durable-harness for durable-harness. Tee Agent Runs.
Collector.coding.sh collector import --clickhouse <url> reads agent traces from an OpenTelemetry Collector's ClickHouse otel_traces table (Map or JSON attributes) into the local store, with the same mapping, redaction and pricing as spans posted to the collector. It keeps its place per table and row filter, so a second run imports nothing new; --since, --from-start, --where, --table, --all, --dry-run and --json shape it. Pull from ClickHouse.
Docs. A guide to whether a terse mode saves money on your tasks: run them with and without a be-concise rule, skill or plugin, read pass rate and cost with intervals, and split output tokens from the input the instruction adds. It cites our A/B of a terse-output plugin: output −8%, cost +11%, same pass rate and clarity. Its commands are checked against the CLI in tests. Terse mode guide.
Benchmarks.bench show and the report add a routing headroom check: the any-contender pass rate against the best single contender, compared with a Rasch model where no contender specializes, so per-case routing is only suggested when the gap beats run noise. Routing headroom
Benchmarks. Contenders that cross models with harnesses (agents, or axes = { model, harness } on any contender) get a grid: interaction residuals with intervals, rank reversals, Cross-Model Fit per harness and leave-one-model-out regret. Model × harness grid
Capture.coding.sh run -- aider records each reply's tokens and cost while Aider runs: the wrapper reads Aider's analytics log (a temp AIDER_ANALYTICS_LOG, or the log you named) and the cache split from its chat history, so live Aider sessions have usage and cost, not only eval runs. Adapters
Cost. CLIProxyAPI is a gateway: sessions whose base URL is on port 8317 (or CLIPROXYAPI_URL) are tagged gateway:cliproxyapi, and gateway enrich --gateway cliproxyapi reads its usage queue with the management key and joins each record to its llm call by session id, or by time and model. The call gets reasoning effort, service tier, speed, time to first token, compaction, tokens, upstream cost and a hashed account id. The read empties the queue for other readers, so it runs only when named, prints a warning, and keeps every record until it joins. LLM gateways.
Sessions. An agent started by another agent's shell tool (codex exec or gemini -p from Claude Code's Bash tool) is linked to that session as a child of type harness, and coding.sh show lists it under the parent. The link comes from the session id Claude Code and Codex export to the commands they run, else from the parent's shell call that ran the child's CLI while the child started in the same directory. Concepts.
Workflows.coding.sh ui shows workflow runs at #/workflows: one bar per agent grouped by phase, the critical path outlined, barrier idle shaded, a concurrency strip against the cap, links to each agent's session, and per-phase and metrics tables. On a phone it opens as a table. The page reads /api/workflows, the same documents workflows show --json prints. Workflows guide
Workflows. Verifier cases take named [[truth.tests]] and score the share that pass, reporting tests marked before = "pass" that fail after the run as regressions. Judge cases (kind = "judge", a rubric) are graded by an LLM judge and flagged uncalibrated until coding.sh judge calibrate has calibrated that judge version. workflows run now scores every case kind as workflows score does. Workflows guide
Workflows.workflows run checks each seeded bug on its case's [start] snapshot before any run: the bug's test fails seeded and passes with the patch reverted (--no-validate skips it). A case whose truth file sits inside its [start] tree no longer loads. Workflows guide
Workflows. A command-driver variant with fromCheckpoint or replayFrom passes --from-checkpoint <id> or --replay-from <node> to the program, for LangGraph checkpoint forks and node replays. Workflows guide
Store. Every one-way index migration first keeps a copy of the index next to it (index.db.v<N>.bak, a copy-on-write clone where the filesystem has one; a full copy is refused with the space it needs when it would not fit), and coding.sh upgrade-store --restore puts it back. The index it replaces is kept as index.db.v<N>.undone. Troubleshooting
Changed
Docs. An adapter that nobody has run on a live install is now labelled "Not run live" in the README, the agents guide and the site. Only Cursor CLI and Amp are in that state; both need an account login. Agents
Improve.improve check says Helped only when failures fall: the flagged share, or one flag (Holm-adjusted) with no other rising significantly in its place. A new line the agent follows while flagged sessions stay put is now "Followed, no effect yet", and a change after which sessions make 1.25x the tool calls or take 1.25x as long, with no fall, is "Costlier"; both suggest refine test git:<previous> to test the harness without it. --json adds work and next. Regressed and its exit 1 are unchanged. Improve.
Tool evals. The model driver's 16 KB tool-output cap is structure-aware by default: JSON stays valid and keeps every key, and logs keep whole lines; output under the cap is unchanged. outputCap = { mode = "prefix" } on a driver or variant brings back the old byte cut for an A/B, and the report counts cuts and broken-JSON cuts. Tool evals
Sessions.stats.toolErrors, repeated-tool-failure and the failure-streak derail count only real failures. A search that found nothing (grep, rg exiting 1 with no output), a probe that answered no (test -f, command -v) and a diff that found differences are counted in the new stats.benignToolErrors, and a stopped call in stats.interruptedToolCalls. Stored sessions are counted again on the next ingest. API.
Sessions. A shell command run from a REPL or code tool's cell (bash("npm test"), subprocess.run(["pytest"]), os.system, an IPython ! line, a %%bash cell) counts as verification for no-verification, as the same command in a shell tool does. Concepts.
Sinks. The otlp sink sends gen_ai.usage.input_tokens as the whole prompt, cache reads and writes included, as the OpenTelemetry GenAI conventions ask; it used to send only the uncached part, so backends undercounted cached calls. Cache writes move to gen_ai.usage.cache_write.input_tokens (the old cache_creation.input_tokens is still sent through 0.1.5), the uncached part is coding_sh.usage.uncached_input_tokens, and reported reasoning tokens are gen_ai.usage.reasoning.output_tokens. The OTLP receiver reads the sink's spans back to the same token counts and cost. Export to ClickHouse.
Search. Every search word must match a whole word, and only the last may start a longer one, so the fix no longer matches every word that begins with "the". Matches come best first, and a search with more than 20,000 matches lists them newest first instead of ranking them all. On a 756k-event store, search for "the", "voxel" and "error" answers in 34, 12 and 38 ms at p95 instead of 719, 171 and 81 ms. The Postgres and ClickHouse plugins and --where bare words match the same way. CLI reference, Storage.
Store. The index is about a quarter smaller. The search index no longer keeps its own copy of tool text, each working directory is stored once, and an unused index is gone. On a 756k-event store, after gc --compact, it takes 1.38 MB per 1,000 events instead of 1.89. The upgrade builds the new search index and leaves old rows as they are; gc --compact empties their old copies and gives the space back. A coding.sh older than 0.1.5 refuses the upgraded index and says to upgrade. Storage.
CLI.--agent, --tag, --session and the other repeatable id flags take a comma list: --agent claude-code,codex is the same as --agent claude-code --agent codex, on sessions, usage, search, export and the rest. CLI reference.
Collector.coding.sh collector stores concurrent requests together, in one transaction with one blob flush, and no longer keeps every source span as a blob (--keep-raw turns that back on; serve still keeps them). On the desk, 8 clients posting 61-span requests went from 1,437-3,075 to 5,585-6,865 spans/s, with request p95 from 283-613 ms to 125-155 ms. A long session per client is not faster. OTLP collector.
Capture. Outside Windows the hook agents run is a POSIX sh script, ~/.coding.sh/bin/hook.sh, which writes the same spool line without starting node: under bash 5, about 3 ms more than /bin/true per hook call for payloads up to 256 KB, instead of about 30 ms (Hook). It hands --reply, eval runs, gateway base URLs and anything else it does not cover to hook.mjs. Run coding.sh init again to switch existing hooks. Adapters.
Docs. The instructions file is called AGENTS.md wherever any agent is meant: the home page, docs titles and prose, command examples, --help and the MCP tool descriptions. Lists of the files coding.sh reads start with AGENTS.md, and the site, the docs, --help and the hints coding.sh improve prints name no other instructions file: where a sentence is about one agent's own file, it says "the agent's instructions file". The five-minute guide moved to /docs/how-to/test-agents-md-change; the old URL redirects to it. No command changed which file it reads or writes. Test an AGENTS.md change in five minutes.
Docs. The docs pages are shorter and easier to skim: each starts with what it is for and one real example, flags are in tables, and depth sits in "How it is computed" blocks or behind a link. A site test keeps bullets, paragraphs and guide pages within word budgets. Experiments.
Query. A date without a zone in --since, --until, since: and until: is local time: 2026-11-09 is local midnight (it was UTC midnight) and equals 2026-11-09T00:00:00. today and yesterday work, and until is exclusive. sessions, usage and stats print the resolved window on stderr and carry window in --json. The MCP tools read times the same way, and GET /api/metrics reads a date without a zone as midnight in the request's tz, the zone its buckets use, so the first and last day of a range are whole days. Query reference, API
Query.sessions --where with event.duration or error alone reads an index instead of every event. On a 1.4M-event store on the test desktop, --where 'event.duration>60s' went from 840 ms to under 1 ms and --where 'error:*timeout*' from 2.7 s to 3 ms. The first run upgrades the index once (schema v11), with progress on stderr and the old index kept beside it; that store (2.7 GB) took 59 s and grew by 1%. Query reference
CLI. Default --json reads are digests an agent can afford. sessions --json rows, tree --json nodes and status --jsonlatest drop stats.phases and each derail's eventId and index. show --json on a session over 200 events prints events: [] with eventCount and the phases unless --limit N or --all is given, each event drops sessionId (and agent/cwd when equal to the session's), and subagents lists the first 50 with subagentCount and subagentsTruncated. tree --json and MCP session_tree return 50 nodes a page with nextCursor and truncated (--limit/--cursor; MCP limit up to 200). New --fields a,b.c on sessions and show picks paths from the full document. Explore guide
Harness.harness audit (CLI and MCP) reads session rows instead of every event: ingest keeps the memory and instruction files each session's events name in stats.memoryUse. On a store of 3,600 sessions and 1.4M events it takes 0.4 s and 132 MB, where it took 10 to 27 s and up to 969 MB. After an upgrade the audit reads events as before until an ingest has refolded the stored sessions. Memory and instruction files
Viewer. Moving through sessions and steps with the keyboard is instant: rows snap, the query suggestions and pills do not animate or push rows under the cursor, and a held j or k stays smooth in long sessions. Counts read "1 tool call", large costs and token counts keep their separators, long durations roll up to days, relative times keep refreshing, and long titles, model ids and file names stay readable. In the benchmark table a long cost source no longer pushes the cost out of its column. Viewer
Fixed
Capture. A secret written as NAME=value right after a newline no longer survives in a stored raw payload blob. Every string is redacted before the payload is serialized. Privacy
Capture. Once ingest has stored a hook line, it rewrites that line's spool/<agent>/raw/ payload file with secrets redacted. The docs now say a payload written inside its spool line stays as written until gc. Privacy
Capture. A failed Codex shell command is now stored as failed with its exit code, from the hook and the rollout alike, so tool.errors counts it and sessions --where "tool.errors>0" finds the session. Adapters
Sessions. A Claude Code session whose model calls arrive both over OTLP logs and from its transcript now counts each call once, so its tokens and call count match the transcript. Agents guide
Sinks. A sink gets each event once when an agent hands the same one over in two spool lines (a Claude Code helper's events come from both the parent's Agent call and the helper's own stop), so a consumer that sums chat spans no longer overcounts tokens. Config
Evals.compare on one task reads the runs of that task: a Newcombe interval for the difference of the two pass rates and Fisher's exact test, labelled as holding for that task only. It no longer prints a zero-width bootstrap, McNemar p = 1.000 or a tasks needed line from one task, and --json adds report.oneTask. Evals
Docs. The Langfuse comparison now says the viewer has a playground that reruns one model call; only prompt management is missing. Compare
Attribution. A session is credited a file from the tree diff only when its tools named the file or it ran a shell or subagent call; a named file takes the lines its edit steps added, not the diff. Lines a person typed in the same window match no session of a run that only read files. A session that ran a shell tool can still be credited a file a person wrote by hand, at lower confidence. Attribute commits
Cost. A Claude Code subagent whose transcript sits under more than one session is stored once, under the session that wrote it. A workflow run resumed in another session (resumeFromRunId), a symlinked run dir or a fork used to store each copy as its own subagent session, so its calls and cost counted again. Adapters.
Cost. Copies already in the index are removed on the next re-parse. A session an older coding.sh stored from a copy of another session's transcript (a Claude Code subagent copied into a resumed workflow run or a fork) is deleted with its events once the session that wrote it is stored, so its calls and cost stop counting twice. Re-parse used to keep it as a session whose transcript is gone; a session whose transcript is really gone is still kept. ingest --rebuild prints how many it removed. Troubleshooting.
Cost. Claude Fable 5.2 and Mythos 5.2 are priced at their own rates ($8 input, $40 output, $0.20 cache hit, fast mode $16/$80) instead of Fable 5.1's $10/$50, which put standard calls 25% high and fast calls 37.5% low. Stored sessions are repriced on the next ingest. Prices.
Privacy. A purge given a wait (CODING_SH_PURGE_WAIT_MS, or waitMs in code) now keeps to it while another process reads the index. The checkpoint before the VACUUM used to wait the full 10 s whatever wait was given. Privacy.
Store. An index upgrade on a store of 100,000 events or more no longer runs silently. It says so on stderr within a second, prints its progress at most once a second, and ends with how long it took and, when old data is left, gc --compact. A command that opens the index while another process upgrades it waits and prints that process's progress. Upgrading a 740k-event store from schema v2 took 20 s instead of 119 s. Troubleshooting.
Docs. Status claims match the code and the registries again. Tool evals and workflows are tagged built, and coding.sh, @codingdotsh/sdk and the Postgres, ClickHouse and S3 store plugins are no longer called unpublished; the Python SDK is still not on PyPI. The dogfood plan gives each step's state with code pointers. A site test fails when a page calls something planned whose module exists, or when the agent list disagrees with the adapters in the code. What is built.
Sinks. Metadata sinks no longer receive a session's stats.llmErrors.error text, which could quote the prompt. Config
Privacy. The env redactor no longer replaces PWD, OLDPWD or variables named *_PATH, *_DIR, *_FILE or *_SOCK, or any value that is an existing path, so the working directory stopped turning into [redacted:env] in every path. Privacy.
Capture. A Claude Code response with parallel tool calls is one llm.call again, with its usage counted once. Claude Code writes a tool's result between the lines of the response that called it, and each part used to become its own call; the call is now timed from the request's api-request line. A subagent that another subagent spawned hangs off that subagent's session instead of the main one. Stored sessions are parsed again on the next ingest. Adapters.
Capture. A Codex subagent thread has a prompt and a title: the task its parent sent it (an agent_message addressed to the thread) is its user.message, with from, taskName and encrypted. Codex encrypts the task text, so the prompt says which agent asked for which task. Adapters.
Capture. OpenCode history imports when OpenCode has set its database aside as opencode.db.schema-mismatch-<ms> and not yet written a new one, and doctor says when a database has no session tables coding.sh knows or cannot be opened, where backfill used to import nothing without a word. Adapters.
Capture. An Antigravity command that exited nonzero is a failed tool call with its exitCode, read from the result's The command exited with code N. line, and the result's Created At/Completed At time it. Every Antigravity tool call used to count as ok. Adapters.
Sessions.show, tree, usage, improve, harness audit and the other reads answer within the read budget while a re-parse runs, from what is indexed. show, tree, usage, replay and harness audit used to ingest every pending capture first, with no budget. They leave the spool to the re-parse, say how many files wait (on stderr, or pending with reparsing: true in JSON), and a session not found says it may be among them. Configuration.
OpenTelemetry. A span that reports a cache read or cache write of 0 tokens no longer adds cacheReadTokens: 0 or cacheWriteTokens: 0 to the call's usage; non-zero counts and cost are unchanged. OpenTelemetry.
OpenTelemetry. eve's agent.step and approval spans become notification events (eve.step, …), as the eve mapping documents, instead of generic span events. eve.
Capture. The sh hook no longer hangs when an agent starts it with stdin closed. Under macOS /bin/sh and bash 3.2 it never exited and left a child process behind. It now treats a closed stdin as an empty payload and exits 0 at once, as hook.mjs does. Adapters
Capture.hook.sh no longer fails the agent's hook call when it hands an event to hook.mjs and node cannot run (not on the agent's PATH, a version manager's shim that fails, a missing hook.mjs): it exits 0 and still prints the --echo-continue reply. Before, an eval run, a gateway base URL or --reply made the hook exit 127 on such a machine. That event is not captured. Adapters
Capture. Claude Code hooks registered in two settings files with different commands (user settings on hook.sh, a project's .claude/settings.local.json still on node …/hook.mjs) no longer store each prompt, turn end and session end twice. The spool lines of one hook firing (the same payload, at most 2 s apart) get the same event ids; the same prompt sent again later is still a second event. coding.sh init also looks for project hooks at the root of the repository it runs in, reports them and skips the user install unless --force. Stored Claude Code sessions are parsed again. Adapters
Capture. A session whose hooks ran with a stale CLAUDE_CODE_SESSION_ID or CODEX_THREAD_ID is no longer hidden as a subagent of a session that is not in the store or had already ended. The marker links a child only when the named session is in the store and was open when the child started; stored sessions with such a parent become top-level after the refold. Concepts
Capture. When the ingest the hook starts fails, coding.sh status, the status line and coding.sh doctor print ingest stopped 4h ago with the command that fixes it, and status --json and doctor --json carry ingestStopped. status prints the home, the spool and that line even when the store can't be opened. Troubleshooting
Store. The store records the coding.sh version that last wrote it. A build that is not a newer release than that one (a source checkout, a stale dist) no longer migrates the index by itself, with or without a bin/: it stops with store_version, and coding.sh upgrade-store migrates on request. Troubleshooting
Store. The error for a store a newer coding.sh already migrated says captures are safe in the spool, how many files wait there, which version wrote the store, and to run coding.sh update; it offers upgrade-store --restore when a copy from before the migration is kept. Troubleshooting
Store.coding.sh upgrade-store always leaves bin/cli-path naming the running coding.sh (also when there is no bin/, or it names a CLI that is gone), and upgrade progress counts events instead of the highest rowid. Troubleshooting
Doctor. An agent whose hook is not installed or is blocked is a ! warning row with every blocker and the file and line to change (Codex: config.toml:<line>); recent events alone no longer earn a check mark. The last line is N agents not capturing instead of ok, and doctor --json lists them under warnings. ok and the exit code still report spool and store health only. Troubleshooting
Cost.usage and cache doctor total every session in the window; they stopped at the newest 2,000 without saying so. Past 100,000 sessions (CODING_SH_SCAN_CAP) they print Stopped after N sessions: narrow --since or --where. and set truncated in --json. Configuration
Cost.coding.sh cache doctor counts every session in the window in its breaks, re-billed tokens, extra USD and grade, so they match usage whatever --limit is. --limit (default 200) now only bounds how many sessions are read to classify causes: a session past it keeps its stored cause or counts as unclassified, and --json adds breaksNotRead. Before, the totals and the grade covered only the sessions that were read. Explore
Cost. A gateway enrich record with no upstream cost no longer removes (estimated) from a session's cost. Only a record with a billed cost marks the call as billed. LLM gateways
Gateways.gateway enrich --gateway cliproxyapi no longer joins another client's usage record to your call. A record whose session id is not in the store is kept for a later run, a record joins by time and model only when it has no session id, and records that name a session join first, so each call gets its own tokens, cost and account. LLM gateways
Gateways.gateway enrich --gateway cliproxyapi no longer joins a failed or retried CLIProxyAPI request to a call that answered, which gave every later call its neighbour's usage record. A failed record joins only a call that failed, a record that answered joins only a call that did not fail, and a call whose token counts equal the record's wins over a nearer one. A failed record with no failed call is kept for a day, then dropped. LLM gateways
Gateways. After init --proxy chains through a gateway (CLIProxyAPI, OpenRouter, LiteLLM, …), new sessions keep their gateway:<name> tag: the proxy names the gateway on each call it logs, also in capture mode metadata. gateway status and doctor report the route, marked "through the coding.sh proxy". Capture with the proxy
Gateways. A background re-parse, refold or end-of-turn snapshot no longer drops the gateway:<name> tag and the billed cost that gateway enrich stored at the same moment. A session that got events while its row was being built is folded again before the row is written, and gateway enrich stores its events and the session rows in one transaction. LLM gateways
Sinks.coding.sh serve and coding.sh collector now send the otlp sink a session's invoke_agent span while the session is still open: once it has been quiet for 10 seconds, and every 60 seconds while it stays busy. An OTLP session keyed by a conversation id (Claude Code, Codex, gen_ai.conversation.id, Agent Runs) never ends, so it used to reach the sink as chat and execute_tool spans with no parent and no session row. Each send repeats the span id with newer totals, and the ClickHouse queries now take the latest row per span id. Export to ClickHouse
Sinks.coding.sh serve and coding.sh collector send an event to [[sinks]] once. A request that was posted again, such as a client retry answered "inserted":0, used to send all its events again and doubled rows and cost downstream; now only the events a batch newly stored go on, and a batch that overlaps stored events sends the new ones. A commit that fails after its events were written sends them when the retry commits. Forward and sinks
Sinks. Local ingest now sends the events it imports from agent transcripts to [[sinks]], not only the events from the hook spool, so a sink has every model call the store has. When an import adds events to a session without ending it, the otlp sink gets the session's invoke_agent span again with the new totals. A sink that is down does not stop the import and catches up after its backoff, and a second ingest sends nothing new. Config
Collector.coding.sh collector import keeps its place per table and row filter (--all, each --where), so a run without the filter reads the rows a filtered run skipped. A --since given on the command line reads from that time again, and the new --from-start does the same with the default 7 days, for a root span that reached the table more than an hour late. Nothing is stored twice. Pull from ClickHouse
Collector.coding.sh collector import stores each page with its sessions before it saves its place, so a run that loses ClickHouse part-way leaves no events without a session. A dropped connection or a 502, 503 or 504 is tried three more times; a run that still fails says how many spans it read and prints the command that reads the rest. Before, the next run exited 0 with fewer sessions than traces. Pull from ClickHouse
Privacy. A source span or log record that coding.sh serve or coding.sh collector --keep-raw keeps as a blob, and an oversize structured value moved to a blob, is now redacted one string at a time (a string that holds JSON as JSON) before it is serialized. A NAME=value line after a newline and a JSON field such as api_key or password used to stay in clear in the stored blob and were served by /api/blobs/<sha>, while the event showed them as redacted. Blobs stored before 0.1.6 are not rewritten: remove such a value with coding.sh purge. Privacy
Refine.refine signals show <id> takes the Signal id or a prefix of it again; it rejected every id with Unexpected argument. An unknown id says No Signal <id> in <file> and exits 2. Diagnosing sessions into Signals
Refine.refine log, the refine test verdict line and the refine apply refusal lead with the canary's reason for a round the canary rejected or left inconclusive, not the reason the candidate was first kept. Canary re-test
Refine.refine distill --keep-corpus DIR no longer deletes a directory that holds a file named SCHEMA.md next to other work. Only a directory that holds nothing but an earlier corpus is replaced, entry by entry; any other non-empty directory is refused and left as it is. With --dry-run nothing is written to DIR. Distilling a skill
Refine.refine diagnose --session takes an id prefix or latest, as show does. An id that matches no session is a not-found error (exit 1) instead of an empty plan. Diagnosing sessions into Signals
Refine.refine mine reports failed eval runs with the default --repo: a run counts for the repo when its task starts from it or belongs to a suite under its evals/. The summary line and --json (evalRuns) say how many eval runs were read. Mining failure patterns
Improve. A Helped line from improve check now names every flag whose share rose after the change, significant or not, as in repeated-tool-failure rose 4 to 8 of 12, not significant. The verdict is unchanged: one flag falling is Helped unless another flag rose significantly. Improve guide
Judges. A ran-command check with "ok": true no longer passes a failed command on OpenAI chat and Responses traces. judge grade --trace reads the exit code a tool result states on a line of its own (Process exited with code 1, exit code 0), and a result with no status or exit code makes the item N/A, not a pass. Checklists and trace checks
Judges.judge grade --trace exits 2 with trace_incomplete for a file cut mid-line, a record with no type, role or kind, and a file with no JSON records; it used to grade them as whole traces. --json counts them in traceCoverage.unparsedLines and unreadRecords. An agent's plain-text stdout as the default trace is still no trace. Checklists and trace checks
Evals.eval new --statement ledger keeps a reply that approves and goes on ("yes, but call it goodbye instead") as its own obligation, after the proposal it changes. A short reply that opened with an approval word used to count as a bare approval, so the instruction asked for the assistant's proposal and dropped the user's change. Session to eval
Evals.eval init --validate no longer marks a session that rewrote the test as the validated reference. A session diff that edits, deletes or skips the tests the verifier runs is kept as a near miss, with or without --validate, and a note names the test file. A diff that only adds test cases to a test file still counts as a reference. Your agent's failed sessions
Evals.eval trigger <skill> --draft reads only the sessions of the current git repo, so a triggers.toml you commit no longer holds prompts typed in other projects. --repo DIR reads the sessions under another directory and --repo all reads every repo's. Does the skill load?
Evals.coding.sh score add event:<id> --session <ID> (and POST /api/scores with a sessionId) no longer stores a score on an event that is not in the store, or under another session. An unknown event is event not found (exit 1, HTTP 404), and a session that is not the event's own is refused with both ids named (exit 2, HTTP 400). Scores
Evals. A stored score keeps its type. A value that reads as another type (1,5 over a number, 0.5 over a pass or fail label) is refused (exit 2, HTTP 400) and names --type and score config, instead of quietly turning the score into a category. --type, dataType or a config for the name still change the type, and score add now prints the type: Scored n1 = -5 (numeric). Scores
Experiments.compare --signals no longer gives a verdict from too few tasks. A signal needs task+arm pairs from 8 tasks or more, however many pairs there are; below that the verdict is too-few-pairs and the table says how many tasks it found. With one task the 95% CI column shows –, where it used to print a zero-width interval such as [0.65, 0.65]. A coin-flip signal on one task with --k 10 used to get adds-run-signal in about 45% of tables. --json adds withinTaskArm.tasks to each row. Evals guide
Tool evals.toolevals validate --against <variant> --driver <d> no longer counts a trial where the agent never worked on the task as a failing trial. A logged-out agent, a failed setup step, an agent that could not start (exit 127) or one that exited non-zero before its first turn used to make every bad task look like it holds; each such task is now reported as couldn't run on <variant> with the reason (infra: auth, agent never ran, exit 127) and does not hold. toolevals run records the same never-ran trials with an error. Task kinds
Benchmarks. Routing headroom now prints the best single contender's own pass rate, the one on the leaderboard, and measures the gap and its expected range from it. With several trials it used to average the best contender of each trial, so the rate beside the name was too high and the gap too small. Runs stored before the fix keep their old numbers. Routing headroom
Benchmarks. The model × harness grid no longer states noise as fact. A rank reversal is listed only when the 95% interval of both pass-rate gaps excludes 0, each leave-one-model-out regret and the mean carry a 95% interval (regretCi and meanRegretCi in --json), no cell is starred under 20 paired cases, a bound that rounds to 0 no longer stars some cells of a 2 × 2 and not others, and the legend says the stars are per cell and not adjusted for the number of cells. Model × harness grid
Attribution. Without snapshots (a store filled by ingest --backfill, or a session whose end snapshot is gone), a session is credited only for the lines its own Write, Edit and patch calls added, less the ones it later removed. Lines a person added to the file between two of the agent's edits used to be credited to the session once the agent read the file again. Sources cached by an older build are built again. Attribute commits
Attribution. A person's copy of a long line in another file of the same commit no longer takes the session's credit. Every file of a commit gets its same-file matches before a long line may match across files, so blame credits the agent's own line and shows - for the copy. Attribute commits
Attribution. A commit made on a branch that was no longer checked out when the session's end snapshot was taken got 0 lines, because an empty or unrelated snapshot diff hid the session's own edit tool calls. coding.sh attribution and coding.sh blame now take every file the session's tools named that the snapshot diff does not hold from those calls, at confidence 0.8. Attribute commits
Compare.compare --parity reads a tag whose attribute value holds a raw > in full, so two pages that differ after it no longer read as the same. Page parity
Viewer. "Open in playground" works for model calls in subagent and workflow-agent sessions: the request is rebuilt from the subagent's own conversation, without the calls of a subagent it started. Every such call used to answer 404 no_request. API
Docs. The troubleshooting page lists each error reason under the exit code the CLI gives it, and the session rows example in the API reference is the real answer for the page's example session. Errors by reason, API