fix: batch-1 bug sweep — runs DELETE status lie, cleanup dry-run parity, subagent registry/relay - #170
Merged
Merged
Conversation
DELETE /api/runs/{id} called cancelRun unconditionally and answered the
hardcoded status "cancelled" — even for runs that had already completed
or failed. cancelRun → finish also re-stamped EndedAt on terminal runs.
Terminal runs are now left untouched and the response echoes the run's
real status with idle=true, matching POST /api/runs/{id}/cancel.
RED-first regression test: TestRunDelete_TerminalRunReportsRealStatus.
Two preview gaps made 'odek cleanup --dry-run' lie about what the real
sweep would remove:
- the dry-run collector had no artifacts category, so it could report
'storage is clean' while maintenance.Sweep deleted
~/.odek/artifacts/<session_id>/ subtrees older than
ArtifactsMaxAgeHours (on by default). Artifact subtrees are now
previewed via artifactCandidates, with the same duration-based cutoff
sweepArtifacts uses.
- the dry-run log list was {schedule.log, telegram.log} while
rotateLogs also rotates serve.log. The list is now shared via
maintenance.LogRotationNames so the two can never drift again.
RED-first regression tests: TestCleanupDryRun_PreviewsArtifactSubtrees,
TestCleanupDryRun_IncludesServeLog.
…inal reports Two wire-v2 telemetry bugs: - Ring eviction dropped entries[0] regardless of phase, so a still-running sub-agent could be evicted under ring pressure; its next progress record then auto-created a hollow entry without RunKey, making the task invisible to GET /api/subagents?run_key=... — the reload-restore path the registry exists for. Eviction now prefers the oldest finished entry, and subagentRegistryUpdate stamps recreated entries with the relay's runKey. - The parent done relay (fired only for children whose framed result never arrived or never parsed) unconditionally overwrote the terminal state and bumped the failed counter. A child that reported success on its own stream showed as failed-with-cost, and both lifetime counters counted the same task. First terminal report now wins. RED-first regression tests: TestSubagentRegistry_EvictionKeepsLiveEntriesVisible, TestSubagentDoneRelay_DoesNotClobberChildReportedSuccess.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
odek | 268d4f6 | Commit Preview URL Branch Preview URL |
Sep 01 2026, 06:41 AM |
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.
Batch 1 of the bug-hunt sweep (5 bugs, every fix RED-first: failing test observed before the fix, green after).
Bugs fixed
DELETE /api/runs/{id} lied about terminal runs (serve_runs.go) — the handler called
cancelRununconditionally and answered the hardcoded status"cancelled", even for runs that had already completed or failed;cancelRun → finishalso re-stampedEndedAton terminal runs. Terminal runs are now left untouched; the response echoes the real status withidle: true, matching POST/api/runs/{id}/cancel.cleanup --dry-runnever previewed artifact deletions — the collector had no artifacts category, so it could report "storage is clean" while the real sweep deleted~/.odek/artifacts/<session_id>/subtrees older thanArtifactsMaxAgeHours(enabled by default). Artifact subtrees are now previewed with the same duration-based cutoffsweepArtifactsuses.cleanup --dry-runlog list omittedserve.log— the realrotateLogsrotates{telegram, schedule, serve}.log; the preview only knew two. The list is now shared viamaintenance.LogRotationNames()so preview and rotation can never drift again.Sub-agent registry evicted LIVE entries (wire-v2) — ring overflow dropped
entries[0]regardless of phase; a running task's next progress record then auto-created a hollow entry withoutRunKey, making it invisible toGET /api/subagents?run_key=…(the reload-restore path). Eviction now prefers the oldest finished entry, andsubagentRegistryUpdatestamps recreated entries with the relay's runKey.Done relay clobbered child-reported success (wire-v2) — the parent-side relay (fired when a child's framed result never arrived/parsed) unconditionally overwrote the terminal state and bumped
failed: a task the child reported as success showed failed-with-cost and both lifetime counters counted it. First terminal report now wins.Verification
go build ./...clean;go test ./cmd/odek/ ./internal/maintenance/greengo vetclean;golangci-lint0 issues;-raceclean on maintenance + scoped cmd/odek suites