Skip to content

session: a worker can stop its own job, and a run's checker is told the work is in its copy - #1515

Merged
AbirAbbas merged 3 commits into
devfrom
fix/worker-jobs-and-checker-copy
Sep 25, 2026
Merged

AbirAbbas merged 3 commits into
devfrom
fix/worker-jobs-and-checker-copy

Conversation

@AbirAbbas

Copy link
Copy Markdown
Collaborator

These two bugs showed up in a default /task run during the fresh-install check of dev 1194d4b8f.

1. A worker could not stop its own job. The bash belt puts jobs, read_document and manual on the wire (Decision 6 of the bash-task-loop design), and the worker's page sends the worker to jobs and read_document. But the one-action envelope refused every call not named bash. A worker's find / had become job 1. The worker called jobs kill and was told jobs was not on this belt, so the walk ran on for the rest of the task.
Now the envelope still allows exactly one call per response, and it refuses only a name the belt does not carry. The page says a job is read and stopped with the jobs tool. A job still running when its task ends was already stopped by the worker seat's close, and a test now proves it.

2. The checker began in the person's checkout. Nothing in a check's opening said where the work was. The only path it held was the footer's working directory, and the project folder's name in that path spells the person's checkout. The checker decoded it (cd /tmp/fxfresh/repo 2>/dev/null || pwd) and read an unrelated diff there. It moved into its own copy only when a write was refused. A check that only reads is never refused, so it could have answered on the wrong tree.
Now the check section says the work is in its working directory, every check and probe runs there, and the person's checkout is not the work.

Manual: how-tasks-run.md gains a section on which folder the checker reads, plus a sentence on stopping jobs. worker-harness.md now says the kept hands are called directly. Both come with probes.

Validation contract

  • When a bash-belt worker sends one jobs kill call for a job it started, the call runs, answers job 1 killed, and the job's process group is gone.
  • A call naming a tool the belt does not carry is still refused with [not run] no action executed: …. Two calls in one response are still refused.
  • Every belt tool the worker page names is one the envelope lets run.
  • A job still running when its task ends is gone once the worker's run returns.
  • A check's real opening (run.NewBashWorker, a RoleCheck task) says the work is in its working directory and never names the person's checkout.
  • The chat belt's jobs tool and the promotion sentence are unchanged.

How it was checked

  • The session envelope test and the check-opening test fail on dev and pass here. The end-of-task job test passes on dev as well; it fails if the jobs round in Close is removed.
  • make pr-ready: green (see below).
  • Hand check: the real binary with every seat on deepseek-v4-flash ($0.014).
    • The worker started sleep 900 in the background, then its trajectory reads jobs kill → job 1 killed and jobs list → killed. No sleep process was left.
    • The checker's first command was cd …/trees/1 (its own copy). Its jobs call was let through.

Follows #1429 / #1485 / #1494 / #1436 review.

🤖 Generated with Claude Code

AbirAbbas and others added 3 commits September 25, 2026 16:39
…ries

The bash belt composes `jobs`, `read_document` and `manual` onto the wire
(the design's Decision 6), and the worker's page sends the worker to the
first two, but the one-action envelope refused every call not named bash.
A worker whose `find /` had become job 1 called `jobs` to stop it, was told
`jobs` was not on this belt, and the walk ran on for the rest of the task.

The envelope now keeps the one-call rule and refuses only a name the belt
does not carry, read off the same belt the request was built from. The
page says a job is read and stopped through `jobs` (output, kill), never
the shell's builtin. A test proves a run worker's job still running when
its task ends is stopped with it (it already was, through Close).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Nothing in a check's opening said where the work was. The only path in it
was the footer's working directory, the run's copy, whose project folder
name spells the person's checkout. A checker decoded it, began with
`cd /tmp/fxfresh/repo`, read an unrelated diff there, and moved home only
when a write was refused; a check that only reads is never refused.

The check section now says the work is in its working directory, every
check and probe runs there, and the person's checkout is not the work. The
manual gains the section a person asks when they saw a check read their
checkout, and a probe for asking how a task stops its own job.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@AbirAbbas
AbirAbbas merged commit 8690b18 into dev Sep 25, 2026
4 checks passed
@AbirAbbas
AbirAbbas deleted the fix/worker-jobs-and-checker-copy branch September 25, 2026 21:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant