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
The 0.28.2 → 0.29.0 gap was missing a release entry for the work that
landed between them: PR #15 (triage spike upgrades + run_triage.py
wrapper + graceful sleuth_reminders handling), the classifier test-
isolation refactor (load_project_matchers gains an explicit
priority_rules override), and the test fixture client-name scrub.
Also refresh 4X4.md section C (last weeks accomplishments) to reflect
the now-5-job portability scope, the timezone centralization, the
triage upgrade, and the test-isolation fix. Add a sixth lesson under
section D: operator-path hygiene is a continuous regression surface
that warrants a baseline-aware audit, not a one-time grep — between
PR #18 opening and merging, two new launchd jobs landed on main with
the same hardcoded paths the PR was specifically removing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: 4X4.md
+5-4Lines changed: 5 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,14 +21,15 @@ B. CURRENT WEEK GOALS
21
21
4.[ ] Extend existing classification patterns beyond calendar so unattributed or low-confidence signals improve instead of repeating noise.
22
22
23
23
C. LAST WEEKS ACCOMPLISHMENTS
24
-
1.Fixed install portability across the operator surface: git-pulse auto-discovers local GitHub repos and keeps copied launchers in sync, and the rebalance-OS launchd jobs (daily, vault, pulse) plus the ask-self wrappers no longer hardcode one developer's home directory — fresh clones now install cleanly on any machine.
25
-
2.Recovered this Mac Studio from single-repo self-tracking to 49 watched repos and pushed a widened historical backfill that now reaches February 1, 2026.
26
-
3.Added recap and planning layers that clarified exact retrieval, dedupe, and SQLite as the next backbone rather than jumping straight to embeddings.
27
-
4.Reframed the product direction around an Obsidian-first dashboard, a canonical attention ledger, and a narrower rebalance-oriented MCP surface.
24
+
1.Hardened operator portability end-to-end: all five rebalance-OS launchd jobs (daily, vault, pulse, pulse-web, github), `pulse_server.sh`, and the ask-self wrappers now derive paths from script location; the five plists became `.plist.template` files with `{{REBALANCE_DIR}}` substitution at install time. Combined with the canonical app-data DB path and the `resolve_secret_path` chain shipped earlier, fresh clones install cleanly on any machine with no per-user editing.
25
+
2.Centralized timezone handling into a single`tz_utils.local_tz()` resolver — operator-facing timestamps in the terminal dashboard, pulse, and calendar reports now show device-local zone (resolved from `REBALANCE_TZ` → `/etc/localtime` → UTC) instead of hardcoded coast-specific fallbacks. Storage stays UTC; conversion happens only at display.
26
+
3.Upgraded the triage spike with three new buckets (close-candidates, stale-issues, stale-branches), fixed merged-PR filtering, milestone-due-date surfacing, and close-intent label warnings; shipped `run_triage.py` so the multi-step flow runs as one command.
27
+
4.Closed a test-isolation footgun: `load_project_matchers` now takes an explicit `priority_rules` argument instead of unconditionally reading operator-local `temp/rbos.config`, so tests that exercise the classifier (directly or via `generate_daily_report` / `generate_weekly_report`) no longer inherit host-machine brand rules. Scrubbed 15 fixture files of real client/org names in the same pass — the test suite is now portable to any collaborator without the operator's local config.
28
28
29
29
D. RECENT LESSONS LEARNED
30
30
1. Broad retrieval is useful for exploration, but a second brain needs verdict-first outputs to stay useful day to day.
31
31
2. Obsidian is the right operator surface, but computation and normalization must stay in SQLite plus MCP or CLI layers.
32
32
3. Exact attribution and low-noise classification matter more than adding another signal source.
33
33
4. Confidence must be visible; unresolved attribution should surface as review work, not hidden certainty.
34
34
5. Pipeline calibration needs first-class operator tooling: silent gaps (a watched-repo ingest that misses an event, a render module that ships without ARCHITECTURE.md / CHANGELOG.md fan-out, a working-tree change that drifts past a release) only surface when something explicitly looks for them. `rebalance raw` and `scripts/audit_modules.py` are the first two of these — both prefer a baseline-aware "fail on new drift" posture over "fail on all known debt" so they stay deployable from day one.
35
+
6. Operator-portability is not a one-shot fix — it's a continuous regression surface. Between the time PR #18 opened (3 plists templatized) and merged (5 plists templatized), two new launchd jobs landed on main with the same `/Users/<name>/...` hardcoded paths the PR was specifically removing. Test fixtures and `cleanup.sh` had the same drift. Treat operator-path hygiene the same way as `audit_modules.py` treats doc drift: a baseline-aware automated check that fails on new `/Users/[a-z]+/` in committed code, not a one-time grep during refactors.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+20Lines changed: 20 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -37,6 +37,26 @@ If you already had launchd jobs or ask-self wrappers set up against the previous
37
37
38
38
No DB or vault migration is required — only the install paths above change behavior.
39
39
40
+
## [0.28.3] - 2026-05-13
41
+
42
+
### Added
43
+
44
+
- Single-command triage wrapper [experimental/triage/run_triage.py](experimental/triage/run_triage.py). Wraps the multi-step triage flow (github-sync, sleuth-sync, `spike.py`) into one invocation with flags for `--sync`, `--publish`, and `--dry-run`. Existing direct `spike.py` workflows are unchanged.
45
+
- Two new triage buckets in [experimental/triage/spike.py](experimental/triage/spike.py): **close candidates** (scores open issues against merged PRs to surface issues likely already fixed) and **stale issues** (uses last-comment dates instead of `updated_at`, since the latter is bumped by edits/labels/assignee changes that don't indicate progress). A notes-section counter also surfaces orphaned remote branches whose `head_sha` matches a merged PR.
46
+
47
+
### Changed
48
+
49
+
-`load_project_matchers(db, config=None, *, priority_rules=None)` and `_build_matchers_from_priority_rules(rules=None)` now accept an explicit `priority_rules` override. `None` (default) preserves production behavior — read operator-local `project_priority_rules` from `temp/rbos.config`. `[]` skips operator rules entirely; a list of rule dicts injects test fixtures. Previously, any test exercising the classifier (directly or via `generate_daily_report` / `generate_weekly_report`) inherited whatever brand rules happened to be on the host machine, making test outcomes depend on the operator's local config. `tests/test_calendar_reports.py` drops its `setUpModule`/`tearDownModule` pair as a result; `tests/test_calendar_aggregator.py` shrinks similarly.
50
+
51
+
### Fixed
52
+
53
+
- The triage spike's **PRs unblocked** bucket now filters out merged PRs, requires CI-green status, excludes drafts, and adds a staleness warning when activity stalls. Previously merged PRs could appear because the filter relied on `state` alone.
54
+
- The triage spike's **release blockers** bucket now joins `github_milestones` to surface due dates and flags overdue items. Previously the rendered table had no time signal.
55
+
- The triage spike's **perf concrete** bucket now reads `labels_json` and warns on close-intent labels (`wontfix`, `duplicate`, etc.), reducing false-positive recommendations.
56
+
-`bucket_client_visible` in [experimental/triage/spike.py](experimental/triage/spike.py) now handles a missing `sleuth_reminders` table gracefully — catches `sqlite3.OperationalError` and returns an empty bucket instead of crashing the whole triage run when Sleuth hasn't been synced on this checkout.
57
+
- Eight test-suite failures carried over from pre-0.28 main are now resolved, restoring a fully green `pytest tests/` from a fresh clone.
58
+
- Real client/org names were scrubbed from 15 test fixture files (`Binoid` → `AcmeCorp`, `Bloomz` → `Mainline`, `CreditRegistry` → `AcmeReg`, etc., with longest-match-first to preserve substring relationships). Test fixtures no longer advertise real client relationships, and the suite is portable to anyone running it without the operator's `temp/rbos.config` priority rules.
0 commit comments