changed_entries(before,after,limits): pure diff that flags only NEW/CHANGED
over-limit entries, ignoring unchanged legacy fat — so rollover (trims by count,
writes back recent fat entries) is never rejected. Wired into write_memory_file
via _validate_entry_limits (gates only .trinity/{local,observations}.json): warn
mode logs+writes, enforce mode rejects new/changed over-limit only. Validation
wrapped in try/except → a validator bug can never abort a write. +15 tests (917
total), seedgo 100%, enforce stays false. Verified by artifact incl. live proof
of rollover-safety + the defensive guarantee. @memory side (P1-3) complete. The
changed_entries() helper is what @hooks imports next. Part of DPLAN-0205.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pure check_entry(type,text,limits) validator (chars not bytes, boundary at cap,
unknown-type safe) reusable by both gates. New 'drone @memory lint run' scans all
branches' .trinity via registry, handles dict+list containers and both
key_learning value shapes, sorts worst-first — strictly READ-ONLY (never writes/
trims, honors never_trim_s153). Phase-1 unused_function bypass removed (reader now
called). +12 tests (902 total), seedgo 100%. Verified by artifact incl. live lint:
513 over-limit entries across 17 branches (devpulse worst at 71, top offender
5724/600). enforce still false. Part of DPLAN-0205.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Config-driven char caps for .trinity memory entries. Phase 1 = foundation only:
adds entry_limits section to memory.config.json (4 caps: learnings 200, sessions
300, todos 200, observations 600) and the load_entry_limits(branch) reader
(deep-merge per_branch overrides, safe-defaults on missing/malformed). Reader has
NO callers yet (Phase 3 wires it) — unused_function bypass is intentional.
Verified by artifact: 14/14 tests, seedgo 100%, scope clean. enforce:false →
zero behavior change. Part of DPLAN-0205.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Memory files now reconcile to template, not just clean known fields:
- normalize.py: rewrote from field-targeted cleanup to template-conformance —
strips ANY key not in the template at every level (root/metadata/limits/status).
Kills legacy orphans (old 'st' blocks, active_tasks, current_lines, max_lines)
that field-targeted cleanup was blind to. Fixed _MEMORY_ROOT path (parents[3])
that silently skipped template loading in production.
- memory_watcher.py: wired normalize_memory_file into both scan paths
(check_and_rollover + on_modified) with a write-loop guard — drift now
self-heals on every trigger, no manual run needed.
- line_counter.py: stop writing current_lines (entry-count is the only metric).
- LOCAL/OBSERVATIONS templates: removed line-count fields.
Entry-count is the sole rollover metric, both files, all branches.
873 tests pass, seedgo 100%.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
_get_json_handler() was reading sys.modules[] directly after _fresh_json_handler
had just popped the module out. importlib.import_module() replaces the lookup so
the module is actually imported fresh each test. Also removes dead reload/pop
code from the fixture that never ran. Fixes 27 failures (issue #360 finding A2).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- pyproject.toml: add memory = ["numpy>=2.0", "chromadb>=1.0"] optional-deps group
- setup.sh: install .[dev,memory] so fresh-clone pytest works end-to-end
- test_vector.py: gate with pytest.importorskip("numpy"/"chromadb") — skip cleanly without extras
- memory_watcher.py: _check_vector_deps() probes venv at startup; health report now honest when chromadb absent
- bypass.json: 4 entries covering test_vector.py seedgo false-positives (architecture/docs/encapsulation/meta)
- dispatch/daemon.py: resolve relative branch_path to absolute before use
- dispatch/dispatch_monitor.py: resolve lock_file path so claude cwd is always absolute
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(system): fix(windows-ci): combine pip bootstrap fix + venv activation in Verify step
Combines both fixes needed to get windows-test.yml actually passing:
1. setup.sh: stop swallowing ensurepip errors (quiet + 2>/dev/null + || true was
hiding real failures — pip was silently not installed). Add get-pip.py fallback
and hard pip verification.
2. windows-test.yml: add 'source .venv/Scripts/activate' to Verify step. Each CI
step gets a fresh shell — setup.sh's venv activation doesn't carry over, so
drone wasn't on PATH in the subsequent step.
Together, these should take Windows CI from the 'silent failure every run since
creation' state to actually green. Supersedes PRs #330 and #331 which had the
fixes on separate branches (neither green alone).
Co-Authored-By: @devpulse <devpulse@aipass>
* feat(system): chore(lint): ruff auto-fix sweep — 303 errors across 178 files (F401 unused imports + F541 f-string placeholders + F811 redefined); restored report_error re-export + added logger call in errors.py
Co-Authored-By: @devpulse <devpulse@aipass>
---------
Co-authored-by: @devpulse <devpulse@aipass>
* feat(system): ci: add Windows setup test workflow — runs setup.sh + drone CLI verification on windows-latest GitHub Actions runner. Triggers on changes to setup.sh, handler __init__.py files, cli.py, or pyproject.toml. Closes the 'we never tested on Windows' gap.
Co-Authored-By: @devpulse <devpulse@aipass>
* feat(system): fix(windows): SIGPIPE guard in flow.py (#301) + fcntl platform guards in trigger/config.py and watchdog/registry.py (#302) — lazy import fcntl on Unix only, no-op on Windows. inbox_lock.py already cross-platform (msvcrt). ai_mail.py already guarded (hasattr check).
Co-Authored-By: @devpulse <devpulse@aipass>
* feat(system): fix(windows): handler guard backslash path fix — all 11 __init__.py files (#304). caller_file.replace('\\', '/') normalizes Windows paths before the same-branch check. This is the actual fix for #293 which was incorrectly closed. drone is completely broken on Windows without this.
Co-Authored-By: @devpulse <devpulse@aipass>
---------
Co-authored-by: @devpulse <devpulse@aipass>