@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.
@@ -985,15 +985,15 @@
985
985
  }
986
986
  },
987
987
  "node_modules/@next/env": {
988
- "version": "15.5.16",
989
- "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.16.tgz",
990
- "integrity": "sha512-9QMKolCl+JnJtaRAQSXy4RQrhgfe8W7/G1+Hl3QSB/HZY7zQMzTwPDdTRwwio8BS96ps1MHpHhbS8qxoNV3JIQ==",
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.16",
995
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.16.tgz",
996
- "integrity": "sha512-wzdER4JZj+31vNkhaZ1Ght3IsNI8DMwj7VqadfIOqJB5sh8FiOqNSopYADQn6mgEPomzDd/DHqBcfo2fmVMYtg==",
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.16",
1011
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.16.tgz",
1012
- "integrity": "sha512-PPTo+cvcanxkuDEuDyZGk28ntmu0WjfkxqlG7hw9Mhsiribs4x1C6h2Culn0cJKqsne1gFjjZRK3ax7WYlSxgg==",
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.16",
1027
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.16.tgz",
1028
- "integrity": "sha512-Jl0IL9P7S8uNl5oI1TqrQmfmLp7OqjWM58000pVnUVIsHrvPP6m9QDW/uNWYUbmd+8IYvc6MTeZKICstBMBpew==",
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.16",
1043
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.16.tgz",
1044
- "integrity": "sha512-Zf0BIqv/o5uOWfyRkzgGhyV2Tky7HLt0bG+w7XWdaU1JpyX0tltM3TrSfa/Y9c597SJG4CzN47+u2InhgZZ4vg==",
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.16",
1059
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.16.tgz",
1060
- "integrity": "sha512-HCDDU1TRLeUDV180QQTWrs5Oa4lIcI7XH9nF0UVUVmYLN/boZ6LqyFtm3814gc1fv+lOVyKaw5B6bVC9BpXTSQ==",
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.16",
1075
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.16.tgz",
1076
- "integrity": "sha512-kvXUY1dn5wxKuMkXxQRUbPjEnKxW1PR9uKOm0zpIpj3574+cFfaePhYFmBVtrOuwt+w34OdDzNaJr5Iixf+HBQ==",
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.16",
1091
- "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.16.tgz",
1092
- "integrity": "sha512-zpOQuF+eyENMXRjglp2hZCIrUjTdO37suEBnDn1mX4PXSuetXZDMLpjKOh4dYSw3SiDTnOoOUwBl5i5Elr6nnQ==",
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.16",
1107
- "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.16.tgz",
1108
- "integrity": "sha512-LnwKYpiSmIzXlTq76hMeeIzZoDcFwu848p6H+QBkGFJIbZphgzNUPdHruJcHM/bFnaFeco0l1Frie5I27VKglA==",
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.17",
1691
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.17.tgz",
1692
- "integrity": "sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==",
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.16",
3952
- "resolved": "https://registry.npmjs.org/next/-/next-15.5.16.tgz",
3953
- "integrity": "sha512-aZExBk/V6JCu3NCFc90twdj9L/M3y0+ukeQwUAZbOiqRhAX+h2oMEa0NZFhcpj6HYRYjVS3V2/3xvyOpNnmw7A==",
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.16",
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.16",
3970
- "@next/swc-darwin-x64": "15.5.16",
3971
- "@next/swc-linux-arm64-gnu": "15.5.16",
3972
- "@next/swc-linux-arm64-musl": "15.5.16",
3973
- "@next/swc-linux-x64-gnu": "15.5.16",
3974
- "@next/swc-linux-x64-musl": "15.5.16",
3975
- "@next/swc-win32-arm64-msvc": "15.5.16",
3976
- "@next/swc-win32-x64-msvc": "15.5.16",
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. If uncertain, ask.
39
- - If multiple approaches exist, name them — don't pick silently.
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
- - If something is unclear, stop. Name what is unclear. Ask.
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": "Owner+CEO+CTO 합의로만 services[] 를 수정한다. local/docker/vm/aws/cloud 등 운영 서버 매핑을 Owner에게 받아 기록한다. live=true 이고 services[] 가 있으면 OPS 는 매 hourly review 마다 port/health/log 상태를 운영보고서에 남긴다.",
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
- # For consumer projects, add .worktrees/ to .gitignore
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) GOAL 모호성 명료화 (1~2 개 객관식 질문, 한 번만), (b) 결과 보고, (c) escalation 셋 뿐.
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)) continue;
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에 lifecycle 보강`);
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 must agree on a {xx}000 base port with the Owner.\n# Set HARNESS_BASE_PORT before CXX agents allocate any service ports.\n# HARNESS_BASE_PORT=\n`;
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 — set value with Owner approval before starting services');
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
 
@@ -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
 
@@ -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 ask the Owner to create or select one with `/goal` before proceeding.
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
 
@@ -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.34",
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 = missions.find((m) => m.active) ?? missions.sort((a, b) => b.mtimeMs - a.mtimeMs)[0] ?? null;
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
- # (~/.walwal-harness/dashboard/<project-key>) 에 격리 복사 후 dev 실행한다.
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
- PROJECT_KEY="$(printf '%s' "${HARNESS_ROOT}" | shasum -a 1 | awk '{print substr($1,1,12)}')"
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 격리 경로 = ${LOCAL_DIR}"
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
- mkdir -p "${LOCAL_DIR}"
74
- cd "${LOCAL_DIR}"
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 상태이므로 Owner에게 외부 결정이 필요한지 확인한다."
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 agree on a {xx}000 base port with the Owner and add it to .env:" >&2
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. Owner+CEO+CTO must define runtime.production.services[] before OPS can monitor live servers."
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
@@ -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 컨텍스트로 계속