@walwal-harness/cli 7.1.21 → 7.1.22
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.
- package/CHANGELOG.md +9 -0
- package/HR-Resource/ceo/SKILL.md +1 -0
- package/README.md +19 -0
- package/assets/templates/company-pipeline-manifest.json +1 -0
- package/assets/templates/progress.json.template +8 -0
- package/package.json +1 -1
- package/scripts/harness-company-complete.sh +43 -0
- package/scripts/harness-stop.sh +19 -5
- package/scripts/harness-user-prompt-submit.sh +4 -0
package/CHANGELOG.md
CHANGED
|
@@ -31,6 +31,15 @@ docmeta:
|
|
|
31
31
|
|
|
32
32
|
## Unreleased
|
|
33
33
|
|
|
34
|
+
### Fixed
|
|
35
|
+
- v7 `/goal`, `/submission`, and `/hot-fix` now mark both `company_state.state` and `conductor.state` as `running`, so Claude Stop hook auto-chain does not stop after CEO routing or hiring-only summaries.
|
|
36
|
+
- Stop hook now treats v7 CEO routing state (`current_agent=ceo`, `agent_status=running`, `owner_prompt.status=routing`) as an unfinished company loop, including migrated projects that do not yet have running conductor/company state.
|
|
37
|
+
- CEO skill now explicitly forbids ending a mission turn with only hiring/resource-manager output while the Owner goal remains unfinished.
|
|
38
|
+
|
|
39
|
+
### Added
|
|
40
|
+
- `scripts/harness-company-complete.sh` provides the shared running → idle/completed transition for dashboard auto-mode, external runners, hooks, and final CEO handoff paths.
|
|
41
|
+
- New progress templates include `company_state.state` and default `conductor` fields for consistent runner/dashboard state.
|
|
42
|
+
|
|
34
43
|
### Changed
|
|
35
44
|
- Dashboard Org Tree now positions only hired HR-Resource workers from `hr-roster.json`, requiring a backing `.harness/shared/HR-Resource/{worker}/SKILL.md`.
|
|
36
45
|
- Running hired workers are highlighted under their owning CXX instead of showing queue jobs as worker seats.
|
package/HR-Resource/ceo/SKILL.md
CHANGED
|
@@ -30,6 +30,7 @@ You are the only direct conversation channel with the Owner.
|
|
|
30
30
|
- If a suitable hired worker is absent, invoke the `harness-hiring` skill before the CXX proceeds with that deliverable.
|
|
31
31
|
- CEO must reject CXX reports that contain completed specialist deliverables without matching worker records under `.harness/documents/{goal-or-child-mission}/{owning-cxx}/workers/`.
|
|
32
32
|
- Every CXX starts from fresh context and records decisions in `.harness/documents/{goal-or-child-mission}/{cxx}.md`.
|
|
33
|
+
- Hiring or resource-manager output is never a stopping point. After missing workers are registered, immediately continue routing to the responsible CXX fresh sessions and require those CXX agents to brief/run the hired workers. Do not end the turn with only a hiring summary while the Owner goal remains unfinished.
|
|
33
34
|
- Preserve DDD boundaries: domain decisions, application wiring, infrastructure, and quality policy are separate responsibilities.
|
|
34
35
|
- Before CTO/CDO/OPS allocate runnable services, agree with the Owner on a `{xx}000` base port and write it to project `.env` as `HARNESS_BASE_PORT={xx}000`. Mentioning the value in `ceo.md` is not sufficient.
|
|
35
36
|
- After writing `.env`, verify with `grep '^HARNESS_BASE_PORT=' .env` before routing service work.
|
package/README.md
CHANGED
|
@@ -158,6 +158,25 @@ Dashboard options:
|
|
|
158
158
|
| `--port <port>` | Run Brick Office on a custom port, e.g. `3002` |
|
|
159
159
|
| `--reinstall` | Delete and rebuild the isolated dashboard cache under `~/.walwal-harness/dashboard/` |
|
|
160
160
|
|
|
161
|
+
### Company Auto-Chain State
|
|
162
|
+
|
|
163
|
+
`/goal`, `/submission`, and `/hot-fix` mark the v7 company loop as running in `.harness/progress.json`:
|
|
164
|
+
|
|
165
|
+
- `company_state.state = "running"`
|
|
166
|
+
- `conductor.state = "running"`
|
|
167
|
+
- `current_agent = "ceo"`
|
|
168
|
+
- `next_agent = "ceo"`
|
|
169
|
+
|
|
170
|
+
Claude's Stop hook uses this state to prevent an unfinished CEO/CXX/worker loop from ending after a partial routing step such as hiring. Hookless executors such as Codex should drive the same state through an external runner or dashboard auto-mode process.
|
|
171
|
+
|
|
172
|
+
When the mission is genuinely complete, the common completion transition is:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
bash scripts/harness-company-complete.sh . mission-complete
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
This sets `company_state.state = "idle"`, `conductor.state = "completed"`, `next_agent = "none"`, and `owner_prompt.status = "completed"` so dashboards, runners, and hooks agree that auto-mode can stop.
|
|
179
|
+
|
|
161
180
|
Existing users should update and migrate from the target project:
|
|
162
181
|
|
|
163
182
|
```bash
|
|
@@ -48,11 +48,19 @@
|
|
|
48
48
|
"sprint-contract.md": { "status": "pending", "updated_by": null, "updated_at": null }
|
|
49
49
|
},
|
|
50
50
|
"company_state": {
|
|
51
|
+
"state": "idle",
|
|
51
52
|
"active_workers": 0,
|
|
52
53
|
"concurrency": 3,
|
|
53
54
|
"paused_at": null,
|
|
54
55
|
"resume_from": null
|
|
55
56
|
},
|
|
57
|
+
"conductor": {
|
|
58
|
+
"state": "idle",
|
|
59
|
+
"tracks": [],
|
|
60
|
+
"rendezvous": null,
|
|
61
|
+
"fork_meeting_id": null,
|
|
62
|
+
"stop_chain_count": 0
|
|
63
|
+
},
|
|
56
64
|
"updated_at": "{{DATE}}",
|
|
57
65
|
"history": []
|
|
58
66
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walwal-harness/cli",
|
|
3
|
-
"version": "7.1.
|
|
3
|
+
"version": "7.1.22",
|
|
4
4
|
"description": "Company-style AI agent harness for Claude and Codex. Installs commands, CXX agents, skills, HR-Resource hiring pool, and project-local .harness runtime state.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"walwal-harness": "bin/init.js"
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# harness-company-complete.sh — mark the current v7 company mission complete.
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# bash scripts/harness-company-complete.sh <project-root> [reason]
|
|
6
|
+
#
|
|
7
|
+
# This is the explicit running -> idle/done transition used by dashboard,
|
|
8
|
+
# runner, hooks, and final CEO handoff paths. It intentionally only updates
|
|
9
|
+
# runtime state; it does not archive or rewrite mission documents.
|
|
10
|
+
|
|
11
|
+
set -uo pipefail
|
|
12
|
+
|
|
13
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
14
|
+
PROJECT_ROOT="${1:-.}"
|
|
15
|
+
REASON="${2:-mission-complete}"
|
|
16
|
+
|
|
17
|
+
PROGRESS="$PROJECT_ROOT/.harness/progress.json"
|
|
18
|
+
[ -f "$PROGRESS" ] || {
|
|
19
|
+
echo "[company-complete] not found: $PROGRESS" >&2
|
|
20
|
+
exit 1
|
|
21
|
+
}
|
|
22
|
+
command -v jq >/dev/null 2>&1 || {
|
|
23
|
+
echo "[company-complete] jq is required" >&2
|
|
24
|
+
exit 1
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
bash "$SCRIPT_DIR/harness-progress-set.sh" "$PROJECT_ROOT" \
|
|
28
|
+
'.company_state.state = "idle" |
|
|
29
|
+
.company_state.active_workers = 0 |
|
|
30
|
+
.company_state.completed_at = (now | todate) |
|
|
31
|
+
.conductor.state = "completed" |
|
|
32
|
+
.conductor.current_action = "complete:'"$REASON"'" |
|
|
33
|
+
.conductor.completed_at = (now | todate) |
|
|
34
|
+
.conductor.tracks = [] |
|
|
35
|
+
.conductor.rendezvous = null |
|
|
36
|
+
.conductor.fork_meeting_id = null |
|
|
37
|
+
.current_agent = null |
|
|
38
|
+
.next_agent = "none" |
|
|
39
|
+
.agent_status = "completed" |
|
|
40
|
+
.owner_prompt.status = "completed" |
|
|
41
|
+
.owner_prompt.completed_at = (now | todate)'
|
|
42
|
+
|
|
43
|
+
echo "[company-complete] marked complete: $REASON"
|
package/scripts/harness-stop.sh
CHANGED
|
@@ -52,8 +52,11 @@ if [ "${STOP_CHAIN_COUNT:-0}" -ge "${STOP_CHAIN_MAX:-200}" ]; then exit 0; fi
|
|
|
52
52
|
|
|
53
53
|
# 회사 루프 상태 확인
|
|
54
54
|
CONDUCTOR_STATE=$(jq -r '.conductor.state // "idle"' "$PROGRESS" 2>/dev/null || echo "idle")
|
|
55
|
+
COMPANY_STATE=$(jq -r '.company_state.state // "idle"' "$PROGRESS" 2>/dev/null || echo "idle")
|
|
56
|
+
CURRENT_AGENT=$(jq -r '.current_agent // "none"' "$PROGRESS" 2>/dev/null || echo "none")
|
|
55
57
|
NEXT_AGENT=$(jq -r '.next_agent // "none"' "$PROGRESS" 2>/dev/null || echo "none")
|
|
56
58
|
AGENT_STATUS=$(jq -r '.agent_status // "pending"' "$PROGRESS" 2>/dev/null || echo "pending")
|
|
59
|
+
OWNER_PROMPT_STATUS=$(jq -r '.owner_prompt.status // "none"' "$PROGRESS" 2>/dev/null || echo "none")
|
|
57
60
|
TASK_STOP_ACTIVE=$(jq -r '.task_stop.active // false' "$PROGRESS" 2>/dev/null || echo "false")
|
|
58
61
|
ESCALATION=$(jq -r '.conductor.escalation // "null"' "$PROGRESS" 2>/dev/null || echo "null")
|
|
59
62
|
SPRINT_STATUS=$(jq -r '.sprint.status // "init"' "$PROGRESS" 2>/dev/null || echo "init")
|
|
@@ -66,19 +69,30 @@ if [ "$HOOK_EVENT" = "Stop" ]; then
|
|
|
66
69
|
fi
|
|
67
70
|
|
|
68
71
|
# 자동 연쇄 조건:
|
|
69
|
-
# conductor 가 running
|
|
70
|
-
# AND task_stop 비활성
|
|
72
|
+
# conductor/company loop 가 running
|
|
71
73
|
# AND task_stop 비활성
|
|
72
74
|
# AND (next_agent 가 명시되어 있거나, agent_status=completed 라서 다음 tick 결정 필요)
|
|
75
|
+
# v7 CEO 루프는 conductor-tick 없이 CEO/CXX 상태로 시작될 수 있다.
|
|
76
|
+
# current_agent=ceo running + owner_prompt.routing 은 기존 설치본이 conductor/company
|
|
77
|
+
# state를 아직 쓰지 않은 stuck 상태에서도 turn 종료 차단 대상으로 본다.
|
|
73
78
|
should_chain="false"
|
|
74
|
-
if [ "$CONDUCTOR_STATE" = "running" ] \
|
|
79
|
+
if { [ "$CONDUCTOR_STATE" = "running" ] || [ "$COMPANY_STATE" = "running" ]; } \
|
|
75
80
|
&& [ "$TASK_STOP_ACTIVE" != "true" ]; then
|
|
76
81
|
if [ "$NEXT_AGENT" != "none" ] && [ "$NEXT_AGENT" != "null" ]; then
|
|
77
82
|
should_chain="true"
|
|
78
83
|
elif [ "$AGENT_STATUS" = "completed" ]; then
|
|
79
84
|
should_chain="true"
|
|
85
|
+
elif [ "$CURRENT_AGENT" = "ceo" ] && [ "$AGENT_STATUS" = "running" ] && [ "$OWNER_PROMPT_STATUS" = "routing" ]; then
|
|
86
|
+
should_chain="true"
|
|
80
87
|
fi
|
|
81
88
|
fi
|
|
89
|
+
if [ "$should_chain" != "true" ] \
|
|
90
|
+
&& [ "$TASK_STOP_ACTIVE" != "true" ] \
|
|
91
|
+
&& [ "$CURRENT_AGENT" = "ceo" ] \
|
|
92
|
+
&& [ "$AGENT_STATUS" = "running" ] \
|
|
93
|
+
&& [ "$OWNER_PROMPT_STATUS" = "routing" ]; then
|
|
94
|
+
should_chain="true"
|
|
95
|
+
fi
|
|
82
96
|
|
|
83
97
|
if [ "$should_chain" != "true" ]; then exit 0; fi
|
|
84
98
|
|
|
@@ -91,9 +105,9 @@ jq --argjson n "$NEW_COUNT" '.conductor.stop_chain_count = $n |
|
|
|
91
105
|
|
|
92
106
|
# Claude 에게 다음 행동 지시
|
|
93
107
|
if [ "$ESCALATION" != "null" ]; then
|
|
94
|
-
REASON="자율 회사 루프 진행 중. escalation=${ESCALATION} 는 정지 사유가 아니라 meeting-manager/service-ops 공유 대상이다. next_agent=${NEXT_AGENT}, agent_status=${AGENT_STATUS}, conductor=${CONDUCTOR_STATE}. SKILL 에 따라 conductor-tick 을 굴려 meeting-manager 회의로
|
|
108
|
+
REASON="자율 회사 루프 진행 중. escalation=${ESCALATION} 는 정지 사유가 아니라 meeting-manager/service-ops 공유 대상이다. current_agent=${CURRENT_AGENT}, next_agent=${NEXT_AGENT}, agent_status=${AGENT_STATUS}, conductor=${CONDUCTOR_STATE}, company=${COMPANY_STATE}. SKILL 에 따라 CEO/CXX/worker 흐름을 계속하거나 conductor-tick 을 굴려 meeting-manager 회의로 라우팅하라. progress.log 에는 절대 미래 시각을 쓰지 말 것. 진짜로 끝났을 때만 turn 을 종료하라."
|
|
95
109
|
else
|
|
96
|
-
REASON="자율 회사 루프 진행 중. next_agent=${NEXT_AGENT}, agent_status=${AGENT_STATUS}, conductor=${CONDUCTOR_STATE}. SKILL 에 따라
|
|
110
|
+
REASON="자율 회사 루프 진행 중. current_agent=${CURRENT_AGENT}, next_agent=${NEXT_AGENT}, agent_status=${AGENT_STATUS}, conductor=${CONDUCTOR_STATE}, company=${COMPANY_STATE}. SKILL 에 따라 CEO/CXX/worker 흐름을 계속하고, 필요한 CXX/worker fresh session 을 실행하라. progress.log 에는 절대 미래 시각을 쓰지 말 것. 진짜로 끝났을 때만 turn 을 종료하라."
|
|
97
111
|
fi
|
|
98
112
|
|
|
99
113
|
jq -nc \
|
|
@@ -83,6 +83,10 @@ if [ -n "$PROMPT" ] && [ -d "$CWD/.harness" ]; then
|
|
|
83
83
|
.current_agent = "ceo" |
|
|
84
84
|
.agent_status = "running" |
|
|
85
85
|
.next_agent = "ceo" |
|
|
86
|
+
.company_state.state = "running" |
|
|
87
|
+
.conductor.state = "running" |
|
|
88
|
+
.conductor.current_action = ("owner-" + $command + "-to-ceo") |
|
|
89
|
+
.conductor.stop_chain_count = 0 |
|
|
86
90
|
.updated_at = $now |
|
|
87
91
|
.owner_prompt = {
|
|
88
92
|
command: $command,
|