harnex 0.2.0
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.
- checksums.yaml +7 -0
- data/GUIDE.md +242 -0
- data/LICENSE +21 -0
- data/README.md +119 -0
- data/TECHNICAL.md +595 -0
- data/bin/harnex +18 -0
- data/lib/harnex/adapters/base.rb +134 -0
- data/lib/harnex/adapters/claude.rb +105 -0
- data/lib/harnex/adapters/codex.rb +112 -0
- data/lib/harnex/adapters/generic.rb +14 -0
- data/lib/harnex/adapters.rb +32 -0
- data/lib/harnex/cli.rb +115 -0
- data/lib/harnex/commands/guide.rb +23 -0
- data/lib/harnex/commands/logs.rb +184 -0
- data/lib/harnex/commands/pane.rb +251 -0
- data/lib/harnex/commands/recipes.rb +104 -0
- data/lib/harnex/commands/run.rb +384 -0
- data/lib/harnex/commands/send.rb +415 -0
- data/lib/harnex/commands/skills.rb +163 -0
- data/lib/harnex/commands/status.rb +171 -0
- data/lib/harnex/commands/stop.rb +127 -0
- data/lib/harnex/commands/wait.rb +165 -0
- data/lib/harnex/core.rb +286 -0
- data/lib/harnex/runtime/api_server.rb +187 -0
- data/lib/harnex/runtime/file_change_hook.rb +111 -0
- data/lib/harnex/runtime/inbox.rb +207 -0
- data/lib/harnex/runtime/message.rb +23 -0
- data/lib/harnex/runtime/session.rb +380 -0
- data/lib/harnex/runtime/session_state.rb +55 -0
- data/lib/harnex/version.rb +3 -0
- data/lib/harnex/watcher/inotify.rb +43 -0
- data/lib/harnex/watcher/polling.rb +92 -0
- data/lib/harnex/watcher.rb +24 -0
- data/lib/harnex.rb +25 -0
- data/recipes/01_fire_and_watch.md +82 -0
- data/recipes/02_chain_implement.md +115 -0
- data/skills/chain-implement/SKILL.md +234 -0
- data/skills/close/SKILL.md +47 -0
- data/skills/dispatch/SKILL.md +171 -0
- data/skills/harnex/SKILL.md +304 -0
- data/skills/open/SKILL.md +32 -0
- metadata +88 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
module Harnex
|
|
2
|
+
module Polling
|
|
3
|
+
POLL_INTERVAL = 0.5
|
|
4
|
+
|
|
5
|
+
class << self
|
|
6
|
+
def available?
|
|
7
|
+
true
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def directory_io(path, _events)
|
|
11
|
+
PollingIO.new(path)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class PollingIO
|
|
16
|
+
EVENT_HEADER_SIZE = 16
|
|
17
|
+
|
|
18
|
+
def initialize(dir_path)
|
|
19
|
+
@dir_path = dir_path
|
|
20
|
+
@snapshots = take_snapshot
|
|
21
|
+
@closed = false
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def readpartial(_maxlen)
|
|
25
|
+
raise IOError, "closed stream" if @closed
|
|
26
|
+
|
|
27
|
+
loop do
|
|
28
|
+
sleep POLL_INTERVAL
|
|
29
|
+
raise IOError, "closed stream" if @closed
|
|
30
|
+
|
|
31
|
+
current = take_snapshot
|
|
32
|
+
changed = detect_changes(@snapshots, current)
|
|
33
|
+
@snapshots = current
|
|
34
|
+
next if changed.empty?
|
|
35
|
+
|
|
36
|
+
return encode_events(changed)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def close
|
|
41
|
+
@closed = true
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def closed?
|
|
45
|
+
@closed
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def take_snapshot
|
|
51
|
+
entries = {}
|
|
52
|
+
Dir.foreach(@dir_path) do |name|
|
|
53
|
+
next if name == "." || name == ".."
|
|
54
|
+
|
|
55
|
+
path = File.join(@dir_path, name)
|
|
56
|
+
stat = File.stat(path)
|
|
57
|
+
entries[name] = { mtime: stat.mtime, size: stat.size }
|
|
58
|
+
rescue Errno::ENOENT, Errno::EACCES
|
|
59
|
+
nil
|
|
60
|
+
end
|
|
61
|
+
entries
|
|
62
|
+
rescue Errno::ENOENT, Errno::EACCES
|
|
63
|
+
{}
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def detect_changes(old_snap, new_snap)
|
|
67
|
+
changed = []
|
|
68
|
+
new_snap.each do |name, info|
|
|
69
|
+
prev = old_snap[name]
|
|
70
|
+
if prev.nil? || prev[:mtime] != info[:mtime] || prev[:size] != info[:size]
|
|
71
|
+
changed << name
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
changed
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def encode_events(names)
|
|
78
|
+
buf = +""
|
|
79
|
+
buf.force_encoding(Encoding::BINARY)
|
|
80
|
+
names.each do |name|
|
|
81
|
+
name_bytes = name.encode(Encoding::BINARY)
|
|
82
|
+
padded_len = (name_bytes.bytesize + 4) & ~3
|
|
83
|
+
# inotify event header: wd(int) + mask(uint) + cookie(uint) + len(uint)
|
|
84
|
+
buf << [0, Harnex::Inotify::IN_CLOSE_WRITE, 0, padded_len].pack("iIII")
|
|
85
|
+
buf << name_bytes
|
|
86
|
+
buf << ("\0" * (padded_len - name_bytes.bytesize))
|
|
87
|
+
end
|
|
88
|
+
buf
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require_relative "watcher/inotify"
|
|
2
|
+
require_relative "watcher/polling"
|
|
3
|
+
|
|
4
|
+
module Harnex
|
|
5
|
+
module Watcher
|
|
6
|
+
module_function
|
|
7
|
+
|
|
8
|
+
def available?
|
|
9
|
+
true
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def directory_io(path, events)
|
|
13
|
+
if Inotify.available?
|
|
14
|
+
Inotify.directory_io(path, events)
|
|
15
|
+
else
|
|
16
|
+
Polling.directory_io(path, events)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def backend
|
|
21
|
+
Inotify.available? ? :inotify : :polling
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
data/lib/harnex.rb
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require "fileutils"
|
|
2
|
+
require "json"
|
|
3
|
+
require "open3"
|
|
4
|
+
|
|
5
|
+
require_relative "harnex/version"
|
|
6
|
+
require_relative "harnex/core"
|
|
7
|
+
require_relative "harnex/watcher"
|
|
8
|
+
require_relative "harnex/adapters"
|
|
9
|
+
require_relative "harnex/runtime/session_state"
|
|
10
|
+
require_relative "harnex/runtime/message"
|
|
11
|
+
require_relative "harnex/runtime/inbox"
|
|
12
|
+
require_relative "harnex/runtime/file_change_hook"
|
|
13
|
+
require_relative "harnex/runtime/api_server"
|
|
14
|
+
require_relative "harnex/runtime/session"
|
|
15
|
+
require_relative "harnex/commands/run"
|
|
16
|
+
require_relative "harnex/commands/send"
|
|
17
|
+
require_relative "harnex/commands/wait"
|
|
18
|
+
require_relative "harnex/commands/stop"
|
|
19
|
+
require_relative "harnex/commands/status"
|
|
20
|
+
require_relative "harnex/commands/logs"
|
|
21
|
+
require_relative "harnex/commands/pane"
|
|
22
|
+
require_relative "harnex/commands/recipes"
|
|
23
|
+
require_relative "harnex/commands/guide"
|
|
24
|
+
require_relative "harnex/commands/skills"
|
|
25
|
+
require_relative "harnex/cli"
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Recipe: Fire and Watch
|
|
2
|
+
|
|
3
|
+
This is the core harnex recipe.
|
|
4
|
+
|
|
5
|
+
Spawn a fresh worker, send it one task, watch its screen until it
|
|
6
|
+
is done, capture the result, stop it. Compose bigger workflows by
|
|
7
|
+
repeating this pattern with file handoffs between steps.
|
|
8
|
+
|
|
9
|
+
## Steps
|
|
10
|
+
|
|
11
|
+
### 1. Spawn the worker
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
harnex run codex --id cx-23 --tmux
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### 2. Send the task
|
|
18
|
+
|
|
19
|
+
If the plan file is self-contained, reference it directly:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
harnex send --id cx-23 --message "Implement koder/plans/plan_23.md. Run tests when done." --wait-for-idle --timeout 1200
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
For tasks that need structured output, tell the worker to write a
|
|
26
|
+
file and inspect the screen separately:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
cat > /tmp/task-cx-23.md <<'EOF'
|
|
30
|
+
Implement koder/plans/plan_23.md.
|
|
31
|
+
Run the full test suite when done.
|
|
32
|
+
Write a short summary to /tmp/impl-23.md.
|
|
33
|
+
EOF
|
|
34
|
+
|
|
35
|
+
harnex send --id cx-23 --message "Read and execute /tmp/task-cx-23.md" --wait-for-idle --timeout 1200
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 3. Watch until done
|
|
39
|
+
|
|
40
|
+
Use `--wait-for-idle` as the fence, then read the worker's screen:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
harnex pane --id cx-23 --lines 25
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
If you prefer to watch while it runs:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
harnex pane --id cx-23 --follow
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
When the worker looks idle, capture a larger snapshot:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
harnex pane --id cx-23 --lines 80
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 4. Stop the worker
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
harnex stop --id cx-23
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Start a fresh worker for the next step instead of reusing this one.
|
|
65
|
+
|
|
66
|
+
## Common step types
|
|
67
|
+
|
|
68
|
+
Use the same pattern for every role:
|
|
69
|
+
|
|
70
|
+
- Codex planning: "Write the plan to `/tmp/plan-23.md`. Do not change code."
|
|
71
|
+
- Codex implementation: "Read `/tmp/plan-23.md`, implement it, run tests, write `/tmp/impl-23.md`."
|
|
72
|
+
- Claude review: "Review current changes against `/tmp/plan-23.md` and write findings to `/tmp/review-23.md`."
|
|
73
|
+
- Codex fix: "Read `/tmp/review-23.md`, fix the issues, run tests, write `/tmp/fix-23.md`."
|
|
74
|
+
|
|
75
|
+
## Rationale
|
|
76
|
+
|
|
77
|
+
This is the dependable path because it minimizes the fragile parts:
|
|
78
|
+
|
|
79
|
+
- Fresh worker per step avoids context bleed and stale inbox state
|
|
80
|
+
- File artifacts are easier to pass between steps than callback messages
|
|
81
|
+
- `harnex pane` shows the truth even when the worker ignores reply instructions
|
|
82
|
+
- Stopping the worker after each step keeps the workflow disposable
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Recipe: Chain Implement
|
|
2
|
+
|
|
3
|
+
This is repeated fire-and-watch for a batch of jobs.
|
|
4
|
+
|
|
5
|
+
Process plans in series. For each plan, use fresh instances for
|
|
6
|
+
every step:
|
|
7
|
+
|
|
8
|
+
- Codex plans or implements
|
|
9
|
+
- Claude reviews
|
|
10
|
+
- Codex fixes
|
|
11
|
+
- Repeat review and fix until clean, then move to the next plan
|
|
12
|
+
|
|
13
|
+
## Trigger
|
|
14
|
+
|
|
15
|
+
User says something like:
|
|
16
|
+
- "implement plans 23 to 27, review each, fix issues"
|
|
17
|
+
- "implement plans 23 to 27, use fresh Codex for implementation
|
|
18
|
+
and fresh Claude for review on every plan"
|
|
19
|
+
|
|
20
|
+
## Procedure
|
|
21
|
+
|
|
22
|
+
For each plan in the batch:
|
|
23
|
+
|
|
24
|
+
### Step 1: Plan or confirm the plan
|
|
25
|
+
|
|
26
|
+
If the plan file does not already exist or needs refinement, spawn a
|
|
27
|
+
fresh Codex planner and tell it to write a plan artifact.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
harnex run codex --id cx-plan-23 --tmux
|
|
31
|
+
harnex send --id cx-plan-23 --message "Write a concrete implementation plan for plan 23 to /tmp/plan-23.md. Do not change code." --wait-for-idle --timeout 600
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Inspect with `harnex pane --id cx-plan-23 --lines 60`, then stop it.
|
|
35
|
+
|
|
36
|
+
If the plan is already written and trusted, skip this step and use the
|
|
37
|
+
existing plan file directly.
|
|
38
|
+
|
|
39
|
+
### Step 2: Implement
|
|
40
|
+
|
|
41
|
+
Spawn a fresh Codex worker, send it the plan, watch it, stop it.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
harnex run codex --id cx-impl-23-r1 --tmux
|
|
45
|
+
harnex send --id cx-impl-23-r1 --message "Read /tmp/plan-23.md, implement it, run tests, and write a summary to /tmp/impl-23-r1.md." --wait-for-idle --timeout 1200
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Inspect with `harnex pane --id cx-impl-23-r1 --lines 80`, then stop it.
|
|
49
|
+
|
|
50
|
+
### Step 3: Review
|
|
51
|
+
|
|
52
|
+
Spawn a fresh Claude reviewer. Claude is only used for reviews in this
|
|
53
|
+
recipe.
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
harnex run claude --id cl-rev-23-r1 --tmux
|
|
57
|
+
harnex send --id cl-rev-23-r1 --message "Review the current changes against /tmp/plan-23.md. Write findings to /tmp/review-23-r1.md. If there are no issues, say clean." --wait-for-idle --timeout 900
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Inspect with `harnex pane --id cl-rev-23-r1 --lines 80`, then stop it.
|
|
61
|
+
|
|
62
|
+
### Step 4: Fix and repeat if needed
|
|
63
|
+
|
|
64
|
+
If the review is clean, move to the next plan.
|
|
65
|
+
|
|
66
|
+
If the review finds issues, spawn a fresh Codex fixer:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
harnex run codex --id cx-fix-23-r1 --tmux
|
|
70
|
+
harnex send --id cx-fix-23-r1 --message "Read /tmp/review-23-r1.md, fix every issue, run tests, and write a summary to /tmp/fix-23-r1.md." --wait-for-idle --timeout 1200
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Inspect with `harnex pane --id cx-fix-23-r1 --lines 80`, then stop it.
|
|
74
|
+
|
|
75
|
+
Then spawn another fresh Claude reviewer and repeat the review and fix
|
|
76
|
+
loop until clean or until you decide the plan needs manual attention.
|
|
77
|
+
|
|
78
|
+
### Step 5: Next plan
|
|
79
|
+
|
|
80
|
+
Move to plan 24. Repeat from step 1.
|
|
81
|
+
|
|
82
|
+
## Naming convention
|
|
83
|
+
|
|
84
|
+
Use the plan number in every worker ID so you can tell them apart in
|
|
85
|
+
`harnex status`:
|
|
86
|
+
|
|
87
|
+
| Step | ID pattern | Example |
|
|
88
|
+
| --- | --- | --- |
|
|
89
|
+
| Plan | `cx-plan-NN` | `cx-plan-23` |
|
|
90
|
+
| Implement | `cx-impl-NN-rM` | `cx-impl-23-r1` |
|
|
91
|
+
| Review | `cl-rev-NN-rM` | `cl-rev-23-r1` |
|
|
92
|
+
| Fix | `cx-fix-NN-rM` | `cx-fix-23-r1` |
|
|
93
|
+
|
|
94
|
+
## Notes
|
|
95
|
+
|
|
96
|
+
- Each step uses a fresh instance. Don't reuse a worker across
|
|
97
|
+
steps or rounds. A clean context avoids bleed between plan,
|
|
98
|
+
implement, review, and fix.
|
|
99
|
+
- The batch is serial. Finish plan 23 completely before starting
|
|
100
|
+
plan 24. Plans often build on each other.
|
|
101
|
+
- Claude only reviews. Do not use Claude as the planner or fixer in
|
|
102
|
+
this recipe.
|
|
103
|
+
- Pass artifacts between steps as files (`/tmp/plan-23.md`,
|
|
104
|
+
`/tmp/review-23-r1.md`), not as harnex reply messages.
|
|
105
|
+
- If the review finds no issues, skip the fix step and move on.
|
|
106
|
+
|
|
107
|
+
## Rationale
|
|
108
|
+
|
|
109
|
+
This recipe is not a different control model. It is just
|
|
110
|
+
fire-and-watch repeated with stronger discipline:
|
|
111
|
+
|
|
112
|
+
- one worker per step
|
|
113
|
+
- one artifact per handoff
|
|
114
|
+
- one reviewer role, always Claude
|
|
115
|
+
- one serial job stream, so later plans see earlier fixes
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: chain-implement
|
|
3
|
+
description: End-to-end workflow from issue to shipped plans via harnex agents. Covers mapping, plan extraction, and the serial plan → review → implement → review → fix loop.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Chain Implement
|
|
7
|
+
|
|
8
|
+
Take an issue from design through to shipped code via harnex agents. Designed
|
|
9
|
+
so the user can walk away after triggering the chain.
|
|
10
|
+
|
|
11
|
+
## Guiding Principle
|
|
12
|
+
|
|
13
|
+
Keep each agent invocation inside its **safe context zone** (< 40% of context
|
|
14
|
+
window). Agents produce their smartest work when they aren't overloaded. Large
|
|
15
|
+
issues get split into smaller plans because massive plans degrade agent output.
|
|
16
|
+
|
|
17
|
+
**Scale the process to the work:**
|
|
18
|
+
- Small issue, one coherent change → skip mapping, write one plan, implement
|
|
19
|
+
- Medium issue, a few moving parts → one plan with phases is fine
|
|
20
|
+
- Large issue, many files/seams/sequencing → mapping plan + extracted plans
|
|
21
|
+
|
|
22
|
+
The phases below describe the **full** workflow. Skip phases that aren't needed.
|
|
23
|
+
|
|
24
|
+
## Workflow Overview
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
Issue (user + agent chat)
|
|
28
|
+
↓
|
|
29
|
+
[Mapping Plan] → [Map Review] → [Fix Map] ← skip if scope is small
|
|
30
|
+
↓
|
|
31
|
+
[Plan Extraction] → thin-layer plans ← skip if one plan suffices
|
|
32
|
+
↓
|
|
33
|
+
Per plan (serial):
|
|
34
|
+
Plan (codex) → Plan Review (claude) → Fix Plan (codex)
|
|
35
|
+
→ Implement (codex) → Code Review (claude) → Fix Code (codex)
|
|
36
|
+
→ Commit → next plan
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Why two review phases?
|
|
40
|
+
|
|
41
|
+
The plan review catches design problems before code is written. The code review
|
|
42
|
+
catches implementation problems after. Skipping plan review leads to wasted
|
|
43
|
+
implementation cycles when the plan itself is flawed. This was validated in
|
|
44
|
+
production — adversarial plan/review cycles consistently produce better outcomes
|
|
45
|
+
than jumping straight to implementation.
|
|
46
|
+
|
|
47
|
+
## Phase 1: Issue
|
|
48
|
+
|
|
49
|
+
The user and the agent have a detailed design chat. From that, a structured
|
|
50
|
+
issue is filed (e.g., `koder/issues/NN_label/INDEX.md`).
|
|
51
|
+
|
|
52
|
+
The issue captures:
|
|
53
|
+
- The problem and motivation
|
|
54
|
+
- Design decisions and trade-offs
|
|
55
|
+
- Acceptance criteria
|
|
56
|
+
- Known open questions
|
|
57
|
+
|
|
58
|
+
This phase is interactive — the user is present and driving.
|
|
59
|
+
|
|
60
|
+
## Phase 2: Mapping Plan (optional — for large issues)
|
|
61
|
+
|
|
62
|
+
Skip if the issue is small enough for a single implementation plan. Use when
|
|
63
|
+
the scope crosses many files, involves sequencing constraints, or has open
|
|
64
|
+
design questions that would block an away user.
|
|
65
|
+
|
|
66
|
+
A **mapping plan** doesn't produce code. It produces a detailed technical map:
|
|
67
|
+
- Exact files, functions, and seams involved
|
|
68
|
+
- Sequencing constraints (what depends on what)
|
|
69
|
+
- Questions that need user input before implementation
|
|
70
|
+
|
|
71
|
+
### Why mapping is its own phase
|
|
72
|
+
|
|
73
|
+
- **Surfaces blockers early** — user-blocking decisions come out here, not
|
|
74
|
+
halfway through implementation
|
|
75
|
+
- **Creates shared context** — the mapping plan becomes the reference for all
|
|
76
|
+
subsequent plans
|
|
77
|
+
- **Separates research from decomposition** — mapping agent focuses on
|
|
78
|
+
understanding, extraction focuses on scoping
|
|
79
|
+
|
|
80
|
+
### Dispatch
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
harnex run codex --id cx-map-NN --tmux cx-map-NN \
|
|
84
|
+
--context "Write a mapping plan for koder/issues/NN_label/INDEX.md. \
|
|
85
|
+
Produce a detailed technical map: files, seams, sequencing, open questions. \
|
|
86
|
+
Write to koder/plans/NN_mapping.md."
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Poll every 30s with `harnex pane --id cx-map-NN --lines 20`.
|
|
90
|
+
|
|
91
|
+
### Map Review
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
harnex run claude --id cl-rev-map-NN --tmux cl-rev-map-NN \
|
|
95
|
+
--context "Review koder/plans/NN_mapping.md. Check: unresolved user questions? \
|
|
96
|
+
Accurate file/function analysis? Sequencing constraints identified? \
|
|
97
|
+
Write review to koder/reviews/NN_mapping.md"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**If user-blocking questions exist**, stop the chain and surface them.
|
|
101
|
+
|
|
102
|
+
## Phase 3: Plan Extraction (optional)
|
|
103
|
+
|
|
104
|
+
Skip if the mapping plan describes one coherent change, or if you skipped
|
|
105
|
+
mapping entirely.
|
|
106
|
+
|
|
107
|
+
Extract thin-layer implementation plans from the mapping plan. Each plan is:
|
|
108
|
+
- **One capability** — testable independently
|
|
109
|
+
- **Self-contained** — the implementing agent reads only that plan file
|
|
110
|
+
- **Ordered** — respects sequencing constraints from the mapping plan
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
harnex run codex --id cx-extract-NN --tmux cx-extract-NN \
|
|
114
|
+
--context "Read koder/plans/NN_mapping.md. Extract thin-layer plans. \
|
|
115
|
+
Each plan is one independently testable capability. Write to koder/plans/."
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Phase 4: Serial Plan Loop
|
|
119
|
+
|
|
120
|
+
Each plan goes through the full cycle. This is the walk-away part.
|
|
121
|
+
|
|
122
|
+
### Per-plan cycle
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
1. Plan (codex) — write/refine the plan if not already extracted
|
|
126
|
+
2. Plan Review (claude) — check plan against codebase, flag issues
|
|
127
|
+
3. Fix Plan (codex) — address review findings
|
|
128
|
+
4. Implement (codex) — write code, run tests, commit per phase
|
|
129
|
+
5. Code Review (claude) — review implementation against plan
|
|
130
|
+
6. Fix Code (codex) — address review findings if needed
|
|
131
|
+
7. Commit — final state on master
|
|
132
|
+
8. → next plan
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Steps 1-3 can be skipped if the plan was already extracted and reviewed during
|
|
136
|
+
the mapping phase, or if the issue is simple enough that the plan is obviously
|
|
137
|
+
correct.
|
|
138
|
+
|
|
139
|
+
### Dispatch pattern
|
|
140
|
+
|
|
141
|
+
For each plan NN, use the Fire & Watch pattern from the `dispatch` skill:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# Steps 1-3: Plan convergence (skip if plan already extracted and reviewed)
|
|
145
|
+
harnex run codex --id cx-plan-NN --tmux cx-plan-NN \
|
|
146
|
+
--context "Refine koder/plans/NN_label.md based on current codebase state."
|
|
147
|
+
# Poll every 30s: harnex pane --id cx-plan-NN --lines 20
|
|
148
|
+
# When done: harnex stop --id cx-plan-NN
|
|
149
|
+
|
|
150
|
+
harnex run claude --id cl-rev-plan-NN --tmux cl-rev-plan-NN \
|
|
151
|
+
--context "Review koder/plans/NN_label.md. Check: accurate file/function refs? \
|
|
152
|
+
Sequencing correct? Acceptance criteria testable? \
|
|
153
|
+
Write review to koder/reviews/NN_label.md"
|
|
154
|
+
# Poll → stop → if NEEDS FIXES, dispatch cx-fix-plan-NN
|
|
155
|
+
|
|
156
|
+
# Step 4: Implement
|
|
157
|
+
harnex run codex --id cx-impl-NN --tmux cx-impl-NN \
|
|
158
|
+
--context "Implement koder/plans/NN_label.md. Run tests when done. Commit after each phase."
|
|
159
|
+
# Poll every 30s: harnex pane --id cx-impl-NN --lines 20
|
|
160
|
+
# When done: harnex stop --id cx-impl-NN
|
|
161
|
+
|
|
162
|
+
# Steps 5-6: Code review + fix
|
|
163
|
+
harnex run claude --id cl-rev-NN --tmux cl-rev-NN \
|
|
164
|
+
--context "Review implementation of plan NN against koder/plans/NN_label.md. \
|
|
165
|
+
Write review to koder/reviews/NN_label.md"
|
|
166
|
+
# Poll every 30s: harnex pane --id cl-rev-NN --lines 20
|
|
167
|
+
# When done: harnex stop --id cl-rev-NN
|
|
168
|
+
# If NEEDS FIXES → dispatch cx-fix-NN
|
|
169
|
+
# If PASS → next plan
|
|
170
|
+
|
|
171
|
+
# Fix (if needed)
|
|
172
|
+
harnex run codex --id cx-fix-NN --tmux cx-fix-NN \
|
|
173
|
+
--context "Fix findings in koder/reviews/NN_label.md for plan NN. Run tests. Commit."
|
|
174
|
+
# Poll, stop, re-review if needed
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Poll cadence
|
|
178
|
+
|
|
179
|
+
Checking is cheap — 20 lines is a few hundred bytes:
|
|
180
|
+
|
|
181
|
+
| Elapsed | Interval | Rationale |
|
|
182
|
+
|---------|----------|-----------|
|
|
183
|
+
| 0–2 min | 30s | Catch fast completions and early errors |
|
|
184
|
+
| 2–10 min | 60s | Steady state for typical work |
|
|
185
|
+
| 10+ min | 120s | Long-running, reduce noise |
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
harnex pane --id cx-impl-NN --lines 20
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Naming conventions
|
|
192
|
+
|
|
193
|
+
| Step | ID pattern | Example |
|
|
194
|
+
|------|-----------|---------|
|
|
195
|
+
| Mapping plan | `cx-map-NN` | `cx-map-42` |
|
|
196
|
+
| Map review | `cl-rev-map-NN` | `cl-rev-map-42` |
|
|
197
|
+
| Plan extraction | `cx-extract-NN` | `cx-extract-42` |
|
|
198
|
+
| Plan write/refine | `cx-plan-NN` | `cx-plan-184` |
|
|
199
|
+
| Plan review | `cl-rev-plan-NN` | `cl-rev-plan-184` |
|
|
200
|
+
| Plan fix | `cx-fix-plan-NN` | `cx-fix-plan-184` |
|
|
201
|
+
| Implement | `cx-impl-NN` | `cx-impl-184` |
|
|
202
|
+
| Code review | `cl-rev-NN` | `cl-rev-184` |
|
|
203
|
+
| Code fix | `cx-fix-NN` | `cx-fix-184` |
|
|
204
|
+
|
|
205
|
+
**Rule**: Fresh instance per step. Don't reuse agents across steps — clean
|
|
206
|
+
context avoids bleed.
|
|
207
|
+
|
|
208
|
+
## Worktree Option
|
|
209
|
+
|
|
210
|
+
By default, all work happens serially on master. Use worktrees only when:
|
|
211
|
+
- The user explicitly requests isolation
|
|
212
|
+
- You need to work on something else while a plan is being implemented
|
|
213
|
+
|
|
214
|
+
See the `dispatch` skill for worktree setup and caveats.
|
|
215
|
+
|
|
216
|
+
## When Things Go Wrong
|
|
217
|
+
|
|
218
|
+
**Plan review finds user-blocking question**: Stop the chain. Surface the
|
|
219
|
+
question. Resume after the user answers. This is exactly what the plan review
|
|
220
|
+
phase is for — catching these before implementation begins.
|
|
221
|
+
|
|
222
|
+
**Plan review finds P1**: Dispatch a plan fix agent (`cx-fix-plan-NN`).
|
|
223
|
+
Re-review the plan. Do not proceed to implementation with unresolved P1s.
|
|
224
|
+
|
|
225
|
+
**Code review finds P1**: Dispatch a code fix agent (`cx-fix-NN`). Re-review
|
|
226
|
+
after fix. Do not skip to the next plan with unresolved P1s.
|
|
227
|
+
|
|
228
|
+
**Implementation diverges from plan**: The implementer may discover the plan
|
|
229
|
+
is wrong. If the divergence is minor (P3), note it and continue. If major,
|
|
230
|
+
stop and re-plan.
|
|
231
|
+
|
|
232
|
+
**Agent gets stuck**: Check `harnex pane --lines 20`. If blocked on a
|
|
233
|
+
permission prompt or trust dialog, intervene. If confused, stop the agent and
|
|
234
|
+
dispatch a fresh one with clearer instructions.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: close
|
|
3
|
+
description: Close a work session in this repo — update koder/STATE.md with what changed and the next step, clean up accidental or temporary repo artifacts, and leave a clear handoff. Use when the user says "close session", "wrap up", "end session", "handoff", or invokes "/close".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Close Session Workflow
|
|
7
|
+
|
|
8
|
+
When the user asks to wrap up or close the current session, run this sequence:
|
|
9
|
+
|
|
10
|
+
## 1. Review the session changes
|
|
11
|
+
|
|
12
|
+
- Check `git status --short` and `git diff --stat`
|
|
13
|
+
- Separate the work from this session from unrelated user changes
|
|
14
|
+
- Do not revert unrelated changes you did not make
|
|
15
|
+
|
|
16
|
+
## 2. Update `koder/STATE.md`
|
|
17
|
+
|
|
18
|
+
- Update the `Updated:` date
|
|
19
|
+
- Add or adjust concise lines in `Current snapshot` for completed work
|
|
20
|
+
- Update test count if it changed
|
|
21
|
+
- Update issue or plan statuses only when work was actually completed or a new blocker was clearly discovered
|
|
22
|
+
- Rewrite `Next step` so the next agent can resume without reconstructing context
|
|
23
|
+
|
|
24
|
+
## 3. Clean up repo artifacts
|
|
25
|
+
|
|
26
|
+
- Remove temporary files, scratch notes, or mistaken tracking docs created during the session
|
|
27
|
+
- Keep durable artifacts that are part of the intended result
|
|
28
|
+
- If cleanup would discard ambiguous work, ask the user instead of guessing
|
|
29
|
+
|
|
30
|
+
## 4. Commit and clean the repo
|
|
31
|
+
|
|
32
|
+
- Stage all session changes (code, docs, STATE.md updates) and commit with a clear message summarizing the session's work
|
|
33
|
+
- Do NOT stage files that look like secrets, credentials, or large binaries — flag them to the user
|
|
34
|
+
- After committing, run `git status --short` to confirm a clean working tree
|
|
35
|
+
- If unrelated uncommitted changes remain, leave them alone — do not revert or commit work you did not produce
|
|
36
|
+
|
|
37
|
+
## 5. Verify the handoff
|
|
38
|
+
|
|
39
|
+
- Run the relevant tests or verification commands if code or docs changed
|
|
40
|
+
- Give the user a concise summary of what changed, the commit, and any remaining follow-up
|
|
41
|
+
- The goal: the next `/open` should see a clean repo and an accurate `koder/STATE.md`
|
|
42
|
+
|
|
43
|
+
## Notes
|
|
44
|
+
|
|
45
|
+
- Do NOT create or close issue docs unless the user explicitly asks
|
|
46
|
+
- Do NOT build, install, or publish anything unless the user explicitly asks
|
|
47
|
+
- If `koder/STATE.md` is already accurate, keep the update minimal rather than churning it
|