Repository navigation
fix(daily-insight): honor SUTANDO_WORKSPACE — write to workspace, not repo - #832
Merged
Merged
Conversation
This was referenced May 18, 2026
sonichi
added a commit
that referenced
this pull request
May 18, 2026
#815) (#836) * fix(workspace): honor SUTANDO_WORKSPACE in 5 scripts — same bug class as PR #815/#832/#833 Audit per owner's "REPO_DIR might be more places than #815" — confirmed 10 bugs across 5 scripts all hitting the same workspace-vs-repo distinction the bridges fixed pre-PR #762. Each was resolving per-user-state paths (logs/, results/, state/, build_log.md, core-status.json, pending-questions.md) to the repo root instead of $SUTANDO_WORKSPACE. ## src/health-check.py — 6 sites - L314 voice-agent.log freshness check → WORKSPACE_DIR/logs - L598 core-status.json proactive-loop liveness → WORKSPACE_DIR - L681 build_log.md critical-file check → WORKSPACE_DIR - L795 bridge log-staleness check → WORKSPACE_DIR/logs - L807 bridge heartbeat check → WORKSPACE_DIR/state - L1171 restart-on-fix subprocess stdout redirect → WORKSPACE_DIR/logs WORKSPACE_DIR was already wired in this file (line 42 from earlier work); just substituting the right call sites. Code paths (src/*.py, src/*.ts, node_modules, .env, Sutando.app binary, subprocess cwd) correctly stay as REPO_DIR. Effect: health-check no longer false-positives "log stale / heartbeat missing / sutando-app not running" when services are actually fine. Real issues (voice-agent code stale, discord-bridge code stale) now surface cleanly instead of being lost in the false-positive cascade. ## src/event_log.py - L53–54: REPO_DIR/logs → WORKSPACE_DIR/logs (LOGS_DIR module global) - L71: personal_path(...) workspace arg → WORKSPACE_DIR ## src/check-pending-questions.py - L20: WORKSPACE = Path(__file__).parent.parent → resolve_workspace() This one was particularly silent — the cron's been firing for weeks reading the wrong file. After fix: surfaces the 2 long-pending questions (May 9 email-organize, May 13 web-UI bundle/fork) that the friction detector also found. ## src/call-stats.py + src/scan-call-logs.py - Both hardcoded `Path(__file__).parent.parent / "results" / "calls" / ...` - Now use resolve_workspace() (same pattern as daily-insight.py PR #832 + friction-detector.py PR #833) call-stats verified post-fix: now reads 2 real calls; previously read 0 on workspace-only installs. ## What's NOT in this PR - health-check.py L693 (notes-dir) — leaving to James's PR #815 to avoid conflict; same bug, same fix. ## Verification $ python3 src/health-check.py # core-proactive-loop ok, no false positives $ python3 src/check-pending-questions.py # Notified: 2 pending questions $ python3 src/call-stats.py # 2 real calls, Friday busiest $ python3 src/scan-call-logs.py # No new calls to scan (total: 2) * test(health-check): mock WORKSPACE_DIR not REPO_DIR for core-status check PR #836 moved core-status.json read from REPO_DIR to WORKSPACE_DIR (per-user runtime state, not code). The test still mocked REPO_DIR, so case e ('running with 5-day-old ts should be warn') silently failed against the real workspace's core-status.json instead of the temp fixture. Update write_status, with_repo_override, and case_b_status_malformed to mock WORKSPACE_DIR. All 17 cases pass. CI flagged by Chi in Discord, 2026-05-18. --------- Co-authored-by: Chi Wang <4250911+sonichi@users.noreply.github.com>
qingyun-wu
force-pushed
the
fix/daily-insight-honor-workspace
branch
from
May 18, 2026 18:58
6c6e4c2 to
08c7fad
Compare
qingyun-wu
added a commit
that referenced
this pull request
May 18, 2026
… not repo Same workspace-path bug as daily-insight.py (PR #832): WORKSPACE was hardcoded to Path(__file__).parent.parent (repo root), causing FileNotFoundError when results/friction-{date}.txt couldn't be written to the wrong path. Verified before: tried /Users/.../github/sutando/results/friction-2026-05-18.txt → FileNotFoundError Verified after: writes /Users/.../sutando-workspace-001/results/friction-2026-05-18.txt → OK Output: surfaces 3 real friction items (2 long-unanswered questions, 1 stale task). Both this and PR #832 close out the friction-detector + daily-insight half of the workspace-path-violation pattern previously fixed in the bridges.
sonichi
pushed a commit
that referenced
this pull request
May 18, 2026
… not repo (#833) Same workspace-path bug as daily-insight.py (PR #832): WORKSPACE was hardcoded to Path(__file__).parent.parent (repo root), causing FileNotFoundError when results/friction-{date}.txt couldn't be written to the wrong path. Verified before: tried /Users/.../github/sutando/results/friction-2026-05-18.txt → FileNotFoundError Verified after: writes /Users/.../sutando-workspace-001/results/friction-2026-05-18.txt → OK Output: surfaces 3 real friction items (2 long-unanswered questions, 1 stale task). Both this and PR #832 close out the friction-detector + daily-insight half of the workspace-path-violation pattern previously fixed in the bridges.
This was referenced May 18, 2026
… repo
daily-insight.py hardcoded WORKSPACE = Path(__file__).parent.parent, which
resolves to the repo root (/Users/.../github/sutando/) instead of the
canonical $SUTANDO_WORKSPACE. As a result the daily 06:50 cron crashed
with FileNotFoundError when results/insight-{date}.txt couldn't be
written to a path that doesn't exist under the repo.
Verified:
Before: tried to write /Users/qingyunwu/Documents/github/sutando/results/insight-2026-05-18.txt → FileNotFoundError
After: writes /Users/qingyunwu/Documents/github/sutando-workspace-001/results/insight-2026-05-18.txt → OK
Output: "You've made 2 calls total. Peak hour: 1:00 ..."
Same workspace-path-violation pattern that landed in earlier fixes for
the bridges; uses the canonical resolve_workspace() helper.
Closes the daily-insight half of feedback_workspace_path_resolution.md.
qingyun-wu
force-pushed
the
fix/daily-insight-honor-workspace
branch
from
May 18, 2026 19:13
08c7fad to
db6c88e
Compare
sonichi
added a commit
that referenced
this pull request
May 18, 2026
closes #840) (#841) The describe block shares one spawned web-client child for all subtests. Tool-track 'working' set in one subtest can linger into the next when CI scheduling delays the async 'clear-tool' POST that the producing test issues at its tail. Two unrelated PRs flaked on this same suite today (#836 and #832), both on workspace-fix PRs that don't touch web-client.ts — confirms the flake is the test, not the SUT. Fix: add a beforeEach that POSTs idle to both tool and browser tracks + a 20ms flush window. Per-subtest baseline removes the order-dependency that's been latent for the test's lifetime. Verified: 9/9 subtests pass; full TS suite 162/162 pass. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 18, 2026
Merged
4 tasks done
This was referenced May 18, 2026
liususan091219
pushed a commit
to liususan091219/sutando-fork
that referenced
this pull request
May 28, 2026
sonichi#815) (sonichi#836) * fix(workspace): honor SUTANDO_WORKSPACE in 5 scripts — same bug class as PR sonichi#815/sonichi#832/sonichi#833 Audit per owner's "REPO_DIR might be more places than sonichi#815" — confirmed 10 bugs across 5 scripts all hitting the same workspace-vs-repo distinction the bridges fixed pre-PR sonichi#762. Each was resolving per-user-state paths (logs/, results/, state/, build_log.md, core-status.json, pending-questions.md) to the repo root instead of $SUTANDO_WORKSPACE. ## src/health-check.py — 6 sites - L314 voice-agent.log freshness check → WORKSPACE_DIR/logs - L598 core-status.json proactive-loop liveness → WORKSPACE_DIR - L681 build_log.md critical-file check → WORKSPACE_DIR - L795 bridge log-staleness check → WORKSPACE_DIR/logs - L807 bridge heartbeat check → WORKSPACE_DIR/state - L1171 restart-on-fix subprocess stdout redirect → WORKSPACE_DIR/logs WORKSPACE_DIR was already wired in this file (line 42 from earlier work); just substituting the right call sites. Code paths (src/*.py, src/*.ts, node_modules, .env, Sutando.app binary, subprocess cwd) correctly stay as REPO_DIR. Effect: health-check no longer false-positives "log stale / heartbeat missing / sutando-app not running" when services are actually fine. Real issues (voice-agent code stale, discord-bridge code stale) now surface cleanly instead of being lost in the false-positive cascade. ## src/event_log.py - L53–54: REPO_DIR/logs → WORKSPACE_DIR/logs (LOGS_DIR module global) - L71: personal_path(...) workspace arg → WORKSPACE_DIR ## src/check-pending-questions.py - L20: WORKSPACE = Path(__file__).parent.parent → resolve_workspace() This one was particularly silent — the cron's been firing for weeks reading the wrong file. After fix: surfaces the 2 long-pending questions (May 9 email-organize, May 13 web-UI bundle/fork) that the friction detector also found. ## src/call-stats.py + src/scan-call-logs.py - Both hardcoded `Path(__file__).parent.parent / "results" / "calls" / ...` - Now use resolve_workspace() (same pattern as daily-insight.py PR sonichi#832 + friction-detector.py PR sonichi#833) call-stats verified post-fix: now reads 2 real calls; previously read 0 on workspace-only installs. ## What's NOT in this PR - health-check.py L693 (notes-dir) — leaving to James's PR sonichi#815 to avoid conflict; same bug, same fix. ## Verification $ python3 src/health-check.py # core-proactive-loop ok, no false positives $ python3 src/check-pending-questions.py # Notified: 2 pending questions $ python3 src/call-stats.py # 2 real calls, Friday busiest $ python3 src/scan-call-logs.py # No new calls to scan (total: 2) * test(health-check): mock WORKSPACE_DIR not REPO_DIR for core-status check PR sonichi#836 moved core-status.json read from REPO_DIR to WORKSPACE_DIR (per-user runtime state, not code). The test still mocked REPO_DIR, so case e ('running with 5-day-old ts should be warn') silently failed against the real workspace's core-status.json instead of the temp fixture. Update write_status, with_repo_override, and case_b_status_malformed to mock WORKSPACE_DIR. All 17 cases pass. CI flagged by Chi in Discord, 2026-05-18. --------- Co-authored-by: Chi Wang <4250911+sonichi@users.noreply.github.com>
liususan091219
pushed a commit
to liususan091219/sutando-fork
that referenced
this pull request
May 28, 2026
… not repo (sonichi#833) Same workspace-path bug as daily-insight.py (PR sonichi#832): WORKSPACE was hardcoded to Path(__file__).parent.parent (repo root), causing FileNotFoundError when results/friction-{date}.txt couldn't be written to the wrong path. Verified before: tried /Users/.../github/sutando/results/friction-2026-05-18.txt → FileNotFoundError Verified after: writes /Users/.../sutando-workspace-001/results/friction-2026-05-18.txt → OK Output: surfaces 3 real friction items (2 long-unanswered questions, 1 stale task). Both this and PR sonichi#832 close out the friction-detector + daily-insight half of the workspace-path-violation pattern previously fixed in the bridges.
liususan091219
pushed a commit
to liususan091219/sutando-fork
that referenced
this pull request
May 28, 2026
closes sonichi#840) (sonichi#841) The describe block shares one spawned web-client child for all subtests. Tool-track 'working' set in one subtest can linger into the next when CI scheduling delays the async 'clear-tool' POST that the producing test issues at its tail. Two unrelated PRs flaked on this same suite today (sonichi#836 and sonichi#832), both on workspace-fix PRs that don't touch web-client.ts — confirms the flake is the test, not the SUT. Fix: add a beforeEach that POSTs idle to both tool and browser tracks + a 20ms flush window. Per-subtest baseline removes the order-dependency that's been latent for the test's lifetime. Verified: 9/9 subtests pass; full TS suite 162/162 pass. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
liususan091219
pushed a commit
to liususan091219/sutando-fork
that referenced
this pull request
May 28, 2026
… repo (sonichi#832) daily-insight.py hardcoded WORKSPACE = Path(__file__).parent.parent, which resolves to the repo root (/Users/.../github/sutando/) instead of the canonical $SUTANDO_WORKSPACE. As a result the daily 06:50 cron crashed with FileNotFoundError when results/insight-{date}.txt couldn't be written to a path that doesn't exist under the repo. Verified: Before: tried to write /Users/qingyunwu/Documents/github/sutando/results/insight-2026-05-18.txt → FileNotFoundError After: writes /Users/qingyunwu/Documents/github/sutando-workspace-001/results/insight-2026-05-18.txt → OK Output: "You've made 2 calls total. Peak hour: 1:00 ..." Same workspace-path-violation pattern that landed in earlier fixes for the bridges; uses the canonical resolve_workspace() helper. Closes the daily-insight half of feedback_workspace_path_resolution.md. Co-authored-by: Chi Wang <4250911+sonichi@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Symptom
The 06:50 daily-insight cron has been crashing silently for weeks:
```
FileNotFoundError: [Errno 2] No such file or directory:
'/Users/qingyunwu/Documents/github/sutando/results/insight-2026-05-18.txt'
```
Root cause
`src/daily-insight.py:18` hardcodes:
```python
WORKSPACE = Path(file).parent.parent
```
That resolves to the repo root (`/Users/.../github/sutando/`) — but on this machine the canonical `$SUTANDO_WORKSPACE` is `/Users/.../sutando-workspace-001/`. The script tried to write to `/results/insight-{date}.txt`, which doesn't exist.
Same workspace-path-violation pattern that the bridges had pre-PR #762.
Fix
One-line change: use the canonical `resolve_workspace()` helper from `workspace_default` (the same helper telegram-bridge.py, discord-bridge.py, agent-api.py, dashboard.py, dm-result.py, health-check.py already use).
```diff
sys.path.insert(0, str(Path(file).parent))
from util_paths import shared_personal_path # noqa: E402
+from workspace_default import resolve_workspace # noqa: E402
-WORKSPACE = Path(file).parent.parent
+WORKSPACE = resolve_workspace()
```
Verification
```
$ python3 src/daily-insight.py
Daily insight → /Users/qingyunwu/Documents/github/sutando-workspace-001/results/insight-2026-05-18.txt
You've made 2 calls total. Peak hour: 1:00 (1 calls). Hours with zero calls: 8:00, 9:00, 10:00. Consider scheduling deep work during those quiet windows.
```
Now writes to workspace and produces real insight content. The morning-briefing cron at 06:57 reads from `results/insight-{date}.txt`, so once this is merged the daily insights will actually surface in tomorrow's briefing.
🤖 Generated with Claude Code