Method and limits
Facts are verified with git log, git show, and git log -S against AGENTS.md; dates and version tags come directly from repository commits. Interpretations are explicitly highlighted as such. Most commits feature descriptive commit messages referencing specific task IDs, enabling clear tracing of key design decisions.
This review inspects the historical lag between writing a rule in AGENTS.md and introducing the automated test that enforces it, corroborating the real-world value of the 9.0.0 lesson.
1. Figures
- 1,244 commits between 26 August and 24 October 2026, with activity on 57 of those 60 days; the peaks are still the early ones: 74 (02/09) and 65 (29/08).
- 238 commits since the 9.2.3 review (
924aef6, 16/10), over 9 consecutive days, peaking at 51 on 23/10; in that time 39 milestones closed (M5 to M43) and nine minor versions shipped, from 9.3.0 to 9.11.0. - Of those 238 commits, 212 list Claude Opus 5.5 as co-author; earlier, Claude Opus 5, Fable 5.1 and Antigravity (Gemini 3.8 Flash) also took part.
- The suite went from 864 cases in 9.2.3 to 702 in 9.11.0 while covering more features: milestones M24, M32 and M41 pruned trivial, duplicate or absence tests.
2. Evolution phases
Origins and initial growth (26 August – 16 September)
ChatCLI v0.9 emerges (39fed30), featuring multi-chat and voice recognition (later removed in cbc4cb1). Introduction of AgentCore and first MCP integration (969526e). The project is renamed to ZeroChat (ad107f4). Orama lexical RAG engine arrives and the first AGENTS.md is drafted on 02/09 (481c9c6, d37ff35). SVG vector icons, custom modal dialogs, and WebLLM (e20a70c, 11/09).
Backend and hardening (17 September – 4 October)
Frontend bundling step eliminated; zerochat.py unified in version 7.0.0 (f58544f). PyPI package release and backend modularization into py/ (b3db5f0). HMAC signature for tool calls (c51d0a8). ChatState domain slices with tests (2059455) and 0600 token permissions. First audited release with version 8.12.4 (aff1019).
8.12 series (4 – 9 October)
From 8.12.5 to 8.12.16: closure of audit findings with tests against empty catch blocks and untranslated literals, branch summaries, persistent project mode, and its memory protocol.
Towards 9.0.0 and the great cleanup (9 – 12 October)
Unbounded agent loop with loop detection (38ef6f9). Modern run_command and check_command tools replace legacy shell execution (514591d). Read-only subagents (ba21510). Forwarding reasoning traces across tool steps (a3e41b6). Removal of legacy compatibility layers (c1c66af, 8d769f7) and strict hygiene rules (f785a3f). Release of 9.0.0 (d2ab109) followed by 17 refactoring passes deleting 16,500 lines across js/, css/, and py/.
Closure of the 9.1.0 audit (13 October)
Review 9.1.0 closed all ten findings with automated tests in 14a7fab: persistence boundary protection (test_persistence_boundary.js), closed HTML sink whitelist (test_html_sinks.js), provider inheritance (test_providers.js), and help page consistency (test_help_pages.js).
9.1 to 9.2 series: Document maturity, multimodality and optimization (13 – 16 October)
A period of expanding capabilities while actively shedding technical debt:
- Office document ingestion and native parsing: Milestone M4 supported DOCX, PPTX, XLSX, and ODS in chat and RAG. Subsequently, milestone M17 (
ee7e732) replaced the heavy ExcelJS dependency with an in-house lightweight native XLSX parser injs/office-parser.js, cutting ~1 MB from vendor bundles and eliminating complicated external licenses. - Multimodal web vision (M19): Builtin
download_imagetool (88ede9e) allowing multimodal models to directly fetch, validate, and analyze web images with anti-SSRF protections. - In-chat document generation (M13): Interactive generation of HTML, SVG, and CSV documents in chat (
c9b0b0c), with secure Blob previews and CSV table exports. - Project memory automation (M9): Creation of
task.py(37ba6a0,cca1c87) to atomically record tasks, architectural decisions, and milestone states in.zerochat/, preventing memory desynchronization. - Test suite optimization (M5): Domain-based test suite consolidation (
ccf7bec), timer acceleration, andwithTestAppharness (468bf8b), reaching 864 tests running in seconds. - Documentation colocation and rules: Slimmed down
AGENTS.md(93766e5) by relocating subsystem contracts into colocatedREADME.mdfiles and capping tasks at ~300 lines.
9.3 to 9.5 series: own web transport and test pruning (16 – 17 October)
Public proxies are removed and web transport becomes the local server or, without it, Jina Reader, with DuckDuckGo search (M21, M23, M27; b15e953, 029b4c8). The external diff viewer arrives in the file-write cards (9.4.0, M20, 7541dca). happy-dom is removed and trivial or duplicate tests are pruned, with written criteria for keeping or deleting them (M24, 62682d7). The post-9.2.3 review is fixed in M26 (ca8ce1d).
9.6 series: unattended runs, profiles and Playwright (17 – 19 October)
zerochat --prompt runs a prompt in the interface and returns the answer in the terminal, with profile, export and hidden window (M18, from a4b9bbd). Connection profiles become configuration profiles, with the MCP services they start and the model's browser (M29). Playwright MCP gains its own engines, installed from Settings, and a mode with the user's browser (M3, 94ed197, 5b6a5b6).
9.7 and 9.8 series: scoped audits and live state (20 – 21 October)
Two scoped audits between minor versions close with their tasks (M30, M31) and the tests added since 9.2.0 are reviewed (M32). The local server becomes the single source of state that changes during a session: external services, commands and Playwright arrive in the heartbeat (M33, b92e9d7). The most complex frontend hotspots are simplified (M34, M35).
9.9 and 9.10 series: structure and reconnection (22 – 23 October)
PDF reader bounded by each stream (M36), guided diff viewer setup (M37), bilingual home page with a generated sitemap (M28, ba04ab0), model-view-controller separation in the dialogs (M38), interface logic tested without a browser (M39), automatic reconnection to the local server (M40, 7120ce7) and a suite that runs in half the time (M41). For using the home server from Android through an SSH tunnel, zerochat --print-url arrives; 9.11 replaces it with sign-in.
9.11 series: one way to connect (24 October)
Transport with the local server becomes POST-only, without an SSE channel (4e39189). The daily token also expires while the server runs (2476077) and, when it is missing or expired, the page asks for the user name and password of the system account (fb8dd4b). Settings › Connection unifies the local server, the SSH tunnel and the reverse proxy (6407dc1, 3f12d81). The design decisions were recorded before starting (M42-D10 to D17).
3. Rules and tests over time
| Rule | In AGENTS.md | Test added | Lag | What the test found upon arrival |
|---|---|---|---|---|
Dialogs with ChatDialogs | 09/09 (11a0389) | 09/09 (c87f69b) | 0 days | Zero defects; test existed from day one |
ChatState domain slices | 07/09 (3481a07) | 03/10 (2059455) | 26 days | Direct mutations on the ui slice |
| Explicit error handling (frontend) | 07/09 (3481a07) | 04/10 (cf7aca4) | 27 days | 116 empty catch blocks |
Visible text with ChatI18n | 06/09 (66a1967) | 04/10 (46b6228) | 28 days | 10 untranslated string literals |
| Explicit error handling (backend) | 07/09 (3481a07) | 12/10 (72deff7) | 35 days | Silent generic catches across 7 files |
Styles using tokens.css tokens | 06/09 (66a1967) | 12/10 (26abb4c) | 36 days | Literal color values and var() fallbacks across 58 files |
| No fallbacks, legacy compatibility, or test exports | 11/10 (f785a3f) | 11/10 (f785a3f) | 0 days (after 46 d) | The great 9.0.0 cleanup (16,500 lines removed) |
mount() with delegated listeners | 12/10 (98f07af) | 13/10 (9ff0df4) | 1 day | Duplicate listener attachments in MCP panel |
| Injected chat messages in English | 08/09 (cfdab94) | 13/10 (631f2d3) | 35 days | One system profile description in Spanish |
External data kept out of innerHTML | 13/10 (29a1af3) | 13/10 (29a1af3) | 0 days | Markup injection in SVG attributes in render_chart |
| Bilingual synchronized help pages | 13/10 (975a723) | 13/10 (975a723) | 0 days | API key help pages missing language switcher |
Memory automation and sentinel (task.py) | 14/10 (37ba6a0) | 14/10 (cca1c87) | 0 days | Prevents desynchronization in milestone plans |
Single source of truth and exact N/N+1 limits | 15/10 (b4aad8a) | 15/10 (976ab59) | 0 days | Row loss at the 500-row cap in ODS tables |
| No production code used only by tests | 17/10 (2b663f0) | 17/10 (2b663f0) | 0 days | Parameters and injections that only existed for tests |
| Sitemap and unique titles and descriptions | 22/10 (ba04ab0) | 22/10 (ba04ab0) | 0 days | Born with the bilingual home page and the generated sitemap |
| One source also between JavaScript and Python | 15/10 (b4aad8a) | 24/10 (f2e7224) | 9 days | Engines, browsers and the extension token, now in a fixture both suites check |
Interpretation: the lag between writing a rule and having its test was historically the main source of technical debt. Since the 9.x series almost every rule arrives with its test in the same commit; the recent exception, one source between JavaScript and Python, took 9 days because until M42 there was no fixture shared by both suites.
4. What history teaches
- Code improves by trimming dependencies: Replacing ExcelJS with a focused, native XLSX parser showed that simplifying architecture yields better maintainability than piling on vendor libraries.
- Tests must consolidate around domains: Reorganizing test suites in milestone M5 demonstrated that consolidating suites and removing synthetic delays increases test coverage (from 756 to 864 tests) while speeding up execution.
- Scoping tasks preserves control: Capping tasks at ~300 lines and creating shared bases before rolling out multiple format variants stops sister implementations from diverging.
- Fewer tests can cover more: from 9.2.3 to 9.11.0 the suite dropped from 864 to 702 cases while features grew, because each behavior is now tested once, at the lowest level that observes it.
- Decide before coding: in M42 the remote connection design was discussed and recorded as decisions before the first line of code; the seven tasks were then completed without redoing any.
Interpretation: 9.11.0 changes the local server's network surface more than any earlier version, and does so with the same discipline: every decision recorded and every new behavior with its test.
5. Summary timeline
| Date | Version | Commit | Key milestone |
|---|---|---|---|
| 26/08 | v0.9 | 39fed30 | ChatCLI creation |
| 02/09 | v5.3 | d37ff35 | First AGENTS.md |
| 09/09 | v6.5.4 | 11a0389 | Custom dialogs guarded by automated test |
| 11/09 | v6.6.0 | e20a70c | In-browser WebLLM integration |
| 17/09 | v7.0.0 | f58544f | End of client bundle; unification in zerochat.py |
| 04/10 | v8.12.4 | aff1019 | Audited release |
| 11/10 | v9.0.0 | d2ab109 | Great cleanup; unbounded agent and subagents |
| 12/10 | 9.1.0 | a0393c3 | Baseline of the 9.1.0 review |
| 13/10 | 9.1.0 | 14a7fab | Total closure of the 10 infrastructure findings |
| 14/10 | v9.1.2 | 37ba6a0 | Project memory automation with task.py |
| 15/10 | v9.1.5 | 8e449f8 | Office document support (Word, Excel, PowerPoint, ODS) |
| 15/10 | v9.1.6 | 1177dee | Native XLSX reader and removal of ExcelJS |
| 15/10 | v9.2.0 | 02710d7 | Bump to 9.2.0 with unified backend and office support |
| 16/10 | v9.2.1 | 2df3888 | In-chat document generation and table CSV export (M13) |
| 16/10 | v9.2.2 | 233ae57 | download_image tool and multimodal web vision (M19) |
| 16/10 | v9.2.3 | 924aef6 | Test suite consolidation (M5) and previous review |
| 17/10 | v9.3.0 | b15e953 | No public proxies; unified web transport |
| 17/10 | v9.4.0 | 8ce5e82 | External diff viewer |
| 17/10 | v9.5.0 | 09e2fcf | Web transport hardened after the 9.2.3 review |
| 19/10 | v9.6.0 | 07fc781 | Unattended runs, configuration profiles and Playwright engines |
| 20/10 | v9.7.0 | 957220a | Fixes from the scoped audits |
| 21/10 | v9.8.0 | d93491a | Live local server state in the heartbeat |
| 22/10 | v9.9.0 | 4de3d1f | Bilingual home page, PDF stream bounds and visible Playwright browser window |
| 22/10 | v9.10.0 | b8dea66 | zerochat --print-url for the tablet (removed in 9.11) and tool signatures with ±30 s clock skew |
| 24/10 | v9.11.0 | 170ee03 | Sign-in with the system account and Settings › Connection; reviewed version |
Authorship
- Review and drafting: Claude Opus 5.5 in Claude Code, from the Git history up to commit
170ee03; the phases up to 9.2.3 come from the previous review, by Antigravity (Gemini 3.8 Flash).