Repository navigation
feat(runtime-api): include task previews in live task listings - #5646
Conversation
sonichi
left a comment
There was a problem hiding this comment.
Independently verified:
- Confirmed the enumeration gap on main. Reverted just the production change (keeping the new test) against the parent commit (dbb0d45) — 2 errors, since list_tasks never collapsed/truncated/exposed body text at all. At the PR head, 73/73 pass.
- Traced the truncated-scan edge case by hand, not just trusting the test:
test_list_tasks_retains_mtime_and_limit_semanticsdeletes the "newer" file via a mockedPath.statright after its first stat call, sof.read_text()later raisesFileNotFoundErrorfor that entry — caught by the existingexcept OSError: passthe newentry["preview"] = ...line sits inside. So the new field correctly inherits the same fail-open behavior as source/priority/timestamp/instance_id, with no new error handling needed. That's whyrows["tasks"][0](newer) has no "preview" in that test while the full re-scan's "older" does. - Confirmed the truncation/unicode-whitespace handling:
" ".join(th.body.split())[:160]correctly collapses(em-space) along with ordinary whitespace (Python'sstr.split()with no args splits on any Unicode whitespace), and[:160]truncates by code point, not byte, so a 200-"界"-char body truncates to exactly 153 "界" after the 7-char "second " prefix — matches the test's exact expected length (160) and content. - ruff clean, review-checks.sh clean, CI green, no failures.
Small, correctly-scoped, well-tested. LGTM.
qingyun-wu
left a comment
There was a problem hiding this comment.
Approving at 28e3ac6a3. The change is small and right.
What I checked:
- Scope.
list_tasksonly globstask-rtapi-*, the runtime API's own tasks.task.listandtask.detailsgo through the same_taskdispatch with the same authority. So a 160-character preview exposes nothing the caller couldn't already read in full throughtask.details. No other source's task text can appear. - Behaviour. The preview is computed inside the existing
try, so a file that vanishes or can't be read still yields a row without a preview, as before. The disappearance test now asserts that directly. Slicing is by code point, so a CJK body is cut cleanly at 160 characters, and the test pins that. - Tests at head.
tests/runtime-api-tasks-view.test.pyran 73 tests, OK. - Mutation. With the preview line disabled, both updated tests fail (
test_list_tasks_enumerates_live_onlyandtest_list_tasks_retains_mtime_and_limit_semantics). So the assertions have teeth.
CI was still running when I reviewed. sonichi/sutando merges belong to the owner or Chi, so I'm not merging it myself.
Coverage Gate✅ Diff coverage PASSES the 95% bar. Whole-tree (informational): 92%. Diff CoverageDiff: origin/main...HEAD, staged and unstaged changes
Summary
|
liususan091219
left a comment
There was a problem hiding this comment.
Ready to approve.
Reviewed at head 28e3ac6a37c4beb617ce3678f17227e2dfbaa88b (one commit on dbb0d45f). The change adds one production line at src/runtime-api/tasks_view.py:377 and focused assertions in tests/runtime-api-tasks-view.test.py.
What I ran (local clone, SUTANDO_WORKSPACE* / SUTANDO_TASKS_DIR unset)
python3 tests/runtime-api-tasks-view.test.pyat head: 73 tests, OK.- Parent's
tasks_view.pywith the new tests: 2 ERRORs (test_list_tasks_enumerates_live_only,test_list_tasks_retains_mtime_and_limit_semantics). The tests fail without the change. - Mutation 1, dropping the whitespace collapse (
th.body[:160]): FAIL intest_list_tasks_enumerates_live_only. - Mutation 2, an off-by-one bound (
[:161]): FAIL in the same test. Both the normalisation and the 160 bound are pinned by tests. - Regex over the added diff lines for
~/.sutando,$HOME/.sutando,/Users/<name>/andSUTANDO_WORKSPACE: no hits.
Change-request walk (none fire)
- Tests: they exercise the real
TasksViewagainst real task files and assert on literal expected previews. Nothing reads module source, and nothing re-implements the unit in the test file. - Completeness:
- The preview sits inside the existing
try/except OSError, so a file that vanishes mid-scan still yields a row with no preview. The limit test now asserts this (assertNotIn("preview", ...)). - The text comes from the same
parse_task_headers_lenient(...).bodythatdetails()returns attasks_view.py:335-336. list_tasksonly globs this channel's owntask-rtapi-*files, so the preview exposes nothingtask.detailsdoes not already return.
- The preview sits inside the existing
- Base is
main, CI is green, and it is one concern. I found no duplicate or competing open PR: #4399 is a different module.
Approvals at this head (latest non-comment review per author)
- sonichi (OWNER), APPROVED. Substantive: reverted the change against the parent and traced the vanish-mid-scan case.
- qingyun-wu (COLLABORATOR), APPROVED. Substantive: checked scope and ran a mutation.
reviewDecisionis APPROVED. There are no review threads and no CHANGES_REQUESTED anywhere.
Merge gate (not part of this verdict)
repos/sonichi/sutando/commits/28e3ac6a.../statusreturnspendingwith zero contexts. license/cla is ABSENT, not green. Close and reopen the PR to retrigger it before merging.
Live path
- The author's body includes a real daemon plus CLI round trip and a restart check (PID 70062 then 70179). I did not re-run it. It is a disposable isolated daemon, not a deployment.
Non-blocking nits
-
src/runtime-api/protocol.py:43: thetask.list {}doc line could note the newpreviewfield, astask.list_resultsdoes at line 34. -
There are now two preview policies in one file:
list_resultsuses a rawbody[:160](tasks_view.py:319).list_taskscollapses whitespace first (tasks_view.py:377).
The literal 160 appears twice. A shared module constant, or a one-line note on why the two differ, would stop them drifting.
Not verified: the live daemon round trip myself; behaviour against main after dbb0d45f.
— Sutando (susans-MacBook-Pro)
liususan091219
left a comment
There was a problem hiding this comment.
Approving at 28e3ac6a3, the head I reviewed in #5646 (review). That review has the evidence: tests run, mutation checks, and an expert approval already at this head. The head has not changed since. Approved directly per the owner's standing instruction.
— Sutando (susans-MacBook-Pro)
Priority
Level: medium
Reason: Owner-approved reliability improvement.
Closes
N/A — owner-approved work; no public issue is claimed as closed.
Summary
feat(runtime-api): include task previews in live task listings
Review first:
src/runtime-api/tasks_view.py,tests/runtime-api-tasks-view.test.py.Checklist
gh pr list --repo sonichi/sutando --search "closes #N")git log -1 --format='%ae'shows a GH-mapped email, not*.localornoreply@anthropic.com)upstream/main(or feature isn't already covered)branches:filter can silently exclude a stacked PR)resolve_workspace/resolveWorkspace/claude_home_pathhelpers (seeCLAUDE.md"Workspace contract"; enforced by thelint-workspace-resolution,lint-claude-home-path, andworkspace-leak-checkCI checks)Contribution observations (unchecked items remain reviewer decisions):
Duplicate search: Searched PRs (all states) and open issues using feat(runtime-api): include task previews in live task listings, "task.details". No matching records returned. Returned PRs were compared against current files and overlapping diffs: none found. Title similarity alone is not equivalence; this is not exhaustive semantic coverage.
Upstream observed during evidence preparation:
12d2f0d72825019b6af6afc5ae48dd5a00e5fda0. Main advanced after the recorded source base. Local evidence verifies the exact PR candidate, not its integration with newer main. PR checks, independent review and branch maintenance govern merge.Diff review: - review-correctness: Inspected TasksView.list_tasks, the shared parser, status/details handling, dispatcher and CLI output. tasks_view.py:377 normalizes the already parsed string before slicing to 160 characters, inside the existing successful-read block. It preserves IDs, states, metadata, sorting, limits and OSError handling. Real-daemon boundary observations passed for empty/missing bodies, legacy parsed metadata and lengths 159/160/161.
review-scope: The complete parent-to-candidate diff contains only the two allowed paths: one production line and focused regression assertions. No desktop, execution, transport, cross-channel enumeration or archive-browsing changes. The CLI already emits the API response unchanged.
review-maintainability: The implementation reuses existing parsing and introduces no new dependency, helper or duplicated policy. Regression assertions use literal expected previews and retain lifecycle checks. Piping the exact candidate diff to bash scripts/review-checks.sh passed hardcoded-path, root-artifact and comment checks at 2026-10-16T23:56:21Z.
Documentation: No standalone documentation files changed. The reviewer should assess the code and contract comments for documentation completeness.
Live-path verification: - monitor-user-journey: Ran python3 [local path] It launched the candidate server.py and used the real sutando-runtime.py CLI for task submit, list, details and cancel. PID 70062 reached API readiness at 2026-10-17T00:01:12.506Z. Preview recognition, full details, foreign exclusion and persisted cancellation signal passed. All 24 final assertions passed. Exact argv, responses and file observations: monitor-journey.json.
monitor-repeatability: The witness ran task list through three fresh CLI connections; every response equaled the first listing. After stopping PID 70062 and restarting as PID 70179, task list and task details returned identical IDs, states, previews, ordering and bodies. Moving the claimed fixture out of the live directory removed its row; restoring it restored the identical row. Evidence: monitor-journey.json.
These observations used the isolated candidate; no production deployment was performed.
Rollback: revert this PR. Production behavior after deployment remains to be observed.
keweichen; CLA status must be observed on the PR.Before / after evidence
Before
Earlier baseline observations at dbb0d45. These are historical; current-candidate evidence follows below.
Exit: 0
Exit: 0
After
candidate-identity: git rev-parse HEAD matched the required commit. git status --porcelain=v1 --untracked-files=all was empty before and after verification. Only the two allowed paths differ from the approved base. Final identity receipt: diagnostics/candidate-identity.json, recorded 2026-10-16T23:52:55Z.
acceptance-1: Ran python3 [local path] using the supplied scratch environment and real candidate server/CLI. Two distinct submissions were identifiable from one task-list response; both previews exactly matched whitespace-normalized parsed bodies truncated to 160 characters. Daemon PID 28968 started at 2026-10-16T23:52:24.526Z, API readiness passed at 23:52:24.756Z, and it was reaped at 23:52:25.237Z. Exact commands, responses and persisted-body observations are in diagnostics/preview-journey.json.
acceptance-2: The supplementary Unicode request retained its full 266-character parsed body in task.details while its preview contained exactly 160 characters. Original IDs remained task-rtapi-f40fb87a9f45 (pending) and task-rtapi-6a72fce35e5b (in_progress after claiming). Evidence: diagnostics/preview-journey.json.
acceptance-3: Real daemon observations confirmed an empty queue returned {"tasks":[]} and Discord/Telegram control IDs and text were absent. Frozen regressions passed disappearance handling, ordering/limits, assigned IDs, cancellation and foreign-task ownership boundaries.
check-task-preview-socket-acceptance: Executed the supplied python3 -c check unchanged with the provisioned environment. Exit 0; all seven assertions passed against the real disposable daemon. Run: 2026-10-16T23:51:18.923Z–23:51:19.811Z. Exact argv and startup output: diagnostics/task-preview-socket-acceptance.json.
check-task-view-regressions: Executed the supplied python3 -c check unchanged. All 21 selected tests passed without skips; exit 0. Run: 2026-10-16T23:51:18.924Z–23:51:19.219Z. Exact argv and results: diagnostics/task-view-regressions.json.
coverage: python3 -m coverage run --rcfile=.coveragerc tests/runtime-api-tasks-view.test.py passed all 73 tests. After coverage combine and XML generation, diff-cover compared against dbb0d45 with --fail-under=95: one changed executable line, zero missing, 100% coverage. Exact commands and timestamps: diagnostics/coverage-commands.json.
Test plan
Observed: PASS; exit 0.
Observed: PASS; exit 0.
Canonical review scanner:
Verified candidate:
99c7a4d5733f0778c1af7207c3c6b00c599a077c. Publication commit:28e3ac6a37c4beb617ce3678f17227e2dfbaa88b. Both have treecd9e65f29bf9532899a403af88700885cacb7675; only factory-authored commit metadata changed. Acceptance evidence refers to the verified candidate; the scanner ran on the publication tree.