Repository navigation
fix(startup): tee stdout+stderr to /tmp self-log (Lucy's Bug #5) - #1484
Merged
Merged
Conversation
…0.8 auto-migration rm -rf (Lucy's Bug #5) Lucy's Maddy v0.8 migration report (2026-06-06 #design): she ran `nohup bash src/startup.sh > $SUTANDO_WORKSPACE/logs/startup-<ts>.log 2>&1 &` over SSH. Mid-run the v0.8 auto-migration `rm -rf`'d the legacy workspace dir her redirect was pointing at → log vanished mid-write, postmortem impossible. Read-through confirms there's no startup.sh-internal leak — service logs all land in $LOGS_DIR=$WORKSPACE/logs resolved AFTER line 184's `unset SUTANDO_WORKSPACE` + fresh config resolve. Lucy 2026-06-06: "There's no startup.sh-internal leak. The lost log was my own invocation, not the script. … ship your fallback — tee startup.sh's stdout+stderr to /tmp/sutando-startup-<ts>.log at the very top. That's exactly the right fix here: it guarantees a recoverable trace regardless of how it's invoked." Belt-and-suspenders: at the very top of startup.sh (BEFORE the v0.8 auto-migration block runs), tee stdout + stderr to /tmp/sutando-startup-<UTC-ts>-<PID>.log. The PID suffix prevents collisions when an operator retries while a hung previous invocation is still running. The log path is announced to stderr immediately so the operator knows where to look if their own redirect gets eaten. Opt out with SUTANDO_STARTUP_NO_LOG=1 (e.g. test harnesses with their own output capture). Tests: tests/startup-self-log-tmp.test.sh - 6 structural assertions: opt-out env var, /tmp path, exec+tee pattern for stdout AND stderr, announce-to-stderr, tee block BEFORE the auto-migration block, PID in filename for concurrent-startup isolation. - 3 E2E: extracted block writes both stdout AND stderr to the captured /tmp log while preserving pass-through to real fds; opt-out env var actually skips the tee; announce line goes to stderr only. Bug #5 of 5 from Lucy's Maddy migration report — closes the sweep. Lucy 2026-06-06: "That closes all 5 🎉 — great sweep." Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
sonichi
approved these changes
Jun 6, 2026
sonichi
left a comment
Owner
There was a problem hiding this comment.
LGTM. exec-with-process-substitution tee is the right pattern — both stdout and stderr captured, transparent to the rest of the script. Critical ordering: tee runs before auto-migration (Test 5 verifies this explicitly, which is exactly right — an early migration abort would otherwise be invisible). Timestamp+PID gives uniqueness for concurrent invocations. SUTANDO_STARTUP_NO_LOG=1 opt-out is clean. Test suite covers all 6 structural invariants. Stand: Echo Act IV Pro
Merged
7 tasks
qingyun-wu
added a commit
that referenced
this pull request
Jun 6, 2026
…rator checklist + workspace-sync node_modules Per Chi's PR #1472 comments (#design 2026-06-06): **CHANGELOG.md v0.3.0 additions:** - Fixed → Migration subsection: Lucy's Maddy v0.8 5-bug sweep (#1475 #1478 #1482 #1483 #1484) - Fixed → Cross-platform: #1476 (uname -s branch for preflight byte count) - Fixed → Security: #1452 #1462 #1466 (execSync → execFileSync sweep) - Added: #1467 (bridges inject skill instructions into owner task files) - Workspace contract rollup → M1: also reference #1473 (pre-flight scan + per-file progress reporter) **KNOWN_ISSUES.md additions** (from migration-thread digest 1512359988834730014): - Pre-migration operator checklist (7 items) — vault URL, remove shell-rc env var, grep .git/info/exclude, confirm wsId, stagger hosts, restart services, post-migration sanity check - Identity-collision rule — exactly one host at a time can hold a Discord token (also applies to Twilio + other per-identity creds) **docs/workspace-sync.md** pre-flight checklist: - Added `node_modules/` row per Chi's PR #1472 comment (covers vault-sync side; #1482 already handles the backup-side via `_BACKUP_DEFAULT_EXCLUDES`) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.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.
Summary
Closes Bug #5 of 5 from Lucy's Maddy v0.8 migration report (2026-06-06 #design). Last of her five 🎉
Lucy ran
nohup bash src/startup.sh > \$SUTANDO_WORKSPACE/logs/startup-<ts>.log 2>&1 &over SSH. Mid-run the v0.8 auto-migration `rm -rf`'d the legacy workspace dir her redirect was pointing at → log vanished mid-write, postmortem impossible.Read-through confirms there's no startup.sh-internal leak — service logs all land in `$LOGS_DIR=$WORKSPACE/logs` resolved AFTER line 184's `unset SUTANDO_WORKSPACE` + fresh config resolve. Lucy concurred: "There's no startup.sh-internal leak. The lost log was my own invocation, not the script. Ship your fallback — tee startup.sh's stdout+stderr to /tmp/sutando-startup-.log at the very top. That's exactly the right fix here: it guarantees a recoverable trace regardless of how it's invoked."
Fix
At the very top of `src/startup.sh` (BEFORE any other output, BEFORE the v0.8 auto-migration block), tee stdout + stderr to `/tmp/sutando-startup--.log`:
```bash
if [ "${SUTANDO_STARTUP_NO_LOG:-0}" != "1" ]; then
_STARTUP_LOG="/tmp/sutando-startup-$(date -u +%Y%m%dT%H%M%SZ)-$$.log"
echo "📓 startup log → $_STARTUP_LOG" >&2
exec > >(tee -a "$_STARTUP_LOG") 2> >(tee -a "$_STARTUP_LOG" >&2)
fi
```
Tests
`tests/startup-self-log-tmp.test.sh`:
ALL TESTS PASS.
Diff stats
2 files changed, +148 (20 in startup.sh, 128 test).
Related
v0.3.0 milestone table
Test plan
🤖 Generated with Claude Code