@walwal-harness/cli 7.1.34 → 7.1.37
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 +19 -0
- package/HR-Resource/ceo/SKILL.md +15 -4
- package/HR-Resource/ops/SKILL.md +3 -3
- package/README.md +7 -2
- package/apps/harness-dashboard/components/Scene.tsx +48 -17
- package/apps/harness-dashboard/lib/__tests__/harness-state.test.ts +36 -3
- package/apps/harness-dashboard/lib/harness-state.ts +44 -20
- package/apps/harness-dashboard/package-lock.json +42 -43
- package/assets/templates/AGENTS-ko.md.template +4 -0
- package/assets/templates/AGENTS.md.template +7 -3
- package/assets/templates/config.json +1 -1
- package/assets/templates/gitignore-append.txt +6 -1
- package/assets/templates/memory.md +1 -1
- package/bin/init.js +49 -4
- package/commands/goal.md +2 -1
- package/commands/hot-fix.md +2 -1
- package/commands/submission.md +3 -2
- package/conventions/ceo.md +2 -0
- package/gotchas/ceo.md +4 -0
- package/package.json +1 -1
- package/scripts/harness-activity-record.js +6 -1
- package/scripts/harness-dashboard-up.sh +36 -8
- package/scripts/harness-hourly-review.sh +1 -1
- package/scripts/harness-service-ops-monitor.sh +2 -2
- package/scripts/harness-stop.sh +18 -17
- package/scripts/harness-user-prompt-submit.sh +2 -0
- package/scripts/harness-wake-install.sh +68 -15
- package/scripts/harness-worker-evidence-validate.sh +35 -0
|
@@ -985,15 +985,15 @@
|
|
|
985
985
|
}
|
|
986
986
|
},
|
|
987
987
|
"node_modules/@next/env": {
|
|
988
|
-
"version": "15.5.
|
|
989
|
-
"resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.
|
|
990
|
-
"integrity": "sha512-
|
|
988
|
+
"version": "15.5.18",
|
|
989
|
+
"resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.18.tgz",
|
|
990
|
+
"integrity": "sha512-hAV85Ckd9QR6RvH04MEKwsfLTksvFpO47j9xwtoIuvuPnlwecpSi+uZTtm8HirVbtlI2Fnz//xpcSTjFdyJk+g==",
|
|
991
991
|
"license": "MIT"
|
|
992
992
|
},
|
|
993
993
|
"node_modules/@next/swc-darwin-arm64": {
|
|
994
|
-
"version": "15.5.
|
|
995
|
-
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.
|
|
996
|
-
"integrity": "sha512-
|
|
994
|
+
"version": "15.5.18",
|
|
995
|
+
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.18.tgz",
|
|
996
|
+
"integrity": "sha512-w0WvQf1n+txiwns/9pwIQteCJpZTbxzO2SE0FLcwuD4v0WEh1JPOjdyxWL21XwJsdpx8cFRjyzxzCS/siP7HcQ==",
|
|
997
997
|
"cpu": [
|
|
998
998
|
"arm64"
|
|
999
999
|
],
|
|
@@ -1007,9 +1007,9 @@
|
|
|
1007
1007
|
}
|
|
1008
1008
|
},
|
|
1009
1009
|
"node_modules/@next/swc-darwin-x64": {
|
|
1010
|
-
"version": "15.5.
|
|
1011
|
-
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.
|
|
1012
|
-
"integrity": "sha512-
|
|
1010
|
+
"version": "15.5.18",
|
|
1011
|
+
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.18.tgz",
|
|
1012
|
+
"integrity": "sha512-znn71QmDuxm+BOaglihMZfvyySMnNljkVIY5Z2TCssBmm+WqL6c19VhtH5ktFkHa8EZ2bnTUpcNcmNSQsg67og==",
|
|
1013
1013
|
"cpu": [
|
|
1014
1014
|
"x64"
|
|
1015
1015
|
],
|
|
@@ -1023,9 +1023,9 @@
|
|
|
1023
1023
|
}
|
|
1024
1024
|
},
|
|
1025
1025
|
"node_modules/@next/swc-linux-arm64-gnu": {
|
|
1026
|
-
"version": "15.5.
|
|
1027
|
-
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.
|
|
1028
|
-
"integrity": "sha512-
|
|
1026
|
+
"version": "15.5.18",
|
|
1027
|
+
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.18.tgz",
|
|
1028
|
+
"integrity": "sha512-yPPe5MNL+igZUa+OsqQJisqSfh6oarIuA1Q0BDxljGJhRQyZeP+WRHh7rs/jZUGMh5aY0YdIjXZG0VohkKkUdw==",
|
|
1029
1029
|
"cpu": [
|
|
1030
1030
|
"arm64"
|
|
1031
1031
|
],
|
|
@@ -1039,9 +1039,9 @@
|
|
|
1039
1039
|
}
|
|
1040
1040
|
},
|
|
1041
1041
|
"node_modules/@next/swc-linux-arm64-musl": {
|
|
1042
|
-
"version": "15.5.
|
|
1043
|
-
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.
|
|
1044
|
-
"integrity": "sha512-
|
|
1042
|
+
"version": "15.5.18",
|
|
1043
|
+
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.18.tgz",
|
|
1044
|
+
"integrity": "sha512-glaCczEWIrHsokFZ3pP08U4BpKxwIdnT+txdOM32OBgpL9Yw4aqx8NejmgtZQZOdstQ5f0L3CasIZudzCuD+nw==",
|
|
1045
1045
|
"cpu": [
|
|
1046
1046
|
"arm64"
|
|
1047
1047
|
],
|
|
@@ -1055,9 +1055,9 @@
|
|
|
1055
1055
|
}
|
|
1056
1056
|
},
|
|
1057
1057
|
"node_modules/@next/swc-linux-x64-gnu": {
|
|
1058
|
-
"version": "15.5.
|
|
1059
|
-
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.
|
|
1060
|
-
"integrity": "sha512-
|
|
1058
|
+
"version": "15.5.18",
|
|
1059
|
+
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.18.tgz",
|
|
1060
|
+
"integrity": "sha512-oUfg2EgJmU3R0OCOWiokGFUTvZiPfXtriXiuF3YNxRoROCdgvTedHIzYoeKH34gsZxS/V7mHbfq2hpAHwhH1/A==",
|
|
1061
1061
|
"cpu": [
|
|
1062
1062
|
"x64"
|
|
1063
1063
|
],
|
|
@@ -1071,9 +1071,9 @@
|
|
|
1071
1071
|
}
|
|
1072
1072
|
},
|
|
1073
1073
|
"node_modules/@next/swc-linux-x64-musl": {
|
|
1074
|
-
"version": "15.5.
|
|
1075
|
-
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.
|
|
1076
|
-
"integrity": "sha512-
|
|
1074
|
+
"version": "15.5.18",
|
|
1075
|
+
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.18.tgz",
|
|
1076
|
+
"integrity": "sha512-JLxSP3KTd9iu/bvUMQxH7RJo9xKSHf55/6RPE4a6FTSZygGn7uvZbCej0AHXydwkggQGSD9UddSjwv6Xz5ESfA==",
|
|
1077
1077
|
"cpu": [
|
|
1078
1078
|
"x64"
|
|
1079
1079
|
],
|
|
@@ -1087,9 +1087,9 @@
|
|
|
1087
1087
|
}
|
|
1088
1088
|
},
|
|
1089
1089
|
"node_modules/@next/swc-win32-arm64-msvc": {
|
|
1090
|
-
"version": "15.5.
|
|
1091
|
-
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.
|
|
1092
|
-
"integrity": "sha512-
|
|
1090
|
+
"version": "15.5.18",
|
|
1091
|
+
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.18.tgz",
|
|
1092
|
+
"integrity": "sha512-ir1v7enP52K2HNz3tQQvwF+x7VNxBk1ciiZ18WBPvxf4C59IqdfmHPJYK3vH7rSxpuCVw/8C712wTXNAtEp+NA==",
|
|
1093
1093
|
"cpu": [
|
|
1094
1094
|
"arm64"
|
|
1095
1095
|
],
|
|
@@ -1103,9 +1103,9 @@
|
|
|
1103
1103
|
}
|
|
1104
1104
|
},
|
|
1105
1105
|
"node_modules/@next/swc-win32-x64-msvc": {
|
|
1106
|
-
"version": "15.5.
|
|
1107
|
-
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.
|
|
1108
|
-
"integrity": "sha512-
|
|
1106
|
+
"version": "15.5.18",
|
|
1107
|
+
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.18.tgz",
|
|
1108
|
+
"integrity": "sha512-LIu5me6QTANCd25E7I5uIEfvgQ06RK7tvHAbYo3zCb3VpxQEPvMcSpd87NwUABDT6MbGPdEGR5VRiK4PPTJhQg==",
|
|
1109
1109
|
"cpu": [
|
|
1110
1110
|
"x64"
|
|
1111
1111
|
],
|
|
@@ -1687,9 +1687,9 @@
|
|
|
1687
1687
|
"license": "MIT"
|
|
1688
1688
|
},
|
|
1689
1689
|
"node_modules/@types/node": {
|
|
1690
|
-
"version": "22.19.
|
|
1691
|
-
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.
|
|
1692
|
-
"integrity": "sha512-
|
|
1690
|
+
"version": "22.19.18",
|
|
1691
|
+
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.18.tgz",
|
|
1692
|
+
"integrity": "sha512-9v00a+dn2yWVsYDEunWC4g/TcRKVq3r8N5FuZp7u0SGrPvdN9c2yXI9bBuf5Fl0hNCb+QTIePTn5pJs2pwBOQQ==",
|
|
1693
1693
|
"dev": true,
|
|
1694
1694
|
"license": "MIT",
|
|
1695
1695
|
"dependencies": {
|
|
@@ -2660,7 +2660,6 @@
|
|
|
2660
2660
|
"version": "2.3.2",
|
|
2661
2661
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
|
2662
2662
|
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
|
2663
|
-
"dev": true,
|
|
2664
2663
|
"hasInstallScript": true,
|
|
2665
2664
|
"license": "MIT",
|
|
2666
2665
|
"optional": true,
|
|
@@ -3948,12 +3947,12 @@
|
|
|
3948
3947
|
}
|
|
3949
3948
|
},
|
|
3950
3949
|
"node_modules/next": {
|
|
3951
|
-
"version": "15.5.
|
|
3952
|
-
"resolved": "https://registry.npmjs.org/next/-/next-15.5.
|
|
3953
|
-
"integrity": "sha512-
|
|
3950
|
+
"version": "15.5.18",
|
|
3951
|
+
"resolved": "https://registry.npmjs.org/next/-/next-15.5.18.tgz",
|
|
3952
|
+
"integrity": "sha512-eKL8zUJkX9Y5lE+RX/2YJoItVdGlIscyVyboeD9wSpp0PaGqjoA4tTpT2qPqz9ax+5IzGESyLSeZ/RCwbSZ2uQ==",
|
|
3954
3953
|
"license": "MIT",
|
|
3955
3954
|
"dependencies": {
|
|
3956
|
-
"@next/env": "15.5.
|
|
3955
|
+
"@next/env": "15.5.18",
|
|
3957
3956
|
"@swc/helpers": "0.5.15",
|
|
3958
3957
|
"caniuse-lite": "^1.0.30001579",
|
|
3959
3958
|
"postcss": "8.4.31",
|
|
@@ -3966,14 +3965,14 @@
|
|
|
3966
3965
|
"node": "^18.18.0 || ^19.8.0 || >= 20.0.0"
|
|
3967
3966
|
},
|
|
3968
3967
|
"optionalDependencies": {
|
|
3969
|
-
"@next/swc-darwin-arm64": "15.5.
|
|
3970
|
-
"@next/swc-darwin-x64": "15.5.
|
|
3971
|
-
"@next/swc-linux-arm64-gnu": "15.5.
|
|
3972
|
-
"@next/swc-linux-arm64-musl": "15.5.
|
|
3973
|
-
"@next/swc-linux-x64-gnu": "15.5.
|
|
3974
|
-
"@next/swc-linux-x64-musl": "15.5.
|
|
3975
|
-
"@next/swc-win32-arm64-msvc": "15.5.
|
|
3976
|
-
"@next/swc-win32-x64-msvc": "15.5.
|
|
3968
|
+
"@next/swc-darwin-arm64": "15.5.18",
|
|
3969
|
+
"@next/swc-darwin-x64": "15.5.18",
|
|
3970
|
+
"@next/swc-linux-arm64-gnu": "15.5.18",
|
|
3971
|
+
"@next/swc-linux-arm64-musl": "15.5.18",
|
|
3972
|
+
"@next/swc-linux-x64-gnu": "15.5.18",
|
|
3973
|
+
"@next/swc-linux-x64-musl": "15.5.18",
|
|
3974
|
+
"@next/swc-win32-arm64-msvc": "15.5.18",
|
|
3975
|
+
"@next/swc-win32-x64-msvc": "15.5.18",
|
|
3977
3976
|
"sharp": "^0.34.3"
|
|
3978
3977
|
},
|
|
3979
3978
|
"peerDependencies": {
|
|
@@ -110,6 +110,10 @@ CEO는 worker 기록 없이 완료된 산출물을 포함한 CXX 보고서를
|
|
|
110
110
|
|
|
111
111
|
Owner는 최종 검수자다. Tester, QA worker, debugger, 배포 확인 담당자가 아니다.
|
|
112
112
|
|
|
113
|
+
- Owner는 방향 제시, 추가 요구, hot-fix, 최종 acceptance feedback을 제공한다. 회사 루프를 계속 돌리기 위한 진행 신호가 아니다.
|
|
114
|
+
- CEO는 Owner에게 계속 진행 여부, worker 고용 여부, 내부 옵션 선택, 다음 단계 시작 여부를 묻지 않는다.
|
|
115
|
+
- CEO가 혼자 판단하기 어려우면 관련 CXX 회의를 열고 written recommendation을 받아 결정한 뒤 계속 진행한다.
|
|
116
|
+
- Owner 입력 대기는 harness가 추론하거나 확보할 수 없는 외부 권한이 필요할 때만 허용한다: credentials/secrets, payment approval, legal/business acceptance, unavailable production access, destructive data action, 또는 명시된 Owner 방향과의 직접 충돌.
|
|
113
117
|
- 동작하지 않거나 검증되지 않았거나 부분적으로만 실행되는 소프트웨어를 Owner에게 전달하며 "확인해 주세요"를 다음 액션으로 삼지 않는다.
|
|
114
118
|
- Owner에게 개발자 테스트, 회귀 확인, 계정 생성/로그인 확인, Playwright 확인, E2E 순회, 로그 점검, 기본 기능 검증을 요구하지 않는다.
|
|
115
119
|
- CEO와 CXX는 worker를 통해 자체 검증을 계획하고 실행한다: unit test, E2E test, Playwright/browser check, test account, seed data, build/run check, log evidence.
|
|
@@ -35,10 +35,11 @@ Codex does not need `.codex/agents/` to run this harness. The installed Codex co
|
|
|
35
35
|
|
|
36
36
|
Don't assume. Don't hide confusion.
|
|
37
37
|
|
|
38
|
-
- State assumptions before implementing.
|
|
39
|
-
- If multiple approaches exist, name them
|
|
38
|
+
- State assumptions before implementing.
|
|
39
|
+
- If multiple approaches exist, name them and choose the smallest reversible path from evidence.
|
|
40
40
|
- Minimum change that solves the problem. No speculative scope.
|
|
41
|
-
-
|
|
41
|
+
- Do not ask the Owner routine operating questions. CEO/CXX resolve uncertainty internally through written CXX recommendations.
|
|
42
|
+
- Stop for Owner input only when the next action requires external authority the harness cannot infer: credentials/secrets, payment approval, legal/business acceptance, unavailable production access, destructive data action, or a direct conflict with stated Owner direction. Record the recommended default when blocked.
|
|
42
43
|
|
|
43
44
|
For hot-fix: smallest correct patch only. Do not "improve" adjacent code.
|
|
44
45
|
For goal: define verifiable success criteria before CEO routes to CXX.
|
|
@@ -70,6 +71,9 @@ CEO rejects any CXX report that contains completed deliverables without matching
|
|
|
70
71
|
|
|
71
72
|
The Owner is the final acceptance reviewer, not a tester, QA worker, debugger, or deployment verifier.
|
|
72
73
|
|
|
74
|
+
- The Owner sets direction, adds requirements, issues hot-fixes, and gives final acceptance feedback. The Owner is not the progress pump for the company loop.
|
|
75
|
+
- CEO must not ask the Owner whether to continue, which worker to hire, which internal option to choose, or whether to start the next planned step.
|
|
76
|
+
- If CEO cannot answer an operating question alone, CEO convenes the relevant CXX agents, records their recommendations, chooses a path, and continues.
|
|
73
77
|
- Do not hand the Owner broken, unverified, or partially runnable software with "please check this" as the next action.
|
|
74
78
|
- Do not ask the Owner to perform developer testing, regression checks, account setup checks, Playwright review, E2E traversal, log inspection, or basic functionality verification.
|
|
75
79
|
- CEO and CXX must plan and execute self-verification through workers: unit tests, E2E tests, Playwright/browser checks, test accounts, seeded data, build/run checks, logs, and documented evidence.
|
|
@@ -240,7 +240,7 @@
|
|
|
240
240
|
"command": ""
|
|
241
241
|
},
|
|
242
242
|
"production": {
|
|
243
|
-
"comment": "
|
|
243
|
+
"comment": "CEO+CTO+OPS가 repo config, scripts, running process, Docker, logs, CXX report에서 services[]와 운영 서버 매핑을 우선 도출한다. Owner 입력 대기는 credentials/secrets, unavailable production access, legal/business acceptance 같은 외부 권한이 필요할 때만 허용한다. live=true 이고 services[] 가 있으면 OPS 는 매 hourly review 마다 port/health/log 상태를 운영보고서에 남긴다.",
|
|
244
244
|
"live": false,
|
|
245
245
|
"services": [
|
|
246
246
|
{
|
|
@@ -1 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# walwal-harness dashboard runtime
|
|
2
|
+
.harness/dashboard/apps/harness-dashboard/node_modules/
|
|
3
|
+
.harness/dashboard/apps/harness-dashboard/.next/
|
|
4
|
+
.harness/dashboard/apps/harness-dashboard/.turbo/
|
|
5
|
+
.harness/dashboard/apps/harness-dashboard/tsconfig.tsbuildinfo
|
|
6
|
+
.harness/dashboard/.download/
|
|
@@ -73,7 +73,7 @@ docmeta:
|
|
|
73
73
|
- **TTL**: 영구
|
|
74
74
|
- **Lesson**: walwal-harness 는 NEXUS 회사 메타포다. 다음 두 룰을 **절대로** 어기지 않는다.
|
|
75
75
|
1. **정체성**: 사용자 = **Owner** (회사 외부 주주), Dispatcher = **CEO** (Owner 와의 유일한 대화 창구). 응답·GOAL·로그 어디서도 사용자를 "CEO" 로 호칭하지 않는다. 회사 내부 결정 (sprint 분할, mode 선택, agent 호출, 평가 점수) 을 Owner 에게 떠넘기지 않는다.
|
|
76
|
-
2. **자율 실행 (NEXUS P3)**: GOAL 확정 직후 회사는 **사용자 펌프 없이** 자율 진행. "다음 단계로 진행할까요?", "/harness-next 실행하시겠습니까?" 같은 진행 여부 질문은 자율성 위반. Owner 가 돌아오는 시점은 (a)
|
|
76
|
+
2. **자율 실행 (NEXUS P3)**: GOAL 확정 직후 회사는 **사용자 펌프 없이** 자율 진행. "다음 단계로 진행할까요?", "/harness-next 실행하시겠습니까?" 같은 진행 여부 질문은 자율성 위반. CEO가 혼자 결정하기 어려우면 Owner에게 묻지 말고 관련 CXX 회의를 열어 written recommendation을 받은 뒤 결정한다. Owner 가 돌아오는 시점은 (a) 목표 변경/추가 요구/hot-fix, (b) 결과 보고와 최종 acceptance feedback, (c) credentials/secrets, payment approval, legal/business acceptance, unavailable production access, destructive data action, stated direction conflict 같은 외부 권한 block 뿐.
|
|
77
77
|
- **Context**: v6.0.0 publish 직후 dispatcher 응답이 사용자를 "CEO 직접 리뷰…" 로 호명하고 "/harness-next 자동 진행하시겠습니까?" 로 사용자 펌프를 요구함. Owner 의 명시적 교정.
|
|
78
78
|
- **Applies to**:
|
|
79
79
|
- **Dispatcher**: 사용자 호칭/응답 문구, GOAL 정립, 모든 inbound/outbound owner 통신. → anti-pattern: `.harness/gotchas/dispatcher.md` [G-001]~[G-004].
|
package/bin/init.js
CHANGED
|
@@ -530,7 +530,29 @@ function ensureMissionLifecycleStates(opts = {}) {
|
|
|
530
530
|
|
|
531
531
|
for (const mission of group) {
|
|
532
532
|
const statePath = path.join(mission.abs, 'mission-state.json');
|
|
533
|
-
if (fs.existsSync(statePath))
|
|
533
|
+
if (fs.existsSync(statePath)) {
|
|
534
|
+
const state = readJsonFileSafe(statePath) || {};
|
|
535
|
+
const lifecycle = state.lifecycle || state.status;
|
|
536
|
+
const active = state.active === true;
|
|
537
|
+
const shouldDeactivate =
|
|
538
|
+
active &&
|
|
539
|
+
(isTerminalMissionLifecycle(lifecycle) ||
|
|
540
|
+
(mission.rel.includes('/') &&
|
|
541
|
+
(mission.type === 'submission' || mission.type === 'hotfix') &&
|
|
542
|
+
activeChild &&
|
|
543
|
+
activeChild.rel !== mission.rel));
|
|
544
|
+
if (shouldDeactivate) {
|
|
545
|
+
writes.push({
|
|
546
|
+
path: statePath,
|
|
547
|
+
state: {
|
|
548
|
+
...state,
|
|
549
|
+
lifecycle: isTerminalMissionLifecycle(lifecycle) ? lifecycle : 'superseded',
|
|
550
|
+
active: false,
|
|
551
|
+
},
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
continue;
|
|
555
|
+
}
|
|
534
556
|
const isChild = mission.rel.includes('/');
|
|
535
557
|
const isActive = isChild
|
|
536
558
|
? activeChild?.rel === mission.rel
|
|
@@ -555,7 +577,7 @@ function ensureMissionLifecycleStates(opts = {}) {
|
|
|
555
577
|
fs.writeFileSync(item.path, JSON.stringify(item.state, null, 2) + '\n');
|
|
556
578
|
}
|
|
557
579
|
if (writes.length) {
|
|
558
|
-
log(`mission-state.json: ${writes.length}개 기존 mission
|
|
580
|
+
log(`mission-state.json: ${writes.length}개 기존 mission lifecycle/active 보강`);
|
|
559
581
|
}
|
|
560
582
|
return { missing: writes.length, written: writes.length };
|
|
561
583
|
}
|
|
@@ -826,9 +848,9 @@ function ensureHarnessEnv() {
|
|
|
826
848
|
if (re.test(content)) return;
|
|
827
849
|
|
|
828
850
|
const prefix = content && !content.endsWith('\n') ? '\n' : '';
|
|
829
|
-
const block = `${prefix}${content ? '\n' : ''}# Walwal Harness — CEO
|
|
851
|
+
const block = `${prefix}${content ? '\n' : ''}# Walwal Harness — CEO chooses an available {xx}000 base port unless Owner already specified one.\n# Set HARNESS_BASE_PORT before CXX agents allocate any service ports.\n# HARNESS_BASE_PORT=\n`;
|
|
830
852
|
fs.writeFileSync(envPath, content + block);
|
|
831
|
-
log('.env: HARNESS_BASE_PORT placeholder added —
|
|
853
|
+
log('.env: HARNESS_BASE_PORT placeholder added — CEO/CXX must choose an available value before starting services');
|
|
832
854
|
}
|
|
833
855
|
|
|
834
856
|
function ensureStructuredRuntimeFiles({ dryRun = false } = {}) {
|
|
@@ -941,6 +963,27 @@ function refreshScriptsForMigrate({ dryRun = false, backupDir = null } = {}) {
|
|
|
941
963
|
chmodShellScripts(scriptsDest);
|
|
942
964
|
}
|
|
943
965
|
|
|
966
|
+
function ensureWakeScheduler({ dryRun = false } = {}) {
|
|
967
|
+
const wakeInstall = path.join(PROJECT_ROOT, 'scripts', 'harness-wake-install.sh');
|
|
968
|
+
if (!fs.existsSync(wakeInstall)) return;
|
|
969
|
+
|
|
970
|
+
log(' wake scheduler: project registration + launchd load check');
|
|
971
|
+
if (dryRun) return;
|
|
972
|
+
|
|
973
|
+
try {
|
|
974
|
+
execSync(`bash ${shellQuote(wakeInstall)} install ${shellQuote(PROJECT_ROOT)}`, {
|
|
975
|
+
cwd: PROJECT_ROOT,
|
|
976
|
+
stdio: 'pipe',
|
|
977
|
+
timeout: 15000,
|
|
978
|
+
});
|
|
979
|
+
log(' wake scheduler: registered');
|
|
980
|
+
} catch (e) {
|
|
981
|
+
const detail = String(e?.stderr || e?.message || '').trim().split('\n').slice(-1)[0];
|
|
982
|
+
log(` wake scheduler: registration skipped (${detail || 'install command failed'})`);
|
|
983
|
+
log(' wake scheduler: run manually if needed: bash scripts/harness-wake-install.sh install .');
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
944
987
|
function migrateActivityHistory({ dryRun = false } = {}) {
|
|
945
988
|
const recorder = path.join(PROJECT_ROOT, 'scripts', 'harness-activity-record.js');
|
|
946
989
|
if (!fs.existsSync(recorder)) return;
|
|
@@ -2010,6 +2053,7 @@ function runMigrate(opts = {}) {
|
|
|
2010
2053
|
// Runtime scripts are package-owned. Migrate must refresh them so existing
|
|
2011
2054
|
// projects receive wake/meeting/OPS fixes without requiring a full init.
|
|
2012
2055
|
refreshScriptsForMigrate({ dryRun, backupDir });
|
|
2056
|
+
ensureWakeScheduler({ dryRun });
|
|
2013
2057
|
migrateActivityHistory({ dryRun });
|
|
2014
2058
|
updateRuleRegistryLinks(flags.ruleRegistryLinks || [], { dryRun, backupDir });
|
|
2015
2059
|
|
|
@@ -2578,6 +2622,7 @@ function main() {
|
|
|
2578
2622
|
scaffoldHarness();
|
|
2579
2623
|
installSkills();
|
|
2580
2624
|
installScripts();
|
|
2625
|
+
ensureWakeScheduler();
|
|
2581
2626
|
installCommands();
|
|
2582
2627
|
installSessionHook();
|
|
2583
2628
|
installStatusline();
|
package/commands/goal.md
CHANGED
|
@@ -16,7 +16,7 @@ Required flow:
|
|
|
16
16
|
1. Create or update a goal under `.harness/documents/goal-{goal_index}-{goal_name}/`.
|
|
17
17
|
2. Write `.harness/documents/goal-{goal_index}-{goal_name}/mission-state.json` with `{"lifecycle":"active","active":true}` before routing CXX.
|
|
18
18
|
3. Record CEO decisions in `.harness/documents/goal-{goal_index}-{goal_name}/ceo.md`.
|
|
19
|
-
4. CEO decides whether brainstorming is needed or whether CXX questions can be issued immediately.
|
|
19
|
+
4. CEO decides whether brainstorming is needed or whether CXX questions can be issued immediately. CEO must not ask the Owner which path to take.
|
|
20
20
|
5. CEO asks COO, CDO, CTO, and CQO only the questions needed for this goal.
|
|
21
21
|
6. CXX roles must start in a fresh session context. Do not let the default model impersonate a missing worker.
|
|
22
22
|
7. CXX roles must not directly execute specialist deliverables. They must use hired workers for research, planning, design, implementation, QA, ops checks, and documentation.
|
|
@@ -24,6 +24,7 @@ Required flow:
|
|
|
24
24
|
9. CEO must require a Worker Evidence Manifest and worker report paths under `.harness/documents/goal-{goal_index}-{goal_name}/{owning-cxx}/workers/` before accepting CXX completion.
|
|
25
25
|
10. When the goal is accepted, cancelled, superseded, blocked, or closed, update `mission-state.json` to `complete`, `cancelled`, `superseded`, `blocked`, or `closed` and set `active:false`.
|
|
26
26
|
11. Do not invoke internal roles through slash commands; commands are Owner entrypoints only.
|
|
27
|
+
12. Do not ask the Owner whether to continue, hire workers, choose internal options, or start the next step. If CEO cannot decide alone, convene the relevant CXX agents and decide from their written recommendations. Stop only for external authority such as credentials/secrets, payment approval, legal/business acceptance, unavailable production access, destructive data action, or direct conflict with stated Owner direction.
|
|
27
28
|
|
|
28
29
|
Note: A goal is the company's objective. Submissions and hot-fixes that happen while pursuing it should be recorded under that goal directory.
|
|
29
30
|
|
package/commands/hot-fix.md
CHANGED
|
@@ -17,7 +17,7 @@ Required flow:
|
|
|
17
17
|
2. If another child mission under the goal is active, update its `mission-state.json` to `closed`, `cancelled`, or `superseded` with `active:false` before starting the hot-fix.
|
|
18
18
|
3. Create `.harness/documents/{goal_name}/hotfix-{hotfix_index}-{hotfix_name}/ceo.md`.
|
|
19
19
|
4. Write `.harness/documents/{goal_name}/hotfix-{hotfix_index}-{hotfix_name}/mission-state.json` with `{"lifecycle":"active","active":true}`.
|
|
20
|
-
5. CEO summons CTO and CQO first; summon COO/CDO only when planning or UX decisions are involved.
|
|
20
|
+
5. CEO summons CTO and CQO first; summon COO/CDO only when planning or UX decisions are involved. CEO must not ask the Owner whether to start the fix or which internal path to choose.
|
|
21
21
|
6. CTO applies the smallest correct patch path through hired implementation skills.
|
|
22
22
|
7. CXX roles must start in a fresh session context. Do not let the default model impersonate a missing CXX or worker.
|
|
23
23
|
8. CXX roles must not directly execute specialist deliverables. They must use hired workers for implementation, QA, ops checks, and documentation even when the fix is small.
|
|
@@ -26,6 +26,7 @@ Required flow:
|
|
|
26
26
|
11. CQO must register durable lessons in `.harness/gotchas/`, `.harness/conventions/`, or `.harness/memories/`. This step is mandatory, not optional, even for small fixes.
|
|
27
27
|
12. Archive only after CQO has accepted the fix, then update `mission-state.json` to `complete` with `active:false`.
|
|
28
28
|
13. Do not invoke internal roles through slash commands; commands are Owner entrypoints only.
|
|
29
|
+
14. Do not ask the Owner whether to continue, hire workers, choose internal options, or start the next step. If CEO cannot decide alone, convene the relevant CXX agents and decide from their written recommendations. Stop only for external authority such as credentials/secrets, payment approval, legal/business acceptance, unavailable production access, destructive data action, or direct conflict with stated Owner direction.
|
|
29
30
|
|
|
30
31
|
Note: `/hot-fix` is a problem-fix flow while pursuing the active goal. It belongs under that goal in history.
|
|
31
32
|
|
package/commands/submission.md
CHANGED
|
@@ -13,12 +13,12 @@ Codex adapter:
|
|
|
13
13
|
- For CXX "fresh session context", use role-scoped context: read the CXX skill, active mission files, and required conventions/gotchas before writing that role's `{cxx}.md`.
|
|
14
14
|
|
|
15
15
|
Required flow:
|
|
16
|
-
1. Locate the active goal document root under `.harness/documents/{goal_name}/`. If no active goal exists, CEO must
|
|
16
|
+
1. Locate the active goal document root under `.harness/documents/{goal_name}/`. If no active goal exists, CEO must create/select the best matching goal record from available mission context or mark the submission blocked with the recommended default; do not ask the Owner an open-ended setup question.
|
|
17
17
|
2. If another child mission under the goal is active, update its `mission-state.json` to `closed`, `cancelled`, or `superseded` with `active:false` before starting this submission.
|
|
18
18
|
3. Create a submission record under `.harness/documents/{goal_name}/submission-{submission_index}-{submission_name}/`.
|
|
19
19
|
4. Write `.harness/documents/{goal_name}/submission-{submission_index}-{submission_name}/mission-state.json` with `{"lifecycle":"active","active":true}`.
|
|
20
20
|
5. Record CEO decisions in `.harness/documents/{goal_name}/submission-{submission_index}-{submission_name}/ceo.md`.
|
|
21
|
-
6. CEO routes only to the CXX agents needed for this additional requirement.
|
|
21
|
+
6. CEO routes only to the CXX agents needed for this additional requirement. CEO must not ask the Owner which CXX or worker path to choose.
|
|
22
22
|
7. CXX roles must start in a fresh session context. Do not let the default model impersonate a missing CXX or worker.
|
|
23
23
|
8. CXX roles must not directly execute specialist deliverables. They must use hired workers for research, planning, design, implementation, QA, ops checks, and documentation.
|
|
24
24
|
9. If a required worker is missing, the responsible CXX must invoke the installed `harness-hiring` skill before assigning the work.
|
|
@@ -26,6 +26,7 @@ Required flow:
|
|
|
26
26
|
11. CEO must require a Worker Evidence Manifest and worker report paths under `.harness/documents/{goal_name}/submission-{submission_index}-{submission_name}/{owning-cxx}/workers/` before accepting CXX completion.
|
|
27
27
|
12. When the submission is accepted, cancelled, superseded, blocked, or closed, update `mission-state.json` to `complete`, `cancelled`, `superseded`, `blocked`, or `closed` and set `active:false`.
|
|
28
28
|
13. Do not invoke internal roles through slash commands; commands are Owner entrypoints only.
|
|
29
|
+
14. Do not ask the Owner whether to continue, hire workers, choose internal options, or start the next step. If CEO cannot decide alone, convene the relevant CXX agents and decide from their written recommendations. Stop only for external authority such as credentials/secrets, payment approval, legal/business acceptance, unavailable production access, destructive data action, or direct conflict with stated Owner direction.
|
|
29
30
|
|
|
30
31
|
Note: `/submission` is not a new company goal and not an emergency fix. It is an additional requirement while pursuing the active goal. It belongs under that goal in history.
|
|
31
32
|
|
package/conventions/ceo.md
CHANGED
|
@@ -5,5 +5,7 @@
|
|
|
5
5
|
- CEO routes work to CXX agents through agent/skill invocation, not slash commands.
|
|
6
6
|
- CEO records mission framing and routing decisions in `.harness/documents/{goal-or-child-mission}/ceo.md`.
|
|
7
7
|
- CEO asks only mission-relevant questions to COO, CDO, CTO, CQO, and OPS.
|
|
8
|
+
- CEO does not ask the Owner routine operating questions. CEO decides from evidence, or convenes CXX agents and then decides.
|
|
9
|
+
- CEO stops for Owner input only for external authority: credentials/secrets, payment approval, legal/business acceptance, unavailable production access, destructive data action, or direct conflict with stated Owner direction.
|
|
8
10
|
- CEO does not accept CXX completion unless specialist deliverables were produced by hired workers.
|
|
9
11
|
- CEO requires worker names and `.harness/documents/{goal-or-child-mission}/{owning-cxx}/workers/{worker-name}.md` paths in CXX completion reports.
|
package/gotchas/ceo.md
CHANGED
|
@@ -7,3 +7,7 @@ CEO must not call `/coo`, `/cto`, or similar slash commands. CXX routing is agen
|
|
|
7
7
|
## Over-broad Meeting
|
|
8
8
|
|
|
9
9
|
Do not summon every CXX for every mission by default. Ask only the roles needed for the decision.
|
|
10
|
+
|
|
11
|
+
## Owner As Progress Pump
|
|
12
|
+
|
|
13
|
+
Do not ask the Owner whether to continue, start the next step, hire a worker, choose between internal options, or verify routine technical behavior. Decide internally, record the rationale, and keep routing. If a decision is too ambiguous for CEO alone, convene the relevant CXX agents and decide from their recommendations.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walwal-harness/cli",
|
|
3
|
-
"version": "7.1.
|
|
3
|
+
"version": "7.1.37",
|
|
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"
|
|
@@ -130,7 +130,12 @@ function runtimeIdle(root) {
|
|
|
130
130
|
|
|
131
131
|
function currentSamples(root, now = Date.now()) {
|
|
132
132
|
const missions = collectMissions(root);
|
|
133
|
-
const active =
|
|
133
|
+
const active =
|
|
134
|
+
missions
|
|
135
|
+
.filter((m) => m.active)
|
|
136
|
+
.sort((a, b) => b.mtimeMs - a.mtimeMs)[0] ??
|
|
137
|
+
missions.sort((a, b) => b.mtimeMs - a.mtimeMs)[0] ??
|
|
138
|
+
null;
|
|
134
139
|
if (!active) return [];
|
|
135
140
|
const todos = readTodos(root);
|
|
136
141
|
const idle = runtimeIdle(root);
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
# walwal-harness — Brick Office dashboard launcher
|
|
3
3
|
#
|
|
4
4
|
# 처음 쓰는 사용자도 한 줄로 대시보드를 띄워볼 수 있게 만든 helper.
|
|
5
|
-
# npm 패키지에 포함된 apps/harness-dashboard 를
|
|
6
|
-
# (
|
|
5
|
+
# npm 패키지에 포함된 apps/harness-dashboard 를 프로젝트별 runtime 영역
|
|
6
|
+
# (.harness/dashboard/) 에 복사 후 dev 실행한다.
|
|
7
7
|
# 구버전 호환을 위해 패키지에 dashboard 가 없으면 git sparse-checkout 으로 fallback 한다.
|
|
8
8
|
#
|
|
9
9
|
# Usage:
|
|
@@ -38,9 +38,7 @@ if [[ ! -d "${HARNESS_ROOT}/.harness" ]]; then
|
|
|
38
38
|
exit 3
|
|
39
39
|
fi
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
PROJECT_NAME="$(basename "${HARNESS_ROOT}")"
|
|
43
|
-
LOCAL_DIR="${HOME}/.walwal-harness/dashboard/${PROJECT_NAME}-${PROJECT_KEY}"
|
|
41
|
+
LOCAL_DIR="${HARNESS_ROOT}/.harness/dashboard"
|
|
44
42
|
VERSION_FILE="${LOCAL_DIR}/.walwal-dashboard-version"
|
|
45
43
|
|
|
46
44
|
PACKAGE_ROOT="${HARNESS_ROOT}/node_modules/@walwal-harness/cli"
|
|
@@ -53,8 +51,33 @@ if [[ "$REINSTALL" == "true" ]]; then
|
|
|
53
51
|
rm -rf "$LOCAL_DIR"
|
|
54
52
|
fi
|
|
55
53
|
|
|
54
|
+
ensure_gitignore() {
|
|
55
|
+
local gitignore="${HARNESS_ROOT}/.gitignore"
|
|
56
|
+
local marker="# walwal-harness dashboard runtime"
|
|
57
|
+
local block
|
|
58
|
+
block="$(cat <<'EOF'
|
|
59
|
+
# walwal-harness dashboard runtime
|
|
60
|
+
.harness/dashboard/apps/harness-dashboard/node_modules/
|
|
61
|
+
.harness/dashboard/apps/harness-dashboard/.next/
|
|
62
|
+
.harness/dashboard/apps/harness-dashboard/.turbo/
|
|
63
|
+
.harness/dashboard/apps/harness-dashboard/tsconfig.tsbuildinfo
|
|
64
|
+
.harness/dashboard/.download/
|
|
65
|
+
EOF
|
|
66
|
+
)"
|
|
67
|
+
if [[ -f "$gitignore" ]] && grep -Fq "$marker" "$gitignore"; then
|
|
68
|
+
return
|
|
69
|
+
fi
|
|
70
|
+
mkdir -p "$(dirname "$gitignore")"
|
|
71
|
+
if [[ -s "$gitignore" ]] && [[ "$(tail -c 1 "$gitignore" 2>/dev/null || true)" != "" ]]; then
|
|
72
|
+
printf '\n' >> "$gitignore"
|
|
73
|
+
fi
|
|
74
|
+
printf '%s\n' "$block" >> "$gitignore"
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
ensure_gitignore
|
|
78
|
+
|
|
56
79
|
echo "[brick-office] HARNESS_ROOT = ${HARNESS_ROOT}"
|
|
57
|
-
echo "[brick-office] dashboard
|
|
80
|
+
echo "[brick-office] dashboard runtime path = ${LOCAL_DIR}"
|
|
58
81
|
|
|
59
82
|
if [[ -d "${PACKAGED_DASHBOARD}" ]]; then
|
|
60
83
|
INSTALLED_VERSION=""
|
|
@@ -70,14 +93,19 @@ if [[ -d "${PACKAGED_DASHBOARD}" ]]; then
|
|
|
70
93
|
fi
|
|
71
94
|
elif [[ ! -d "${LOCAL_DIR}/${DASHBOARD_PATH}" ]]; then
|
|
72
95
|
echo "[brick-office] 첫 실행 — git sparse-checkout 으로 dashboard 만 가져옵니다 (~5MB)."
|
|
73
|
-
|
|
74
|
-
|
|
96
|
+
rm -rf "${LOCAL_DIR}/.download"
|
|
97
|
+
mkdir -p "${LOCAL_DIR}/.download"
|
|
98
|
+
cd "${LOCAL_DIR}/.download"
|
|
75
99
|
git init -q
|
|
76
100
|
git remote add origin "${REPO_URL}" 2>/dev/null || true
|
|
77
101
|
git config core.sparseCheckout true
|
|
78
102
|
echo "${DASHBOARD_PATH}/" > .git/info/sparse-checkout
|
|
79
103
|
git fetch --depth=1 origin main -q
|
|
80
104
|
git checkout main -q
|
|
105
|
+
mkdir -p "${LOCAL_DIR}/apps"
|
|
106
|
+
rm -rf "${LOCAL_DIR:?}/${DASHBOARD_PATH}"
|
|
107
|
+
cp -R "${DASHBOARD_PATH}" "${LOCAL_DIR}/apps/"
|
|
108
|
+
rm -rf "${LOCAL_DIR}/.download"
|
|
81
109
|
echo "[brick-office] 다운로드 완료."
|
|
82
110
|
fi
|
|
83
111
|
|
|
@@ -397,7 +397,7 @@ meeting_json="$(jq -n \
|
|
|
397
397
|
echo "### Dispatcher/CEO"
|
|
398
398
|
case "$verdict" in
|
|
399
399
|
owner_needed)
|
|
400
|
-
echo "- 판단: escalation
|
|
400
|
+
echo "- 판단: escalation 상태다. 먼저 CEO/CXX가 내부 권장안을 확정하고, 외부 권한(credentials/secrets, payment approval, legal/business acceptance, production access, destructive data action)이 필요할 때만 Owner-facing BLOCKED로 보고한다."
|
|
401
401
|
;;
|
|
402
402
|
*)
|
|
403
403
|
echo "- 판단: 최초 GOAL 이후 Owner 입력은 interrupt다. 회사는 Owner를 기다리지 않고 GOAL 달성 루프를 계속한다."
|
|
@@ -38,7 +38,7 @@ base_port="${env_base_port:-$config_base_port}"
|
|
|
38
38
|
if [ -z "$base_port" ]; then
|
|
39
39
|
echo "ERROR: HARNESS_BASE_PORT is not set." >&2
|
|
40
40
|
echo "" >&2
|
|
41
|
-
echo " CEO must
|
|
41
|
+
echo " CEO/CXX must choose an available {xx}000 base port and add it to .env:" >&2
|
|
42
42
|
echo " HARNESS_BASE_PORT=3000" >&2
|
|
43
43
|
echo "" >&2
|
|
44
44
|
echo " OPS cannot monitor ports without a declared base. Set the value and re-run." >&2
|
|
@@ -208,7 +208,7 @@ if [ "$live" != "true" ] || [ "${service_count:-0}" -eq 0 ]; then
|
|
|
208
208
|
(if (.log.configured|not) then "not configured" elif (.log.exists|not) then "missing" else ((.log.recent_errors|tostring) + " recent errors") end) +
|
|
209
209
|
" | \(.status) |"' <<<"$build_results_json"
|
|
210
210
|
echo ""
|
|
211
|
-
echo "No production service endpoints are configured.
|
|
211
|
+
echo "No production service endpoints are configured. CEO+CTO+OPS must derive runtime.production.services[] from repo config, scripts, running processes, Docker, logs, or CXX reports before OPS can monitor live servers. Escalate to Owner only for external authority such as missing credentials or unavailable production access."
|
|
212
212
|
} > "$report_path"
|
|
213
213
|
echo "$report_rel"
|
|
214
214
|
exit 0
|
package/scripts/harness-stop.sh
CHANGED
|
@@ -28,23 +28,6 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
|
28
28
|
AUTO_CHAIN=$(jq -r '.behavior.auto_chain_on_stop // true' "$CONFIG" 2>/dev/null || echo "true")
|
|
29
29
|
if [ "$AUTO_CHAIN" != "true" ]; then exit 0; fi
|
|
30
30
|
|
|
31
|
-
# CXX direct-execution guard:
|
|
32
|
-
# If a mission has CXX documents but no worker reports, block the stop so the
|
|
33
|
-
# company loop must hire/dispatch workers instead of ending with CXX-only work.
|
|
34
|
-
if [ -x "$SCRIPT_DIR/harness-worker-evidence-validate.sh" ]; then
|
|
35
|
-
WORKER_EVIDENCE_JSON=$("$SCRIPT_DIR/harness-worker-evidence-validate.sh" "$CWD" json 2>/dev/null || true)
|
|
36
|
-
WORKER_EVIDENCE_OK=$(echo "$WORKER_EVIDENCE_JSON" | jq -r 'if has("ok") then .ok else true end' 2>/dev/null || echo true)
|
|
37
|
-
if [ "$WORKER_EVIDENCE_OK" != "true" ]; then
|
|
38
|
-
REASON=$(echo "$WORKER_EVIDENCE_JSON" | jq -r '
|
|
39
|
-
"CXX 직접 실행 차단: " +
|
|
40
|
-
([.violations[] | "\(.mission) has CXX docs without worker reports: \(.docs | join(","))"] | join("; ")) +
|
|
41
|
-
". harness-hiring/resource-manager로 전문 worker를 고용 또는 배정하고 .harness/documents/{goal-or-child-mission}/{owning-cxx}/workers/{worker-name}.md 를 남긴 뒤 계속하라."
|
|
42
|
-
' 2>/dev/null || echo "CXX 직접 실행 차단: worker report가 없는 mission이 있습니다. hired worker 보고서를 먼저 생성하세요.")
|
|
43
|
-
jq -nc --arg reason "$REASON" '{decision:"block", reason:$reason}'
|
|
44
|
-
exit 0
|
|
45
|
-
fi
|
|
46
|
-
fi
|
|
47
|
-
|
|
48
31
|
# 무한루프 방지: 한 sprint 안에서 stop_chain_count 가 상한을 넘으면 중단
|
|
49
32
|
STOP_CHAIN_MAX=$(jq -r '.behavior.auto_chain_max_per_sprint // 200' "$CONFIG" 2>/dev/null || echo 200)
|
|
50
33
|
STOP_CHAIN_COUNT=$(jq -r '.conductor.stop_chain_count // 0' "$PROGRESS" 2>/dev/null || echo 0)
|
|
@@ -96,6 +79,24 @@ fi
|
|
|
96
79
|
|
|
97
80
|
if [ "$should_chain" != "true" ]; then exit 0; fi
|
|
98
81
|
|
|
82
|
+
# CXX direct-execution guard:
|
|
83
|
+
# Only run this while an active company loop is actually chaining. Scope it to
|
|
84
|
+
# the newest active mission so legacy/archive documents cannot keep Stop
|
|
85
|
+
# blocked forever.
|
|
86
|
+
if [ -x "$SCRIPT_DIR/harness-worker-evidence-validate.sh" ]; then
|
|
87
|
+
WORKER_EVIDENCE_JSON=$("$SCRIPT_DIR/harness-worker-evidence-validate.sh" "$CWD" json latest-active 2>/dev/null || true)
|
|
88
|
+
WORKER_EVIDENCE_OK=$(echo "$WORKER_EVIDENCE_JSON" | jq -r 'if has("ok") then .ok else true end' 2>/dev/null || echo true)
|
|
89
|
+
if [ "$WORKER_EVIDENCE_OK" != "true" ]; then
|
|
90
|
+
REASON=$(echo "$WORKER_EVIDENCE_JSON" | jq -r '
|
|
91
|
+
"CXX 직접 실행 차단: " +
|
|
92
|
+
([.violations[] | "\(.mission) has CXX docs without worker reports: \(.docs | join(","))"] | join("; ")) +
|
|
93
|
+
". harness-hiring/resource-manager로 전문 worker를 고용 또는 배정하고 .harness/documents/{goal-or-child-mission}/{owning-cxx}/workers/{worker-name}.md 를 남긴 뒤 계속하라."
|
|
94
|
+
' 2>/dev/null || echo "CXX 직접 실행 차단: worker report가 없는 active mission이 있습니다. hired worker 보고서를 먼저 생성하세요.")
|
|
95
|
+
jq -nc --arg reason "$REASON" '{decision:"block", reason:$reason}'
|
|
96
|
+
exit 0
|
|
97
|
+
fi
|
|
98
|
+
fi
|
|
99
|
+
|
|
99
100
|
# stop_chain_count 증가 (느슨한 카운터 — race 허용)
|
|
100
101
|
NEW_COUNT=$((STOP_CHAIN_COUNT + 1))
|
|
101
102
|
TMP=$(mktemp)
|
|
@@ -195,6 +195,8 @@ ${CONTEXT_WARNING}
|
|
|
195
195
|
- CXX는 직접 전문 산출물을 만들지 않고 worker report를 \`.harness/documents/{goal-or-child-mission}/{owning-cxx}/workers/\`에 남겨야 한다
|
|
196
196
|
- Owner에게 "계속 진행", "진행할까요?", "다음 명령을 입력하세요"를 요구하지 않는다. GOAL이 있고 escalation이 아니면 즉시 next_agent/current_agent 업무를 수행한다
|
|
197
197
|
- Owner 입력은 목표 변경·사고·결과 확인용이지 회사 진행을 펌프하는 신호가 아니다
|
|
198
|
+
- CEO가 혼자 결정하기 어려우면 Owner에게 묻지 말고 관련 CXX 회의를 열어 written recommendation 을 받고 결정한다
|
|
199
|
+
- Owner 입력 대기는 credentials/secrets, payment approval, legal/business acceptance, unavailable production access, destructive data action, stated direction conflict 같은 외부 권한이 필요할 때만 허용한다
|
|
198
200
|
- CEO는 필요한 CXX만 호출하고, CXX는 resource-manager/hiring 없이 worker 업무를 수행하지 않는다
|
|
199
201
|
- 목표 설정/변경 → goal flow | 추가 요구사항 → submission flow | 긴급 수정 → hot-fix flow | 메타 질문 → 짧게 응답 (skip)
|
|
200
202
|
- 활성 pipeline → next_agent/current_agent 컨텍스트로 계속
|