# Reported issues for Agent Coherence — Stale Write Guard (FS)

Pod holds 13 of 13 GitHub reports that passed its relevance review. This can include external user reports, maintainer-confirmed bugs, and concrete feature gaps. Treat them as evidence to inspect, not a count of distinct defects.

Back to [Agent Coherence — Stale Write Guard (FS)](/mcp/agent-coherence-stale-write-guard-fs).

## Most discussed

### GET /status omits each tracked artifact's last writer (last_writer_id)

**Update (2026-09-26):** §1 below is fixed on `dev` by #200 but not yet released. `sessions` is now built from the registry, so a grant holder the running coordinator has no name for is listed with `agent_name: null` instead of being dropped. Treating `sessions` as a lower bound, as "In the meantime" suggests, is still needed on 0.14.1, the latest release, but not on `dev`. Reading `artifacts.last_writer_id` from `state.db` is still the workaround for §2 until #235 (which replaced #227) lands…

[Read the thread](https://github.com/Cohexa-ai/agent-coherence/issues/199) · 2026-09-16 · closed · 4 comments

### GET /status omits grant age, last heartbeat, owner_generation and the reclaim thresholds at every tier

**Update (2026-09-26):** #200 fixed §1 on `dev`, and it no longer reproduces at `4de828f`. The same PR fixed both adjacent findings at the end of this issue. The issue now tracks §2 only and has been retitled to match. The original title, "/status reports sessions: [] while the registry still holds a live EXCLUSIVE grant", described §1. The comments below give the current state of §2 and what it is waiting on.

---

`GET /status` is the only read-side view of who holds what. Two things about it…

[Read the thread](https://github.com/Cohexa-ai/agent-coherence/issues/187) · 2026-09-16 · open · 3 comments

### GET /status emits raw session ids at the default tier, and no tier omits them

**Update (2026-09-26):** Two details in the report below describe the code as it was when this was filed. #200, merged 2026-09-16, changed `_handle_status` to build `sessions` from the registry's grant holders as well as from `agent_names_snapshot()`: a holder the name map does not know now gets a row with `agent_name: null`. #200 and later merges also changed both files quoted below, so `git diff v0.14.1 HEAD` over them is no longer empty. The disclosure itself has not changed on `dev`: at the…

[Read the thread](https://github.com/Cohexa-ai/agent-coherence/issues/198) · 2026-09-16 · closed · 2 comments

### pre-edit displaces a live EXCLUSIVE holder; no acquire-or-fail path

**Update (2026-09-26):** two statements below need correcting. The status of each part of this issue is in the comments.

- *"the client raises `CasVersionConflict version_mismatch artifact=plan.md expected=1 current=1`"*. Since #200, which is on `dev` but not yet released, a CAS refusal carries the coordinator's own reason. On `dev` this case raises `CasVersionConflict other_holder artifact=plan.md expected=1 current=1`. 0.14.1 still prints `version_mismatch`. The refusal itself is unchanged,…

[Read the thread](https://github.com/Cohexa-ai/agent-coherence/issues/196) · 2026-09-16 · closed · 2 comments

### No per-caller credential: hook routes take the acting identity from the body

## What happens today

The hook routes read the acting session identity out of the JSON request body and validate nothing but its shape. `_handle_pre_edit`, `_handle_post_edit`, `_handle_session_stop`, `_handle_pre_read`, `_handle_pre_bash` and `_handle_pre_grep` all do:

```python
session_id = body.get("session_id")
sid_err = validate_session_id(session_id)   # coordinator_server.py:311, UUID-shape regex only
...
agent_id = coordinator.register_session(session_id, read_subagent_id(body))
```…

[Read the thread](https://github.com/Cohexa-ai/agent-coherence/issues/188) · 2026-09-16 · closed · 2 comments

### A `write()` inside a peer's `write_cas_at` commit-to-disk window is lost, and the coordinator then disagrees with disk

## Summary

Suppose a plain `CoherentVolume.write()` lands while another volume's `write_cas_at()` sits between its confirmed commit and its disk write. Both calls return success. The file on disk ends up with the `write_cas_at` bytes, but the coordinator records the `write()` as the newest version, and the `write()` bytes exist nowhere. After that, readers get bytes that don't match the recorded version, and every `write_cas` / `write_cas_at` on the file fails with `ViewWedged` until a plain…

[Read the thread](https://github.com/Cohexa-ai/agent-coherence/issues/248) · 2026-09-26 · open · 1 comment

### Both hook clients turn a coordinator capacity rejection into a silent allow, even where strict mode would deny

**Update (2026-09-26):** two parts of the text below are incomplete. The comment below has the details.

- **Scope.** The plugin's Node hook client fails open in the same way. In strict mode the answer that gets dropped is a deny, not only a warning.
- **The suggested fix.** *"when the transport sees a non-2xx, emit the degraded envelope the timeout path already emits"* has three gaps:
  - Some saturated calls get a connection reset or a broken pipe instead of a non-2xx response (4 of 20 in one…

[Read the thread](https://github.com/Cohexa-ai/agent-coherence/issues/223) · 2026-09-22 · open · 1 comment

### validate_session_id accepts a trailing newline, which derives a different agent id

**Update (2026-09-26):** The second regression test suggested at the end of this issue is aimed wrong. The fix does not touch `session_to_agent_id`, so a clean id and its newline-suffixed twin still derive different agents after it. The test should instead pin that a trailing-newline id is refused before it becomes an agent: a 400, and no agent state recorded for it. The comment below has a test that does this. On current `dev`, the `.match` call cited below is at `coordinator_server.py:331`.…

[Read the thread](https://github.com/Cohexa-ai/agent-coherence/issues/222) · 2026-09-22 · open · 1 comment

## Most recent

### status, track and untrack commands print coordinator strings unescaped and exit 1 on a non-object error body

`agent-coherence-status`, `agent-coherence-track` and `agent-coherence-untrack` print strings from the coordinator without escaping control characters, and exit 1 with a traceback when an error body is not a JSON object.
Exit 1 is documented as "not in a git repo", so a script misreads the failure. Escape sequences and newlines in those strings reach the terminal as they are.

A real coordinator reaches only two narrow cases (see "How much of this a real coordinator reaches"). The rest needs a…

[Read the thread](https://github.com/Cohexa-ai/agent-coherence/issues/245) · 2026-09-26 · open · 0 comments

### Caller-principal files and rows are never reclaimed, and deleting only the files leaves that session uncoordinated

With the hook clients from #234 and Cohexa-ai/agent-coherence-plugin#162, each Claude Code session on the Python coordinator leaves two `.coherence/caller-principal-*` files and one `state.db` row, and nothing ever removes them.
Deleting only the files, the obvious cleanup, leaves every later edit in that session uncoordinated until the row is removed too.

Related: #234 and Cohexa-ai/agent-coherence-plugin#162 (where this code lives; both open), #188 (what they fix), #223 (the lasting `{}`…

[Read the thread](https://github.com/Cohexa-ai/agent-coherence/issues/244) · 2026-09-26 · open · 0 comments

### /hooks/pre-grep and GET /status read the registry outside the handler watchdog, so a contended lock stalls them

`/hooks/pre-grep` and `GET /status` read the registry outside the handler watchdog, so while the registry lock is contended they wait for as long as it is held. A Grep hook then runs past the client timeout and the model gets `{}` instead of the stale warning, and a volume that attaches in that window is refused as if the coordinator did not enforce strict mode.

Related: #245 (the status CLI's handling of the same `/status` output), #223 (both hook clients turn a capacity rejection into a…

[Read the thread](https://github.com/Cohexa-ai/agent-coherence/issues/238) · 2026-09-26 · open · 0 comments

### Eight idle connections hold every coordinator handler slot until they close; the handler has no read timeout

Eight TCP connections that open and send nothing fill every coordinator handler slot, and keep those slots until their owner closes them. While they are open, every request is refused, hook calls included, so a stale-read warning is lost and a strict-mode deny does not block the call.

Related: #223 (the client side of the same saturation). Checked by running a coordinator and by reading the source, on `dev` at `4de828f` and on #234. The #234 column in the table below was measured at `86b880e`.…

[Read the thread](https://github.com/Cohexa-ai/agent-coherence/issues/237) · 2026-09-26 · open · 0 comments

### Strict mode: timed-out pre-edit allows a stale edit with no warning; late handler bodies log denies never sent

In strict mode, when `pre-edit` misses the handler deadline, the coordinator allows the edit with no warning, even for a session whose view of the file is stale. The abandoned handler then finishes and records a strict deny the caller never received: counters, route-around marker, `audit.log` line and a CRITICAL log. `pre-read`, `pre-bash` and `pre-grep` record the same unsent deny on a timeout.

Related: #246 (acquire-or-fail, which needs its own answer next to the `pre-edit` timeout constant…

[Read the thread](https://github.com/Cohexa-ai/agent-coherence/issues/236) · 2026-09-26 · open · 0 comments

The remaining reports are on [the project's issue tracker](https://github.com/Cohexa-ai/agent-coherence/issues).
