Follow-up from the supervisor review of PR #15 (stale-file protection, #4). The stale check compares disk_mtime != self._loaded_mtime (config_mtime returns Path.stat().st_mtime). Pure mtime equality can miss a concurrent external write when:
the external write lands within the filesystem's mtime resolution (coarse on some FS: FAT ~2s, older ext ~1s), or
a tool writes-then-restores content such that mtime is reset, or
clock/mtime is not monotonic across processes.
A missed detection means BCC silently overwrites an external edit (e.g. claude mcp add from a terminal) without showing the StaleDialog.
Not a data-loss emergency — write_config always backs up the pre-write file first, so the external version is recoverable from .bcc_backups/. But the whole point of #4 is to prompt before clobbering, and mtime alone can skip the prompt.
Proposed fix
Cheap hardening: pair mtime with file size (and optionally a content hash of just the server sections) captured at load and compared on save. disk_mtime != loaded_mtime OR disk_size != loaded_size catches the same-second/equal-mtime case at negligible cost. A full content hash is the most robust but heaviest; size+mtime is the pragmatic middle.
Acceptance criteria
Load-time snapshot records both mtime and size (extend config_mtime or add a sibling helper).
Save-time stale check triggers on a same-mtime-but-different-size external write.
Unit test: write a file, capture snapshot, rewrite with different content but force-set the original mtime (os.utime), assert the change is still detected.
bcc.py::MainWindow._loaded_mtime, the stale check in the save path
Filed directly by the supervisor (Cowork) session.
## Problem
Follow-up from the supervisor review of PR #15 (stale-file protection, #4). The stale check compares `disk_mtime != self._loaded_mtime` (`config_mtime` returns `Path.stat().st_mtime`). Pure mtime equality can miss a concurrent external write when:
- the external write lands within the filesystem's mtime resolution (coarse on some FS: FAT ~2s, older ext ~1s), or
- a tool writes-then-restores content such that mtime is reset, or
- clock/mtime is not monotonic across processes.
A missed detection means BCC silently overwrites an external edit (e.g. `claude mcp add` from a terminal) without showing the StaleDialog.
Not a data-loss emergency — `write_config` always backs up the pre-write file first, so the external version is recoverable from `.bcc_backups/`. But the whole point of #4 is to *prompt* before clobbering, and mtime alone can skip the prompt.
## Proposed fix
Cheap hardening: pair mtime with file **size** (and optionally a content hash of just the server sections) captured at load and compared on save. `disk_mtime != loaded_mtime OR disk_size != loaded_size` catches the same-second/equal-mtime case at negligible cost. A full content hash is the most robust but heaviest; size+mtime is the pragmatic middle.
## Acceptance criteria
- Load-time snapshot records both mtime and size (extend `config_mtime` or add a sibling helper).
- Save-time stale check triggers on a same-mtime-but-different-size external write.
- Unit test: write a file, capture snapshot, rewrite with different content but force-set the original mtime (`os.utime`), assert the change is still detected.
## Relevant code
- `bcc_core.py::config_mtime`, `external_change_summary`
- `bcc.py::MainWindow._loaded_mtime`, the stale check in the save path
_Filed directly by the supervisor (Cowork) session._
the_og
added the P2 label 2026-07-02 16:28:07 -04:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem
Follow-up from the supervisor review of PR #15 (stale-file protection, #4). The stale check compares
disk_mtime != self._loaded_mtime(config_mtimereturnsPath.stat().st_mtime). Pure mtime equality can miss a concurrent external write when:A missed detection means BCC silently overwrites an external edit (e.g.
claude mcp addfrom a terminal) without showing the StaleDialog.Not a data-loss emergency —
write_configalways backs up the pre-write file first, so the external version is recoverable from.bcc_backups/. But the whole point of #4 is to prompt before clobbering, and mtime alone can skip the prompt.Proposed fix
Cheap hardening: pair mtime with file size (and optionally a content hash of just the server sections) captured at load and compared on save.
disk_mtime != loaded_mtime OR disk_size != loaded_sizecatches the same-second/equal-mtime case at negligible cost. A full content hash is the most robust but heaviest; size+mtime is the pragmatic middle.Acceptance criteria
config_mtimeor add a sibling helper).os.utime), assert the change is still detected.Relevant code
bcc_core.py::config_mtime,external_change_summarybcc.py::MainWindow._loaded_mtime, the stale check in the save pathFiled directly by the supervisor (Cowork) session.