Eligibility
Stage: deployment / running-workload observability.
Coding agent: Claude Code (Opus 4.8), Monk plugin monk-agent v0.1.54.
Tool: monk.workload.logs (contradiction cross-checked against monk.workload.status).
Summary
After a workload is stopped, monk.workload.logs returns ok: true with log lines and no
field of any kind indicating the workload/container is stopped or exited. An operator or agent
calling workload.logs to check a service receives a healthy-looking response and cannot tell the
service is actually down.
This directly contradicts monk.workload.status, which for the same stopped workload returns
{ "workloads": [] } (the workload is absent entirely). So the two tool surfaces give mutually
inconsistent pictures of the same workload: status says it does not exist, logs says ok: true
and serves its logs. Ground truth (podman) is Exited (137).
Secondary defect: workload.logs's own error path is misleading. For a wrong/nonexistent container
name it returns "could not find any running containers" — implying it requires a running
container — yet it happily serves logs for a non-running (exited) container. The "running
containers" precondition is both falsely stated and inconsistently enforced.
Reproduction (tools only; podman = independent ground truth)
- Running workload
monk-test-app/app. monk.workload.status → state: "running", ready: true.
- Stop it:
monk.workload.stop { workload: "monk-test-app/app" } (approved).
monk.workload.status { } (fresh):
→ the workload is gone from status.
monk.workload.logs { workload: "monk-test-app/app", tail: 5 }:
{
"ok": true,
"workload": "monk-test-app/app",
"tail": 5, "followMs": 0, "maxBytes": 262144,
"truncated": false, "bytes": 55, "lineCount": 5,
"logs": "probe-line\nprobe-line\nprobe-line\nprobe-line\nprobe-line\n"
}
→ ok: true, log lines returned, no state/running/stopped/exited field. Nothing in
the response reveals the workload is down.
- Independent ground truth:
podman ps -a → local-…-monk-test-app-app-main Exited (137) … ago
podman logs --tail 5 <container> → probe-line ×5 (identical to step 4)
The container is genuinely stopped; workload.logs read its logs correctly but reported no
stopped state.
- Secondary defect — on the (previously running) workload, a bogus container name:
monk.workload.logs { workload: "monk-test-app/app", container: "does-not-exist-xyz" }
→ MCP error: "…could not find any running containers"
The message asserts a "running containers" requirement that step 4 shows is not actually the
tool's behavior (it serves logs for a stopped container).
Cross-verification (3 independent sources)
monk.workload.logs → ok: true, lineCount: 5, no stopped indicator (step 4).
monk.workload.status → { "workloads": [] } for the same workload at the same time
(step 3): the two MCP surfaces disagree on whether the workload even exists.
- podman (ground truth) → container
Exited (137); podman logs --tail 5 output byte-identical
to workload.logs (step 5). Confirms the workload is stopped and that logs is live-reading the
exited container while mislabeling its state.
Root cause
workload.logs resolves the container by name and streams its logs (podman serves logs for exited
containers) but never attaches the container run-state to its response, and does not reconcile
with the fact that workload.status no longer lists the workload. The result is a success-shaped
response for a down service. The "could not find any running containers" error string is a separate
inaccuracy in the same handler (it fires for absent/misnamed containers and misstates the
running-container precondition).
Note: this shares a root theme with #234 (stopped-workload state is not recomputed/surfaced) but is
a different tool and a different observable defect — #234 is about workload.status health
flags and the vanish; this is about workload.logs returning ok:true with no down-signal and
contradicting status.
It is also the opposite failure mode to #188. #188 (accepted, impact:high) is "workload.logs
cannot find a container that status reports as running" — logs fails on a running
workload (a false negative during container resolution). This report is the inverse: on a
stopped workload, logs succeeds (ok:true, serves logs) with no stopped indicator (a
false-positive / false-healthy signal). Opposite precondition (stopped vs running), opposite
direction (succeeds-when-it-should-signal-down vs fails-when-it-should-succeed), and a different
root cause (missing run-state in the response vs container-name resolution failing). Fixing #188's
resolution bug would not surface the stopped state this report is about.
Impact
- False health signal / observability: an agent-driven deploy or monitor loop naturally calls
workload.logs to see what a service is doing; on a stopped service it gets ok: true + logs and
no indication the service is down, so automation concludes the service is fine.
- Unreconcilable surfaces:
status (workload absent) and logs (ok:true, serving logs) cannot
both be right; there is no single source of truth for "is this workload running?" across the tool
set.
Expected vs actual
- Expected: for a stopped workload,
workload.logs either surfaces the container run-state
(e.g. state: "stopped"/running: false) alongside the logs, or returns a clear
stopped/not-running signal — and its error text names the actual condition (container not found)
rather than "no running containers." The logs and status surfaces should agree on existence.
- Actual:
workload.logs returns ok: true with logs and no state field for a stopped
workload, while workload.status reports the same workload as absent; podman confirms Exited.
Environment
- OS: Windows 11 Pro (native
monk-agent v0.1.54; runtime WSL Ubuntu-Monk, podman).
- Monk CLI/daemon:
v3.21.1, build 0ecb47b4.
- Scope: personal /
monk-test-app, local runnable monk-test-app/app.
Dedup check
gh search issues -R monk-io/monk-plugin "workload" surfaces two related-but-distinct issues:
#234 (workload.status ready/alive flags + vanish — different tool) and #188 (workload.logs
fails to find a container on a running workload — the opposite failure mode; see Root
cause for the point-by-point distinction). Neither covers a stopped workload where
workload.logs returns ok:true with no down-signal while workload.status reports the workload
absent.
Payout
N/A — reported for the Monk bug bounty; no payout expected for this report itself.
Eligibility
Stage: deployment / running-workload observability.
Coding agent: Claude Code (Opus 4.8), Monk plugin
monk-agent v0.1.54.Tool:
monk.workload.logs(contradiction cross-checked againstmonk.workload.status).Summary
After a workload is stopped,
monk.workload.logsreturnsok: truewith log lines and nofield of any kind indicating the workload/container is stopped or exited. An operator or agent
calling
workload.logsto check a service receives a healthy-looking response and cannot tell theservice is actually down.
This directly contradicts
monk.workload.status, which for the same stopped workload returns{ "workloads": [] }(the workload is absent entirely). So the two tool surfaces give mutuallyinconsistent pictures of the same workload:
statussays it does not exist,logssaysok: trueand serves its logs. Ground truth (podman) is
Exited (137).Secondary defect:
workload.logs's own error path is misleading. For a wrong/nonexistent containername it returns "could not find any running containers" — implying it requires a running
container — yet it happily serves logs for a non-running (exited) container. The "running
containers" precondition is both falsely stated and inconsistently enforced.
Reproduction (tools only; podman = independent ground truth)
monk-test-app/app.monk.workload.status→state: "running", ready: true.monk.workload.stop { workload: "monk-test-app/app" }(approved).monk.workload.status { }(fresh):{ "workloads": [] }monk.workload.logs { workload: "monk-test-app/app", tail: 5 }:{ "ok": true, "workload": "monk-test-app/app", "tail": 5, "followMs": 0, "maxBytes": 262144, "truncated": false, "bytes": 55, "lineCount": 5, "logs": "probe-line\nprobe-line\nprobe-line\nprobe-line\nprobe-line\n" }ok: true, log lines returned, nostate/running/stopped/exitedfield. Nothing inthe response reveals the workload is down.
workload.logsread its logs correctly but reported nostopped state.
tool's behavior (it serves logs for a stopped container).
Cross-verification (3 independent sources)
monk.workload.logs→ok: true,lineCount: 5, no stopped indicator (step 4).monk.workload.status→{ "workloads": [] }for the same workload at the same time(step 3): the two MCP surfaces disagree on whether the workload even exists.
Exited (137);podman logs --tail 5output byte-identicalto
workload.logs(step 5). Confirms the workload is stopped and thatlogsis live-reading theexited container while mislabeling its state.
Root cause
workload.logsresolves the container by name and streams its logs (podman serves logs for exitedcontainers) but never attaches the container run-state to its response, and does not reconcile
with the fact that
workload.statusno longer lists the workload. The result is a success-shapedresponse for a down service. The "could not find any running containers" error string is a separate
inaccuracy in the same handler (it fires for absent/misnamed containers and misstates the
running-container precondition).
Note: this shares a root theme with #234 (stopped-workload state is not recomputed/surfaced) but is
a different tool and a different observable defect — #234 is about
workload.statushealthflags and the vanish; this is about
workload.logsreturningok:truewith no down-signal andcontradicting
status.It is also the opposite failure mode to #188. #188 (accepted, impact:high) is "workload.logs
cannot find a container that status reports as running" — logs fails on a running
workload (a false negative during container resolution). This report is the inverse: on a
stopped workload, logs succeeds (
ok:true, serves logs) with no stopped indicator (afalse-positive / false-healthy signal). Opposite precondition (stopped vs running), opposite
direction (succeeds-when-it-should-signal-down vs fails-when-it-should-succeed), and a different
root cause (missing run-state in the response vs container-name resolution failing). Fixing #188's
resolution bug would not surface the stopped state this report is about.
Impact
workload.logsto see what a service is doing; on a stopped service it getsok: true+ logs andno indication the service is down, so automation concludes the service is fine.
status(workload absent) andlogs(ok:true, serving logs) cannotboth be right; there is no single source of truth for "is this workload running?" across the tool
set.
Expected vs actual
workload.logseither surfaces the container run-state(e.g.
state: "stopped"/running: false) alongside the logs, or returns a clearstopped/not-running signal — and its error text names the actual condition (container not found)
rather than "no running containers." The
logsandstatussurfaces should agree on existence.workload.logsreturnsok: truewith logs and no state field for a stoppedworkload, while
workload.statusreports the same workload as absent; podman confirmsExited.Environment
monk-agent v0.1.54; runtime WSLUbuntu-Monk, podman).v3.21.1, build 0ecb47b4.monk-test-app, local runnablemonk-test-app/app.Dedup check
gh search issues -R monk-io/monk-plugin "workload"surfaces two related-but-distinct issues:#234 (
workload.statusready/alive flags + vanish — different tool) and #188 (workload.logsfails to find a container on a running workload — the opposite failure mode; see Root
cause for the point-by-point distinction). Neither covers a stopped workload where
workload.logsreturnsok:truewith no down-signal whileworkload.statusreports the workloadabsent.
Payout
N/A — reported for the Monk bug bounty; no payout expected for this report itself.