harnex 0.5.0 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,94 @@
1
+ # Buddy Monitoring
2
+
3
+ A buddy is a second harnex session that watches one or more workers and nudges
4
+ them if they stall. Use a buddy when the work is long-running, unattended, or
5
+ needs interpretation that simple stall policy cannot provide.
6
+
7
+ For simple inactivity recovery, prefer built-in watch mode:
8
+
9
+ ```bash
10
+ harnex run codex --id cx-i-NN --watch --preset impl --context "Read /tmp/task-impl-NN.md"
11
+ ```
12
+
13
+ Use a buddy when you need reasoning over pane contents, semantic checks, or
14
+ multi-session correlation.
15
+
16
+ ## When To Use
17
+
18
+ Use a buddy for:
19
+
20
+ - Overnight or multi-hour work.
21
+ - Any dispatched task expected to run more than about 30 minutes unattended.
22
+ - Work where a stalled prompt, permission request, or disconnect would waste a
23
+ long slot.
24
+ - Monitoring multiple signals before deciding whether to nudge.
25
+
26
+ ## Spawn
27
+
28
+ Spawn the worker first, then spawn the buddy:
29
+
30
+ ```bash
31
+ harnex run codex --id cx-i-42 --tmux cx-i-42 \
32
+ --context "Read and execute /tmp/task-impl-42.md"
33
+
34
+ harnex run claude --id buddy-42 --tmux buddy-42
35
+ ```
36
+
37
+ The buddy is just another harnex session. Inspect it, stop it, and read its
38
+ logs with the same commands as any worker.
39
+
40
+ ## Buddy Prompt
41
+
42
+ Give the buddy an explicit polling loop, stall threshold, nudge rule, return
43
+ channel, and cleanup rule:
44
+
45
+ ```text
46
+ You are an accountability partner for harnex session `cx-i-42`.
47
+
48
+ Every 5 minutes:
49
+ - Run `harnex pane --id cx-i-42 --lines 30`.
50
+ - Run `harnex status --id cx-i-42 --json`.
51
+
52
+ If the worker appears stuck at a prompt or permission dialog for more than
53
+ 10 minutes with no progress, nudge it:
54
+ - `harnex send --id cx-i-42 --message "You appear to have stalled. Continue with your current task."`
55
+
56
+ If the worker exits or writes `/tmp/cx-i-42-done.txt`, report back:
57
+ - `tmux send-keys -t "$HARNEX_SPAWNER_PANE" "cx-i-42 finished. Check /tmp/cx-i-42-done.txt." Enter`
58
+
59
+ Do not interfere with active work. Stop yourself after reporting completion.
60
+ ```
61
+
62
+ Send it:
63
+
64
+ ```bash
65
+ harnex send --id buddy-42 --message "Read and execute /tmp/buddy-42.md"
66
+ ```
67
+
68
+ ## Return Channel
69
+
70
+ Every harnex-spawned session receives `HARNEX_SPAWNER_PANE` when the invoker is
71
+ inside tmux. The buddy can use it to report to an invoker that is not itself a
72
+ harnex session:
73
+
74
+ ```bash
75
+ tmux capture-pane -t "$HARNEX_SPAWNER_PANE" -p
76
+ tmux send-keys -t "$HARNEX_SPAWNER_PANE" "cx-i-42 finished" Enter
77
+ ```
78
+
79
+ If no tmux return pane is available, require the buddy to write a file and tell
80
+ the invoker where to read it.
81
+
82
+ ## Cleanup
83
+
84
+ Stop the buddy after the worker completes:
85
+
86
+ ```bash
87
+ harnex stop --id buddy-42
88
+ ```
89
+
90
+ For full recipe form, use:
91
+
92
+ ```bash
93
+ harnex recipes show 03
94
+ ```
@@ -0,0 +1,130 @@
1
+ # Monitoring Patterns
2
+
3
+ Monitoring should be based on work-level signals first and UI state second.
4
+ Pane state is useful for interpretation, but it should not be the only proof
5
+ that delegated work is finished.
6
+
7
+ ## Signal Ladder
8
+
9
+ Prefer signals in this order:
10
+
11
+ | Signal | Use |
12
+ | --- | --- |
13
+ | Expected artifact | Primary proof that a task produced its deliverable |
14
+ | Tests and git state | Confirms work landed and the tree is not mid-edit |
15
+ | `harnex events` | Structured runtime events, including task completion |
16
+ | `harnex logs` | Transcript history and last output |
17
+ | `harnex pane` | Live UI interpretation and prompt/error diagnosis |
18
+ | `harnex status` | Session liveness and coarse state |
19
+
20
+ For Codex app-server sessions, `harnex wait --until task_complete` is a strong
21
+ turn-level fence. It still does not know your acceptance criteria; verify the
22
+ expected artifact or tests afterward.
23
+
24
+ ## Completion Test
25
+
26
+ For unattended work, declare done with a conjunction of work-level facts:
27
+
28
+ ```bash
29
+ test -f /tmp/cx-i-NN-done.txt &&
30
+ test -z "$(git status --short)" &&
31
+ test "$(git log -1 --format=%ct)" -lt "$(($(date +%s) - 600))"
32
+ ```
33
+
34
+ Adjust the artifact path and commit-age window to the task. The point is to
35
+ avoid declaring done while a worker is between edits or between commits.
36
+
37
+ ## Why Pane State Alone Is Not Enough
38
+
39
+ Avoid using `state=prompt` or a quiet pane as the only completion signal:
40
+
41
+ - A finished agent can sit at a prompt forever.
42
+ - Some CLIs stay in a session state while auto-fix or tool loops continue.
43
+ - Focus changes and UI redraws can reset idle timers.
44
+ - A prompt can also mean the agent is blocked, not done.
45
+
46
+ Use `harnex pane` to understand what happened after a stronger signal tells you
47
+ where to look.
48
+
49
+ ## Polling Patterns
50
+
51
+ For active supervision:
52
+
53
+ ```bash
54
+ harnex pane --id cx-i-NN --lines 40
55
+ harnex events --id cx-i-NN --snapshot
56
+ harnex logs --id cx-i-NN --lines 80
57
+ ```
58
+
59
+ For continuous viewing:
60
+
61
+ ```bash
62
+ harnex pane --id cx-i-NN --follow --interval 2
63
+ harnex logs --id cx-i-NN --follow
64
+ harnex events --id cx-i-NN
65
+ ```
66
+
67
+ For task completion:
68
+
69
+ ```bash
70
+ harnex wait --id cx-i-NN --until task_complete --timeout 900
71
+ ```
72
+
73
+ ## Background Sweeper
74
+
75
+ Consumers often run a small shell loop that checks the expected done marker,
76
+ tree state, and harnex liveness. Keep a hard wall-clock cap so an unattended
77
+ pipeline cannot wait forever:
78
+
79
+ ```bash
80
+ start=$(date +%s)
81
+ max_wait=5400
82
+
83
+ until test -f /tmp/cx-i-NN-done.txt; do
84
+ if test "$(($(date +%s) - start))" -gt "$max_wait"; then
85
+ echo "wall-clock cap hit for cx-i-NN" >&2
86
+ exit 2
87
+ fi
88
+
89
+ harnex status --id cx-i-NN --json
90
+ harnex pane --id cx-i-NN --lines 20
91
+ sleep 60
92
+ done
93
+ ```
94
+
95
+ Recommended caps:
96
+
97
+ | Work type | Cap |
98
+ | --- | --- |
99
+ | Small single dispatch | 30 minutes |
100
+ | Medium implementation | 90 minutes |
101
+ | Large unattended phase | 3 hours |
102
+
103
+ ## Built-In Watch Mode
104
+
105
+ Use `harnex run --watch` when one foreground process should launch the worker
106
+ and apply bounded stall recovery:
107
+
108
+ ```bash
109
+ harnex run codex --id cx-i-NN --watch --preset impl \
110
+ --context "Read /tmp/task-impl-NN.md"
111
+ ```
112
+
113
+ `--watch` exits with:
114
+
115
+ | Code | Meaning |
116
+ | --- | --- |
117
+ | `0` | Session exited |
118
+ | `1` | Operational error |
119
+ | `2` | Watcher escalated after bounded resumes |
120
+
121
+ Use a buddy instead when the monitoring decision needs language-level
122
+ interpretation.
123
+
124
+ ## Anti-Patterns
125
+
126
+ - Polling `state=prompt` alone and calling it done.
127
+ - Letting an unattended loop run with no wall-clock cap.
128
+ - Reading raw tmux panes instead of `harnex pane`.
129
+ - Using `--wait-for-idle` as acceptance proof.
130
+ - Reusing a worker after a failure changes the task scope.
@@ -0,0 +1,106 @@
1
+ # Naming Conventions
2
+
3
+ Use predictable session IDs so humans, agents, tmux windows, logs, events, and
4
+ done markers all point at the same work.
5
+
6
+ ## Session IDs
7
+
8
+ Format:
9
+
10
+ ```text
11
+ <cli>-<phase>-<number>
12
+ ```
13
+
14
+ Common prefixes:
15
+
16
+ | Prefix | Meaning |
17
+ | --- | --- |
18
+ | `cx` | Codex worker |
19
+ | `cl` | Claude worker |
20
+ | `buddy` | Buddy monitor |
21
+
22
+ Common phases:
23
+
24
+ | Code | Phase |
25
+ | --- | --- |
26
+ | `m` | Mapping or analysis |
27
+ | `p` | Plan writing |
28
+ | `r` | Plan review |
29
+ | `f` | Plan fix |
30
+ | `i` | Implementation |
31
+ | `cr` | Code review |
32
+ | `cf` | Code fix |
33
+
34
+ Examples:
35
+
36
+ ```text
37
+ cx-m-42 Codex maps task 42
38
+ cx-p-42 Codex writes plan 42
39
+ cx-r-42 Codex reviews plan 42
40
+ cx-f-42 Codex fixes plan 42
41
+ cx-i-42 Codex implements plan 42
42
+ cx-cr-42 Codex reviews implementation 42
43
+ cx-cf-42 Codex fixes implementation 42
44
+ buddy-42 Buddy monitors task 42
45
+ ```
46
+
47
+ Use names that fit your project. The important part is that the ID is stable,
48
+ short, and present in every artifact.
49
+
50
+ ## Match `--id` And `--tmux`
51
+
52
+ Always pass both and keep them identical:
53
+
54
+ ```bash
55
+ harnex run codex --id cx-i-42 --tmux cx-i-42
56
+ ```
57
+
58
+ Avoid this:
59
+
60
+ ```bash
61
+ harnex run codex --tmux cx-i-42
62
+ ```
63
+
64
+ If `--id` is missing, harnex generates a random session ID. The tmux window may
65
+ look right, but `harnex status`, `harnex pane --id`, and logs need the random
66
+ ID.
67
+
68
+ ## Retry Suffixes
69
+
70
+ If a session fails and you dispatch a fresh attempt, append a suffix:
71
+
72
+ ```text
73
+ cx-i-42 first attempt
74
+ cx-i-42b second attempt
75
+ cx-i-42c third attempt
76
+ ```
77
+
78
+ Keep the old session's logs. They are useful for diagnosis.
79
+
80
+ ## Task Files
81
+
82
+ Use human-readable file names for long instructions:
83
+
84
+ ```text
85
+ /tmp/task-plan-42.md
86
+ /tmp/task-impl-42.md
87
+ /tmp/task-review-42.md
88
+ /tmp/task-fix-42.md
89
+ ```
90
+
91
+ The task file name does not need to duplicate the exact short phase code. It
92
+ should be easy to scan in `/tmp` and should include the same task number as the
93
+ session ID.
94
+
95
+ ## Done Markers
96
+
97
+ Derive done markers from the session ID:
98
+
99
+ ```text
100
+ /tmp/cx-p-42-done.txt
101
+ /tmp/cx-i-42-done.txt
102
+ /tmp/cx-cr-42-done.txt
103
+ ```
104
+
105
+ When a brief asks for a completion marker, make it one line and include the
106
+ highest-signal result: tests passed, review clean, or the blocking issue.
@@ -20,6 +20,16 @@ module Harnex
20
20
  @extra_args = extra_args.dup
21
21
  end
22
22
 
23
+ # Default transport. Adapters speaking JSON-RPC override to
24
+ # :stdio_jsonrpc; Session#run uses this to pick the I/O path.
25
+ def transport
26
+ :pty
27
+ end
28
+
29
+ def describe
30
+ { transport: transport }
31
+ end
32
+
23
33
  def build_command
24
34
  base_command + @extra_args
25
35
  end