feat(sandbox): write connect logs to retask.log with rotation, show the path in the TUI - #18
Conversation
Both lane URLs carry the session JWT as a query parameter, and a failed WebSocket dial reports the URL it tried — so every reconnect logged the whole token. Today that only reaches the TUI panel and stderr, but it is about to reach a file on disk, and a long-lived token sitting in a log is not something to fix afterwards. Scrub the token value at both dial sites. redactErr keeps the original error reachable through Unwrap, so errors.Is and errors.As are unaffected. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…the TUI `retask sandbox connect` logged only to the TUI panel, or to stderr when headless. Nothing survived the run, so a reconnect, a session bootstrap or a prompt-watcher decision from twenty minutes ago left no evidence. Tee the slog handler: every line still reaches the TUI (stderr when headless) and is now also appended to retask.log in the folder the command was started from — for a sandbox, the session folder, next to the work the log describes. The TUI Logs divider shows the active path: ─ Logs (…/scratchpad/e2etui/retask.log) ────────────────────────── Rotation is Unix-style and handled by agentfleet: the live file keeps its name and older generations shift down through retask.log.1, retask.log.2, ... up to --log-backups before being discarded. Both behaviours are on by default and can be turned off individually: --log-file log file path, relative to the current folder (retask.log) --no-log-file log to the TUI/stderr only --log-max-size rotation threshold (10MB); 0 disables rotation --log-backups generations kept (5); 0 keeps none --no-log-path hide the path from the TUI Logs divider Each flag has a RETASK_SANDBOX_* environment counterpart, following the existing connect flags; the flag always wins. Requires agentfleet v0.8.0 for LogFileConfig/OpenLogFile and the TUI LogPath/ShowLogPath options. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
agentfleet v0.8.0 raised its go directive to 1.26.5 to clear GO-2026-5856 (Encrypted Client Hello privacy leak in crypto/tls), so the main module has to declare at least the same. govulncheck is clean on this tree. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Follow-up: agentfleet's pipeline flagged GO-2026-5856 (Encrypted Client Hello privacy leak in That raises agentfleet v0.8.0's minimum, so this branch bumps |
The pinned checksum was computed from the PR branch before the tag existed. v0.8.0 carries four dependabot CI commits on top of it, so the module hash moved; the go.mod hash is unchanged. Re-resolved through proxy.golang.org and verified against sum.golang.org. No Go source differs between the branch tip and the tag — only .github/workflows — so the build and tests are unaffected. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
agentfleet v0.8.0 is released — this branch is now locked to the published module and is unblocked. The pinned checksum did move, as flagged: v0.8.0 carries four dependabot CI commits on top of the merged branch, so the module hash changed ( Re-verified end-to-end against the published module on go1.26.5:
Ready to merge. |
Why
retask sandbox connectlogs only to the TUI panel (stderr when headless). Nothing survives the run — a reconnect, a session bootstrap or a prompt-watcher decision from twenty minutes ago leaves no evidence to debug from.What
Every log line now goes to two places: the TUI panel (stderr when headless) exactly as before, and
retask.login the folderconnectwas started from — for a sandbox, the session folder, next to the work the log describes.The Logs divider shows the active path, elided from the left as the terminal narrows:
Rotation follows the Unix convention: the live file keeps its name, older generations shift down through
retask.log.1,retask.log.2, … up to--log-backups, and the oldest is discarded. Restartingconnectappends rather than truncating.Both behaviours are on by default; each can be turned off on its own.
--log-fileretask.logRETASK_SANDBOX_LOG_FILE--no-log-filefalseRETASK_SANDBOX_NO_LOG_FILE=1--log-max-size10MB(0= no rotation)RETASK_SANDBOX_LOG_MAX_SIZE--log-backups5(0= keep none)RETASK_SANDBOX_LOG_BACKUPS--no-log-pathfalseRETASK_SANDBOX_NO_LOG_PATH=1The flag always wins over its environment variable, matching the existing
--session-bufferhandling.--log-file ""is accepted as a synonym for--no-log-file.Included fix: the JWT was being logged
Verifying this end-to-end surfaced a pre-existing leak. Both lane URLs carry the session JWT as a query parameter, and a failed WebSocket dial reports the URL it tried — so every reconnect logged the whole token:
Today that only reaches the TUI and stderr. This PR would have written it to a file in the sandbox folder, so the first commit scrubs the token at both dial sites:
redactErrkeeps the original error reachable throughUnwrap, soerrors.Is/errors.Asare unaffected.Dependency
Requires agentfleet v0.8.0 (#14, merged), which adds
LogFileConfig/OpenLogFile(the rotating writer) and the TUILogPath/ShowLogPathoptions. Now released —go.modandgo.sumare locked to the published tag, resolved throughproxy.golang.organd verified againstsum.golang.org.v0.8.0 also raises its
godirective to 1.26.5 to clear GO-2026-5856 (Encrypted Client Hello privacy leak incrypto/tls), so this branch bumps togo 1.26.5as well — a main module must declare at least what its dependencies require.Testing
go build ./...,go vet ./...andgo test ./...all pass locally against the pinned agentfleet.New unit coverage: flag defaults, every override, environment fallbacks and flag-beats-environment precedence, invalid sizes and counts, the tee reaching both the buffer and the file with identical content, the disabled path creating no file at all, rotation producing
retask.log.1/.2and capping at--log-backups, plus token redaction across both lane URL shapes with the error chain preserved.Verified end-to-end by running the built binary against an unreachable proxy in a scratch folder:
retask.log,retask.log.1,retask.log.2written, capped at--log-backups 2, contents identical to stderr, zero JWT occurrences on disk.─ Logs (…/scratchpad/e2etui/retask.log) ─withtoken=REDACTEDin the panel below it.🤖 Generated with Claude Code