@kaydash9999/banker-plugins 0.22.0 → 0.23.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +68 -0
- package/PRIVACY.md +1 -0
- package/README.md +39 -13
- package/bin/banker.js +118 -22
- package/bin/lib/codex-hooks.mjs +116 -18
- package/bin/lib/codex-names.mjs +4 -0
- package/bin/lib/codex-routes.mjs +93 -1
- package/bin/lib/command-skill.cjs +37 -6
- package/codex/command-skills/front-qa/SKILL.md +1 -1
- package/codex/command-skills/setup/SKILL.md +4 -4
- package/codex/hooks.json +5 -5
- package/codex/manifest.json +18 -15
- package/codex/skills/progress/scripts/progress.mjs +44 -14
- package/codex/skills/teamwork/SKILL.md +143 -0
- package/codex/skills/teamwork/scripts/teamwork.mjs +1007 -0
- package/codex/transform-matrix.md +5 -3
- package/hooks/obsidize-hook.mjs +75 -32
- package/hooks/telemetry-count-codex.mjs +238 -57
- package/hooks/update-fetch.mjs +2 -1
- package/hooks/update-notify.mjs +82 -20
- package/package.json +3 -1
- package/skills/3d-intro-build/SKILL.md +101 -20
- package/skills/3d-intro-build/references/NOTICE.md +9 -2
- package/skills/3d-intro-build/references/assemble.mjs +113 -22
- package/skills/3d-intro-build/references/azure-adapter.mjs +110 -24
- package/skills/3d-intro-build/references/clip-post.mjs +443 -0
- package/skills/3d-intro-build/references/dive-mode.mjs +299 -0
- package/skills/3d-intro-build/references/intro-fixes.css +11 -0
- package/skills/3d-intro-build/references/prompts.md +51 -4
- package/skills/3d-intro-build/references/scrub-engine.js +1 -0
- package/skills/3d-intro-build/references/step-nav.css +29 -0
- package/skills/3d-intro-build/references/step-nav.js +284 -106
- package/skills/3d-intro-build/references/verify-intro.mjs +373 -32
- package/skills/3d-intro-build/references/verify.md +6 -0
- package/skills/3d-intro-build/references/video-pool.mjs +142 -12
- package/skills/3d-intro-setup/SKILL.md +20 -7
- package/skills/3d-intro-setup/references/azure-adapter.mjs +110 -24
- package/skills/3d-intro-setup/references/video-pool.mjs +142 -12
- package/skills/all-in-one/SKILL.md +125 -86
- package/skills/omc-patch/SKILL.md +1 -1
- package/skills/payload-mon/SKILL.md +1 -1
- package/skills/play-qa/SKILL.md +6 -4
- package/skills/progress-mon/README.md +164 -0
- package/skills/progress-mon/SKILL.md +165 -0
- package/skills/progress-mon/assets/fixture/README.md +1 -0
- package/skills/progress-mon/assets/fixture/arch.json +33 -0
- package/skills/progress-mon/assets/fixture/commits.json +7 -0
- package/skills/progress-mon/assets/fixture/config.json +30 -0
- package/skills/progress-mon/assets/fixture/events.jsonl +7 -0
- package/skills/progress-mon/assets/fixture/flow.json +44 -0
- package/skills/progress-mon/assets/fixture/items.json +14 -0
- package/skills/progress-mon/assets/fixture/req-spec.json +31 -0
- package/skills/progress-mon/assets/fixture/reqs.json +11 -0
- package/skills/progress-mon/assets/fixture/variants/arch-auto/arch.json +58 -0
- package/skills/progress-mon/assets/fixture/variants/check-auto/arch.json +15 -0
- package/skills/progress-mon/assets/fixture/variants/check-overlap/arch.json +14 -0
- package/skills/progress-mon/assets/fixture/variants/history-manual/config.json +13 -0
- package/skills/progress-mon/assets/fixture/variants/history-manual/items.json +7 -0
- package/skills/progress-mon/assets/fixture/variants/workflow-wide/flow.json +35 -0
- package/skills/progress-mon/assets/fixture/workflows/wf_ex1/agent-a01.jsonl +1 -0
- package/skills/progress-mon/assets/fixture/workflows/wf_ex1/agent-a02.jsonl +1 -0
- package/skills/progress-mon/assets/fixture/workflows/wf_ex1/agent-a03.jsonl +1 -0
- package/skills/progress-mon/assets/fixture/workflows/wf_ex1/agent-a04.jsonl +1 -0
- package/skills/progress-mon/assets/fixture/workflows/wf_ex1/journal.jsonl +7 -0
- package/skills/progress-mon/references/arch.md +280 -0
- package/skills/progress-mon/references/authoring.md +199 -0
- package/skills/progress-mon/references/config.md +115 -0
- package/skills/progress-mon/references/flow.md +75 -0
- package/skills/progress-mon/references/inventory.md +58 -0
- package/skills/progress-mon/references/items.md +74 -0
- package/skills/progress-mon/references/req-spec.md +74 -0
- package/skills/progress-mon/references/reqs.md +30 -0
- package/skills/progress-mon/scripts/index.js +31 -0
- package/skills/progress-mon/scripts/pm-check.mjs +549 -0
- package/skills/progress-mon/scripts/pm-config.mjs +343 -0
- package/skills/progress-mon/scripts/pm-data.mjs +394 -0
- package/skills/progress-mon/scripts/pm-html.mjs +77 -0
- package/skills/progress-mon/scripts/pm-memory.mjs +333 -0
- package/skills/progress-mon/scripts/pm-render.mjs +1644 -0
- package/skills/progress-mon/scripts/pm-server.mjs +781 -0
- package/skills/progress-mon/scripts/pm-sources.mjs +501 -0
- package/skills/progress-mon/scripts/progress-mon.mjs +167 -0
- package/skills/ralph-qa/SKILL.md +107 -17
- package/skills/ralph-qa/references/gate-evidence.mjs +457 -0
- package/skills/ralph-qa/references/payload-scan.mjs +19 -2
- package/skills/ralph-qa/references/run-folder.mjs +299 -0
- package/skills/ralph-qa/references/seat-payload.mjs +60 -13
- package/skills/ralph-qa/references/seat-run.mjs +200 -159
- package/skills/remains/SKILL.md +2 -0
- package/skills/remains/scripts/boxes.mjs +6 -2
- package/skills/setup-bypass-permissions/scripts/codex-config.mjs +19 -8
- package/skills/setup-mcp/SKILL.md +1 -1
- package/skills/setup-omc-hud/SKILL.md +2 -1
- package/skills/setup-omc-hud/assets/codex-config.mjs +19 -8
- package/skills/ultra-chain/SKILL.md +32 -14
- package/skills/ultra-chain/references/chain-ledger.mjs +111 -3
- package/skills/ultra-init/SKILL.md +30 -22
- package/skills/ultraqa/NOTICE.md +34 -0
- package/skills/ultraqa/SKILL.md +197 -0
- package/skills/ultraqa/references/gate-evidence.mjs +457 -0
- package/skills/ultraqa/references/run-folder.mjs +299 -0
- package/skills/ultraqa/references/tmux-drive.md +52 -0
- package/skills/ultraqa/references/uqa-run.mjs +339 -0
- package/skills/update-banker/SKILL.md +1 -1
|
@@ -122,7 +122,8 @@ node "<이 스킬 디렉터리 절대경로>\assets\apply-hud.mjs"
|
|
|
122
122
|
node "<이 스킬 디렉터리 절대경로>/../payload-mon/scripts/payload-mon.mjs" on
|
|
123
123
|
```
|
|
124
124
|
|
|
125
|
-
- Codex
|
|
125
|
+
- Codex npm 사본(`banker-setup-omx-hud`)에서 실행할 때 경로는 `<이 스킬 디렉터리 절대경로>/../banker-payload-mon/scripts/payload-mon.mjs` 다.
|
|
126
|
+
- Codex 플러그인 사본(`codex/renamed-skills/setup-omx-hud`)에서 실행할 때 경로는 `<이 스킬 디렉터리 절대경로>/../../../skills/payload-mon/scripts/payload-mon.mjs` 다.
|
|
126
127
|
- 이유: `PL:` 칸은 payload-mon 이 래퍼 옆(`hud/payload-mon/`)에 두는 크기 계산 모듈을 쓴다. 모듈이 없으면 `PL:` 이 나오지 않는다. 래퍼 파일이 링크면 링크가 가리키는 파일 옆에 둔다. 래퍼는 이 모듈을 링크가 가리키는 파일 옆에서, 로더(`omc-hud.mjs`)는 statusLine 명령의 경로 옆에서 먼저 찾는다.
|
|
127
128
|
- 출력 `켰습니다. 다음 statusline 갱신부터 PL 칸에 요청 크기가 늘 표시됩니다.` 를 확인한다. `이미 켜져 있습니다`, `모듈 사본을 이 버전으로 맞췄습니다` 도 정상이다.
|
|
128
129
|
|
|
@@ -166,16 +166,27 @@ export function setKey(text, table, key, rawValue, comment = '') {
|
|
|
166
166
|
return ls.join(nl);
|
|
167
167
|
}
|
|
168
168
|
const range = tableRange(scan(text), table);
|
|
169
|
-
if (!range)
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
169
|
+
if (!range) return withNewTable(ls, table, line).join(nl);
|
|
170
|
+
const [at, after] = placeIn(ls, range);
|
|
171
|
+
ls.splice(at, 0, ...line, ...after);
|
|
172
|
+
return ls.join(nl);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function withNewTable(ls, table, line) {
|
|
176
|
+
while (ls.length && ls[ls.length - 1] === '') ls.pop();
|
|
177
|
+
return [...ls, ...(ls.length ? [''] : []), `[${table}]`, ...line, ''];
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// 표 안에서 새 키를 넣을 줄 번호와 키 뒤에 더할 줄. 다음 표 머리에 붙은 주석(`# MCP servers` 처럼 머리 바로 위의 주석
|
|
181
|
+
// 줄)과 그 앞 빈 줄은 건너뛴다. 건너뛴 주석이 파일 첫 줄까지 닿으면 파일 머리 주석으로 보고 그 뒤에 넣고, 키와 표 머리
|
|
182
|
+
// 사이에 빈 줄 하나를 둔다(파일 첫 줄부터 표 설명 주석인 파일도 이렇게 되지만 값의 뜻은 같다).
|
|
183
|
+
function placeIn(ls, range) {
|
|
174
184
|
let at = range[1];
|
|
175
|
-
|
|
185
|
+
const beforeHead = range[1] < ls.length;
|
|
186
|
+
if (beforeHead) while (at > range[0] && ls[at - 1].trim().startsWith('#')) at--;
|
|
187
|
+
if (beforeHead && at === 0 && range[1] > 0) return [range[1], ['']];
|
|
176
188
|
while (at > range[0] && ls[at - 1].trim() === '') at--;
|
|
177
|
-
|
|
178
|
-
return ls.join(nl);
|
|
189
|
+
return [at, []];
|
|
179
190
|
}
|
|
180
191
|
|
|
181
192
|
// 키를 뺀다. comment 와 같은 주석 줄이 바로 위에 있으면 그것도 뺀다.
|
|
@@ -55,9 +55,9 @@ ultra-chain 이 직접 하는 일은 여섯 가지다.
|
|
|
55
55
|
| 1 자료 조사 | `Skill("banker:deep-research")` | `$banker-deep-research` |
|
|
56
56
|
| 1 전문가 작업 방식 | `Skill("banker:lfm")` | `$banker-lfm` |
|
|
57
57
|
| 2 모호성 제거 | `Skill("banker:ultra-interview")` | `$banker-ultra-interview` |
|
|
58
|
-
| 3 합의 계획 | `Skill("oh-my-claudecode:ralplan")` `--deliberate`, 이어서 `Skill("banker:ralph-qa")` | `$ralplan --deliberate`, 이어서 `$banker-ralph-qa` |
|
|
58
|
+
| 3 합의 계획 | `Skill("oh-my-claudecode:ralplan")` `--deliberate`, 이어서 `Skill("banker:ralph-qa")` | `$ralplan --deliberate`, 이어서 `$banker-ralph-qa`(플러그인 길 `$banker:ralph-qa`) |
|
|
59
59
|
| 5 구현 | `Skill("oh-my-claudecode:ralph")` `--critic=critic` | `$ralph` 뒤 이 스킬의 critic 루프(OMX `ralph` 에는 `--critic` 이 없다) |
|
|
60
|
-
| 6 합의 검증 | `Skill("banker:ralph-qa")` | `$banker-ralph-qa` |
|
|
60
|
+
| 6 합의 검증 | `Skill("banker:ralph-qa")` | `$banker-ralph-qa`(플러그인 길 `$banker:ralph-qa`) |
|
|
61
61
|
| 7 시각 판정 에이전트 | `Plan` 유형, `model` 없이 | `spawn_agent`, 역할과 `model` 없이 |
|
|
62
62
|
| 질문 | `AskUserQuestion` | `request_user_input`. 없으면 번호 붙인 평문 선택지 |
|
|
63
63
|
| 오래 도는 명령 | Bash `run_in_background`, 멈출 때 `TaskStop` | `exec_command` 를 `tty: true` 로 띄우고 `write_stdin` 으로 출력을 받음. 멈출 때 그 세션에 `write_stdin` 으로 Ctrl-C(`\u0003`). `tty` 없이 띄운 작업은 PID 로 멈춤 |
|
|
@@ -68,6 +68,7 @@ ultra-chain 이 직접 하는 일은 여섯 가지다.
|
|
|
68
68
|
- Codex 에는 Skill 도구가 없다. 위 표의 `$이름` 은 그 스킬의 `SKILL.md` 를 읽고 그대로 따른다는 뜻이다. banker 스킬은 npm 설치면 `<S>/../banker-<이름>/SKILL.md`, Codex 플러그인 설치(`<S>` 가 `plugins/cache/` 아래, 스킬 이름 `banker:<이름>`)면 `<S>/../<이름>/SKILL.md` 다. 표의 `$banker-<이름>` 은 플러그인 설치에서 `$banker:<이름>` 이다. OMX 스킬은 `~/.codex/skills/<이름>/SKILL.md` 다. 그 스킬이 상태 기록을 요구하면 그 지시대로 직접 기록한다. 큰 `SKILL.md`(ralph-qa 는 약 71KB)는 셸 출력 한도에서 잘리니 나눠 읽는다.
|
|
69
69
|
- Codex 의 하위 에이전트(critic, 시각 판정)는 저자 대화를 넘기지 않는다. multi-agent v2 는 `fork_turns="none"` 을 주고, v1 은 `fork_context` 를 주지 않는다. 판정을 받으면 `close_agent` 로 닫는다.
|
|
70
70
|
- Codex 환경 지시가 역할(`agent_type`)을 요구하면, 고정 모델이 세션 모델과 같은 역할을 쓰고 지시 앞머리에 파일 쓰기 금지를 적는다. 그런 역할이 없으면 역할 없이 띄운다. 쓴 역할과 모델, 강도를 판정 기록의 `note` 에 적는다.
|
|
71
|
+
- **Codex 의 tmux 밖 실행.** OMX 의 런타임 워크플로(`ralph`, `team` 등)는 OMX tmux 런타임을 요구한다. OMX 의 `AGENTS.md` 는 tmux 밖(Codex App, 일반 `codex`, `codex exec`)이면 그 사실을 알리고 가장 가까운 대체 경로로 계속하라고 정한다(oh-my-codex 0.20.2 `templates/AGENTS.md`). 그래서 tmux 밖이라는 사실만으로는 멈추지 않는다. 그 단계는 이 세션이 그 스킬의 `SKILL.md` 절차를 네이티브 하위 에이전트로 그대로 따르고, 보고에 `<단계>: tmux 밖 대체 실행(OMX 런타임 없음)` 한 줄을 적는다. 종결 낱말은 다른 멈춤 조건과 마지막 ralph-qa 판정으로만 정한다. 대체 실행도 할 수 없으면(하위 에이전트 기능이 꺼짐 등) `STOPPED(omx-runtime-unavailable)` 로 멈추고 tmux 안의 OMX 에서 다시 실행하라고 안내한다.
|
|
71
72
|
- Codex 의 오래 도는 명령은 기다리는 시간을 박스 `--timeout` 보다 길게 둔다. 기다리다 끊기면 박스 정리와 결과 JSON 이 남지 않는다.
|
|
72
73
|
- Codex 세션을 닫으면 그 세션에서 띄운 서버도 끝날 수 있다. 오래 볼 미리보기는 사용자 터미널에서 띄우게 안내한다(9단계).
|
|
73
74
|
|
|
@@ -81,7 +82,7 @@ ultra-chain 이 직접 하는 일은 여섯 가지다.
|
|
|
81
82
|
| 박스 시험(`boxes.mjs run`) | ssh, scp 네트워크와 `git stash create` 의 `.git` 쓰기 |
|
|
82
83
|
| `npm ci` 같은 의존성 설치, 웹 조사, 외부 좌석 | 네트워크 |
|
|
83
84
|
| 미리보기 서버, Chromium | 포트와 브라우저 실행 |
|
|
84
|
-
| ralph-qa 좌석 폴더 | 작업 폴더 밖 쓰기 |
|
|
85
|
+
| ralph-qa 좌석 폴더(`seat-run.mjs init`), 게이트 기록 폴더 `<g>`(`gate-evidence.mjs` 의 init, run, cleanup) | 작업 폴더 밖 쓰기 |
|
|
85
86
|
|
|
86
87
|
- 모든 박스가 같은 권한 오류로 실패하면 접속 실패로 판정하지 않는다. 승인을 받아 다시 돌린 뒤 판정한다.
|
|
87
88
|
- 스테이징을 못 하면 새 시험 파일은 박스로 가지 않는다. 그 시험은 박스에서 미검증으로 적는다.
|
|
@@ -96,6 +97,8 @@ ultra-chain 이 직접 하는 일은 여섯 가지다.
|
|
|
96
97
|
| `<S>` | 이 스킬 디렉터리 절대경로 |
|
|
97
98
|
| `<boxes>` | Claude Code `<S>/../remains/scripts/boxes.mjs`, Codex `<S>/../banker-remains/scripts/boxes.mjs` |
|
|
98
99
|
| `<scan>` | Claude Code `<S>/../ralph-qa/references/payload-scan.mjs`, Codex `<S>/../banker-ralph-qa/references/payload-scan.mjs` |
|
|
100
|
+
| `<rq>` | ralph-qa 의 `references` 폴더. Claude Code `<S>/../ralph-qa/references`, Codex npm 설치 `<S>/../banker-ralph-qa/references`, Codex 플러그인 설치 `<S>/../ralph-qa/references`. 게이트 실행기 `gate-evidence.mjs` 와 실행 폴더 도구 `seat-run.mjs` 가 여기 있다 |
|
|
101
|
+
| `<g>` | 게이트 기록 폴더. 5단계 1에서 `node "<rq>/gate-evidence.mjs" init` 이 낸 `dir`(`ralph-qa-gates.<영숫자>`)다. 경로는 `05-baseline.md` 첫 줄에 있다. 9단계까지 남고, 어느 cleanup 의 하루 규칙도 지우지 않는다 |
|
|
99
102
|
| `<run>` | 0단계에서 만든 실행 폴더 절대경로 |
|
|
100
103
|
| `<base>` | 0단계에서 기록한 기준 커밋. 깨끗한 트리면 `HEAD`, 기존 변경을 두고 진행하면 `git stash create` 가 낸 커밋. ralph-qa 와 critic 이 만드는 diff 의 기준이다 |
|
|
101
104
|
| `<agents>`, `<max>` | `--agents`, `--max` 값(기본 3, 5) |
|
|
@@ -172,7 +175,7 @@ node "<S>/references/chain-ledger.mjs" event "<run>" --stage research --status d
|
|
|
172
175
|
- `.omc/` 나 `.omx/` 가 git 에 무시되지 않으면 사용자에게 알린다. 나중에 커밋할 때 상태 파일이 섞일 수 있다. 로컬 제외 파일에 넣을지는 사용자가 정한다.
|
|
173
176
|
- 커밋하지 않은 변경이 있으면 진행할지 묻는다(`--auto` 는 멈춤). 진행하면 지금 트리를 기준선으로 쓴다. `git stash create` 로 지금 트리의 커밋을 만들어 `<base>` 로 기록한다(작업 트리와 stash 목록은 바뀌지 않는다). 깨끗한 트리이거나 출력이 비면(기존 변경이 추적하지 않는 새 파일뿐) `<base>` 는 `HEAD` 의 커밋이다. 이렇게 해야 검토 diff 에 사용자의 기존 변경이 실리지 않는다.
|
|
174
177
|
- 기본 브랜치면 작업 브랜치를 만들지 묻는다(`--auto` 는 그대로 진행).
|
|
175
|
-
4. `<boxes
|
|
178
|
+
4. `<boxes>`, `<scan>`, `<rq>/gate-evidence.mjs` 가 있는지 본다. banker 스킬은 함께 설치되므로 없으면 banker 설치가 깨진 것이니 멈추고 알린다. 이어서 실행 폴더를 만들고(`init`) `task.md` 를 쓴 뒤 바로 `preflight` 시작을 기록한다. 이어서 실행 폴더 경로, 해석한 플래그, 지금 단계를 이어 하기 메모(런타임 대응 표)에 덧붙인다. 사용자의 다른 메모는 고치지 않는다. 브랜치를 정한 뒤라 `run.json` 의 브랜치가 맞다. 아래 점검이 사전 점검의 걸린 시간에 들어가고, 점검 중에 멈춰도 기록이 남는다.
|
|
176
179
|
5. 의존성
|
|
177
180
|
- Claude Code: `omc ralph verify --help 2>&1 | grep -q 'Usage: omc ralph verify' && echo "omc ok"`. 판정은 출력 문구로 한다. 실패하면 멈추고 알린다. `setup-omc` 로 맞출지 묻고, 승인할 때만 그 스킬을 따른다. 묻지 않고 설치나 갱신(`omc update`, `npm install -g`)을 하지 않는다(`--auto` 는 멈춤).
|
|
178
181
|
- Claude Code: 판 두 개를 기록한다. 플러그인 판은 `~/.claude/plugins/installed_plugins.json`(`CLAUDE_CONFIG_DIR` 가 있으면 그 폴더의 `plugins/installed_plugins.json`)에서 `oh-my-claudecode@` 로 시작하는 항목의 `version` 이다. CLI 판은 `omc --version` 이다. 주 판(첫 숫자)이 다르면 `checklist` 에 넣고, 그 밖의 차이는 `summary` 에만 적는다. 하위 스킬이 기대한 대로 돌지 않아도 OMC 의 내부 모듈(`dist/` 아래)을 직접 불러 쓰지 않는다. 판이 다른 내부 API 를 부르게 된다.
|
|
@@ -223,6 +226,7 @@ ralplan 은 계획 작성자 외에 Architect 와 Critic 두 검토자로 합의
|
|
|
223
226
|
- 계획에 넣을 것
|
|
224
227
|
- 대상 OS 와 OS 별 시험 명령. 비대화형으로 돌게 한다(`CI=true`, 감시 모드 끔. Windows 는 `cmd` 기준으로 `set CI=true&&`)
|
|
225
228
|
- 시험 출력 꼴. node:test 면 TAP(`--test-reporter=tap`)로 내게 한다. 박스 결과가 시험 수를 셀 수 있다
|
|
229
|
+
- 이 머신의 로컬 게이트: `tests`, `build`, `lint`, `typecheck` 가운데 이 작업에 맞는 것, 게이트마다 명령 하나(`&&` 나 `;` 로 묶지 않음)와 시간 제한(초). 5단계 기준선과 6단계 ralph-qa `--gates` 가 이 목록을 쓴다
|
|
226
230
|
- 4단계 목업의 보기 목록과 형태, 수용 기준과 단계의 대응
|
|
227
231
|
- 7단계 기계 대조를 위해 실제 출력을 `<run>/actual/` 에 쓰는 방법(임시 데이터 폴더나 임시 HOME 에서)
|
|
228
232
|
- 뒤 단계의 계약. Planner 와 검토자가 파일 시스템을 뒤져 찾지 않게 요약을 함께 넘긴다
|
|
@@ -237,6 +241,7 @@ ralplan 은 계획 작성자 외에 Architect 와 Critic 두 검토자로 합의
|
|
|
237
241
|
- Claude Code: 1 에서 지정한 경로, 또는 ralplan 이 보고한 계획 경로다. 둘 다 없으면 이 단계가 시작된 뒤 `.omc/plans/` 에 쓰였고 `pending approval` 표지가 있는 파일을 고른다. 검토 문서(이름이 `-critic.md`, `-architect.md`, `-review.md` 로 끝남)와 `open-questions.md` 는 고르지 않는다. 원본 경로는 `summary` 에 적는다.
|
|
238
242
|
- Codex: 이번에 쓰인 `.omx/plans/prd-*.md` 와 `test-spec-*.md` 를 차례로 붙이고, 원본 경로를 맨 위에 적는다.
|
|
239
243
|
4. ralph-qa 를 `--lens=plan --agents=<agents> --max=<max>` 로 부른다. 외부 좌석 플래그(`--codex`, `--gemini`, `--opencode`)는 사용자가 준 것만 넘긴다.
|
|
244
|
+
- `--gates` 는 주지 않는다. 구현 전이라 돌릴 대상이 없는 계획 검토이고, 까닭은 `계획 검토` 로 넘긴다. ralph-qa 보고의 `게이트: 선언 없음(계획 검토)` 줄은 `03-ralph-qa.md` 에 그대로 두고, 판정 기록의 `verdict.note` 에도 판정 줄과 함께 적는다. 보고에 그 줄이 없으면 기록하기 전에 ralph-qa 에 그 줄을 다시 받는다.
|
|
240
245
|
- 검증 대상: `03-plan.md`(구현 전이라 `<base>` 대비 diff 가 없으니 원문으로 붙인다). 수용 기준: `02-spec.md` 의 AC 와 deliberate 필수 항목(사전 부검, 확장 시험 계획), 그리고 `01-masters.md` 의 `M-n` 이 모두 `## 전문가 작업 방식 적용` 절에 판정과 함께 있는지(조정과 제외에 이유가 있는지).
|
|
241
246
|
- 모든 좌석의 지시에 "저자의 주장이 틀렸다는 증거를 먼저 찾는 적대적 검토자로 판정한다" 를 넣는다. 렌즈 배정은 ralph-qa 그대로다. ralph-qa 의 기본 배정에서는 적대적 반증 렌즈가 한 좌석뿐이라, 이 문장이 있어야 검토자 모두가 적대적이다.
|
|
242
247
|
- 출처-독립 검토자에게 줄 "사용자 원 요청" 은 `task.md` 와 `02-spec.md` 의 사용자 답변 원문이다.
|
|
@@ -288,8 +293,12 @@ ralplan 은 계획 작성자 외에 Architect 와 Critic 두 검토자로 합의
|
|
|
288
293
|
|
|
289
294
|
## 5. 구현
|
|
290
295
|
|
|
291
|
-
1. 기준선: 바꾸기 전에
|
|
292
|
-
-
|
|
296
|
+
1. 기준선: 바꾸기 전에 계획의 로컬 게이트마다 명령을 실행기로 한 번 돌린다. 0단계에서 기존 변경을 두고 진행했으면 지금 트리를 기준선으로 쓴다.
|
|
297
|
+
- `node "<rq>/gate-evidence.mjs" init --cwd "<저장소>"` 로 게이트 기록 폴더를 만든다. 출력의 `dir` 가 `<g>` 다. 이어 하기 메모에 `<g>` 를 덧붙인다.
|
|
298
|
+
- `init` 이나 `run` 이 `not-a-git-tree`(종료 3)로 멈추면 멈춤의 경로(JSON 의 `checked`)가 대상 저장소인지 먼저 확인하고, 아니면 `--cwd "<저장소>"` 로 다시 부른다. 대상이 맞으면 git 저장소가 아니다(0단계 1의 확인 뒤에 저장소가 사라진 경우). 작업 트리 지문이 변경을 보지 못해 게이트 증거가 설 수 없으니 순환을 쓰지 말고 그 자리에서 멈추고 알린다. 스스로 `git init` 하지 않는다. Claude Code 와 Codex(npm 길, 플러그인 길)가 같다.
|
|
299
|
+
- 게이트마다 `node "<rq>/gate-evidence.mjs" run --dir "<g>" --id <게이트> --cmd "<명령>" --timeout <초> --iter 0 --cwd "<저장소>"` 를 돌린다. 반복 0 이 기준선이다. 6단계 ralph-qa 는 같은 명령, 같은 실패 서명의 실패를 이번 변경의 실패가 아닌 것으로 가른다.
|
|
300
|
+
- `<run>/05-baseline.md` 첫 줄에 `<g>` 경로를 쓴다. 그 아래에 게이트마다 출력 JSON 의 `verdict`, `signature`, `output` 과 이미 실패하는 항목을 옮긴다.
|
|
301
|
+
- 깨끗한 사본이 필요하면 저장소 밖 임시 폴더에 `git worktree add --detach <임시> HEAD` 로 만들고 `--cwd` 를 그 폴더로 준다. 의존성을 링크하거나 설치한 뒤 돌리고, 명령이 실제로 돌았는지 확인한다. "명령 없음" 오류뿐인 기록은 기준선이 아니다. 끝나면 `git worktree remove --force <임시>` 로 지운다. 실행기는 명령을 돌린 폴더를 실패 서명에서 `<repo>` 로 바꾼다. 그래서 사본의 실패와 저장소의 같은 실패가 같은 서명이 된다.
|
|
293
302
|
- `git stash`, `git reset` 은 쓰지 않는다.
|
|
294
303
|
2. Claude Code: ralph 를 `--critic=critic` 으로 부른다. 인자에 아래를 넘긴다.
|
|
295
304
|
- `03-plan.md` 경로. 계획은 합의가 끝났으니 다시 계획하지 말고 PRD 이야기로 나눠 구현하라는 말
|
|
@@ -322,12 +331,16 @@ ralplan 은 계획 작성자 외에 Architect 와 Critic 두 검토자로 합의
|
|
|
322
331
|
|
|
323
332
|
## 6. OS 시험과 합의 검증
|
|
324
333
|
|
|
325
|
-
ralph-qa 의 검토자는 시험을 직접 돌리지 않는다.
|
|
334
|
+
ralph-qa 의 검토자는 시험을 직접 돌리지 않는다. 이 머신의 게이트는 실행기(`gate-evidence.mjs run`)가 돌려 `observed` 기록으로 남기고, 박스 시험은 박스 실행기가 돌린다. 검토자는 그 기록과 출력을 대조한다. 회차 `<k>` 는 1을 시작할 때 `show` 의 `qa.maxRound` 다음 번호로 한 번 정하고, 그 회차가 끝날 때까지 바꾸지 않는다.
|
|
326
335
|
|
|
327
336
|
1. 이번 변경의 새 파일을 스테이징한다(`git add -- <파일>...`, 커밋은 하지 않음). 박스로 보내는 트리는 추적 파일만 담는다. 스테이징할 목록을 먼저 보인다.
|
|
328
337
|
- `.omc/`, `.omx/` 아래, `.env` 류, 키와 자격 증명 파일은 넣지 않는다.
|
|
329
338
|
- 넣을 텍스트 파일은 `<scan>` 으로 검사한다. 걸린 파일은 넣지 않고 사용자에게 알린다. 그 파일이 필요한 시험은 박스에서 미검증이다.
|
|
330
|
-
2. 이
|
|
339
|
+
2. 이 머신의 로컬 게이트를 실행기로 돌린다. 게이트마다 `node "<rq>/gate-evidence.mjs" run --dir "<g>" --id <게이트> --cmd "<명령>" --timeout <초> --iter <k> --cwd "<저장소>"` 를 하나씩 돌린다(게이트 하나에 명령 하나). 반복 번호는 회차 `<k>` 다.
|
|
340
|
+
- 이어서 `node "<S>/references/chain-ledger.mjs" gates "<run>" --file "<g>/evidence.md" --round <k>` 로 기록한다. 반복 `<k>` 의 `observed` 기록만 `tests`(`where: "local:<게이트>"`)로 옮기고, 보기 `<run>/qa/local-r<k>.md` 를 만든다.
|
|
341
|
+
- `status` 는 기록의 판정에서 온다. `pass` 는 통과, `fail` 과 `timeout` 은 실패, `misleading` 과 출력 파일 sha256 불일치는 미검증이다. 기준선과 같은 실패는 실패로 두고 `note` 에 적힌다.
|
|
342
|
+
- `reported`(모델이 적은 결과)는 받지 않는다. 시험 결과를 손으로 `tests` 에 적지 않는다.
|
|
343
|
+
- `<g>` 가 없으면(로그아웃이나 재부팅으로 `$XDG_RUNTIME_DIR` 가 비워짐, 지워짐, 이 판보다 먼저 `seat-run.mjs init` 으로 만든 `ralph-qa.*` 폴더가 하루 규칙으로 정리됨) `gate-evidence.mjs init` 으로 새로 만들고 반복 0 없이 돈다. 그러면 기존 실패도 이번 변경의 실패로 셈해진다. 그 사실을 `checklist` 에 넣고 `05-baseline.md` 를 검토 입력에 넣는다.
|
|
331
344
|
3. 박스에서 같은 시험을 돌린다. 고른 박스마다 `--box <이름>` 을 붙인다. 오래 도는 명령으로 돌리고, 끝난 뒤에 기록한다.
|
|
332
345
|
|
|
333
346
|
```bash
|
|
@@ -345,10 +358,12 @@ ralph-qa 의 검토자는 시험을 직접 돌리지 않는다. 연쇄가 이
|
|
|
345
358
|
- 0단계에서 접속된 박스가 0대였으면 이 3을 하지 않는다.
|
|
346
359
|
- 한 OS 에서만 실패하면 원인을 나눈다. 제품 결함은 고치고, 시험이 실행 환경을 잘못 가정한 것도 고친다.
|
|
347
360
|
- `--boxes=none` 이면 이 3을 건너뛴다.
|
|
348
|
-
4. ralph-qa 를 `--lens=both --agents=<agents> --max=<max>` 로 부른다. 외부 좌석은 3단계에서 고른 모델을 값으로 넘긴다.
|
|
349
|
-
- 입력: 요청 원문, `02-spec.md` 의 수용 기준과 사용자 답변 원문, `03-plan.md`, 승인된 목업과 기대 출력,
|
|
361
|
+
4. ralph-qa 를 `--lens=both --gates=<계획의 로컬 게이트> --agents=<agents> --max=<max>` 로 부른다. 외부 좌석은 3단계에서 고른 모델을 값으로 넘긴다.
|
|
362
|
+
- 입력: 요청 원문, `02-spec.md` 의 수용 기준과 사용자 답변 원문, `03-plan.md`, 승인된 목업과 기대 출력, 3의 박스 JSON 과 실패한 박스의 로그 발췌, `05-baseline.md`. diff 의 기준은 `<base>` 다
|
|
363
|
+
- 게이트 증거: 게이트 기록 폴더 `<g>`(반복 0 기준선과 반복 `<k>` 의 `observed` 기록), 게이트마다 명령과 시간 제한, 반복 번호는 회차 `<k>` 라는 말. `<g>` 는 게이트 기록 전용이라 ralph-qa 가 지우지 않는다(9단계에서 지움). 외부 좌석 페이로드는 ralph-qa 가 따로 만든 폴더로 보낸다
|
|
364
|
+
- 박스 JSON 은 기존대로 입력이다(박스 실행기가 만든 기록). 게이트 연언항에는 넣지 않는다
|
|
350
365
|
- 3단계와 같이 모든 좌석의 지시에 적대적 검토 문장을 넣는다
|
|
351
|
-
- 회차마다 `note` 로 기록하고, 끝나면 보고 전문을 `<run>/qa/ralph-qa-r<k>.md` 로 저장한다.
|
|
366
|
+
- 회차마다 `note` 로 기록하고, 끝나면 보고 전문을 `<run>/qa/ralph-qa-r<k>.md` 로 저장한다. `verdict.note` 에는 종결어 전체와 판정 줄, 게이트 블록의 `연언항` 줄을 쓴다. 종결어가 `ITERATE(한도 소진, 원인 gate)` 면 `result` 는 `ITERATE` 이고 `원인 gate` 는 `note` 에 남는다.
|
|
352
367
|
- `ITERATE` 면 고친 뒤 1부터 3까지 다시 하고(새 `<k>`), 같은 실행에서 다시 판정받는다. 끈끈한 반대는 그 검토자의 재판정으로만 풀린다.
|
|
353
368
|
5. 게이트: ralph-qa 판정이 `APPROVE`. `INCONCLUSIVE` 나 한도 소진이면 멈추고 보고한다. 계획의 대상 OS 가운데 확인하지 못한 OS 는 `checklist` 에 하나씩 넣는다.
|
|
354
369
|
|
|
@@ -404,7 +419,7 @@ node "<S>/references/chain-report.mjs" "<run>"
|
|
|
404
419
|
- 커밋 메시지와 PR 본문 초안 파일을 실행 폴더에 만들기
|
|
405
420
|
- 커밋, push, PR 생성, 외부 게시: 사용자가 명시적으로 요청할 때만
|
|
406
421
|
3. 밖으로 나가는 파일은 보내기 전에 하나씩 `node "<scan>" "<파일>"` 로 비밀처럼 보이는 문자열을 찾는다. 출력 JSON 의 `count` 가 0 이고 종료 코드가 0 일 때만 내보낸다. 이미지(캡처 PNG)는 이 검사로 볼 수 없으니, 화면에 비밀이 찍히지 않았는지 사용자에게 확인받는다.
|
|
407
|
-
4. 서버는 사용자가 볼 수 있게 남겨 두고 끄는 명령을 알린다: `node "<S>/references/serve.mjs" --stop "<run>"`. Codex 는 세션을 닫으면 서버가 끝날 수 있으니, 사용자 터미널에서 다시 띄우는 명령(`node "<S>/references/serve.mjs" "<run>"`)도 알린다. 앱 서버처럼 연쇄가 띄운 다른 작업은 모두 멈춘다.
|
|
422
|
+
4. 서버는 사용자가 볼 수 있게 남겨 두고 끄는 명령을 알린다: `node "<S>/references/serve.mjs" --stop "<run>"`. Codex 는 세션을 닫으면 서버가 끝날 수 있으니, 사용자 터미널에서 다시 띄우는 명령(`node "<S>/references/serve.mjs" "<run>"`)도 알린다. 앱 서버처럼 연쇄가 띄운 다른 작업은 모두 멈춘다. 게이트 기록 폴더는 `node "<rq>/gate-evidence.mjs" cleanup --dir "<g>"` 로 지운다(이 판보다 먼저 만든 `ralph-qa.*` 이름의 `<g>` 는 `node "<rq>/seat-run.mjs" cleanup --dir "<g>"`). 기록의 보기는 `qa/local-r<k>.md` 에 남아 있다.
|
|
408
423
|
5. `share` 의 끝을 기록하고 보고서를 마지막으로 다시 만든다.
|
|
409
424
|
|
|
410
425
|
## 최종 보고
|
|
@@ -434,7 +449,7 @@ node "<S>/references/chain-report.mjs" "<run>"
|
|
|
434
449
|
5. 회차는 `maxRound` 다음 번호로 이어 센다. 앞 회차 파일을 덮어쓰지 않는다. `--max` 는 남은 횟수만 쓴다.
|
|
435
450
|
6. 판정이 없는 회차(그 번호의 시험이나 박스 기록은 있는데 같은 번호의 판정 기록이 없음)는 새 번호로, 지금 트리로 시험부터 다시 한다.
|
|
436
451
|
7. 5단계에서 이을 때
|
|
437
|
-
- `05-baseline.md` 는 다시 쓰지 않는다. 이미 바뀐 트리로 쓰면 이번 변경이 만든 실패가 기존 실패로 바뀐다.
|
|
452
|
+
- `05-baseline.md` 는 다시 쓰지 않는다. 이미 바뀐 트리로 쓰면 이번 변경이 만든 실패가 기존 실패로 바뀐다. 반복 0 게이트 기록도 다시 돌리지 않는다. `<g>` 는 `05-baseline.md` 첫 줄에서 되찾는다.
|
|
438
453
|
- 이 판보다 먼저 시작한 실행 폴더에는 기준선이 `05-baseline.txt` 로 있다. `05-baseline.md` 가 없으면 그 파일을 기준선으로 쓴다.
|
|
439
454
|
- 같은 세션에서 ralph 가 아직 켜져 있으면 다시 부르지 않고 끝나기를 기다린다.
|
|
440
455
|
- 새 세션에서 ralph 를 다시 부르면 ralph 는 지금 트리로 기준선을 다시 기록한다. 이 사실을 `build` 의 `note` 에 적고, 새 실패의 판정은 `05-baseline.md` 기준으로 한다.
|
|
@@ -463,10 +478,13 @@ node "<S>/references/chain-report.mjs" "<run>"
|
|
|
463
478
|
|
|
464
479
|
멈출 때는 `stopped` 나 `failed` 와 `reason` 을 기록하고, 8단계 보고서를 만들고 최종 보고를 낸다. 이때 `trace` 는 기록하지 않고 보고서만 만든다. 기록하면 멈춘 실행이 다시 진행 중으로 보인다. `--auto` 면 묻는 대신 이렇게 멈춘다. 끝내지 못한 단계는 통과로 적지 않는다.
|
|
465
480
|
|
|
481
|
+
STOPPED 뒤에는 한 줄 수정을 포함해 어떤 파일도 고치지 않는다. 사용자가 새로 지시할 때까지 보고만 한다. 이 스킬의 어떤 문구("한 줄 수정은 `ralph`" 안내 포함)도 멈춘 뒤의 수정을 허락하지 않는다. 8단계 보고서와 실행 기록 쓰기는 예외다.
|
|
482
|
+
|
|
466
483
|
## 함정
|
|
467
484
|
|
|
468
485
|
- ralplan 의 Architect 와 Critic 은 둘이다. 이 둘을 "검토자 3명" 으로 세지 않는다. 3명 이상은 3단계 4의 ralph-qa 가 채운다.
|
|
469
|
-
- ralph-qa
|
|
486
|
+
- ralph-qa 의 검토자는 시험을 돌리지 않는다. 로컬 게이트는 실행기 기록, OS 는 박스 결과가 증거다. 박스 결과 없이 판정받으면 OS 검증이 빠진다.
|
|
487
|
+
- 반복 0 기준선을 구현 뒤 트리에서 돌리면 이번 변경이 만든 실패가 기준선 실패로 갈려 게이트가 통과한다. 반복 0 은 5단계 1에서만 돌린다.
|
|
470
488
|
- 추적하지 않는 새 파일은 박스로 가지 않는다. 6단계 1의 스테이징을 빼먹으면 새 시험이 박스에서 돌지 않는다.
|
|
471
489
|
- 박스 결과 JSON 은 실행이 끝날 때 한 번 써진다. 끝나기 전에 `chain-ledger.mjs boxes` 를 돌리면 빈 파일이라 실패한다.
|
|
472
490
|
- 피드백 명령의 `grep -Ev` 꼴을 시험 게이트에 쓰면 성공과 실패가 뒤집힌다. 그 꼴은 ralph 의 피드백 명령에만 쓴다.
|
|
@@ -8,14 +8,16 @@
|
|
|
8
8
|
// [--summary <text>] [--reason <text>]
|
|
9
9
|
// node chain-ledger.mjs boxes <run> --file <boxes.mjs report> [--stage <id>] [--round <n>]
|
|
10
10
|
// [--unverified <box,...> --why <text>]
|
|
11
|
+
// node chain-ledger.mjs gates <run> --file <g>/evidence.md --round <k> [--stage <id>]
|
|
12
|
+
// (ralph-qa's gate-evidence.mjs records of iteration <k>; observed only)
|
|
11
13
|
// node chain-ledger.mjs show <run>
|
|
12
14
|
//
|
|
13
15
|
// Exit codes: 0 done, 1 a file could not be read or written (a missing or broken --file included),
|
|
14
16
|
// 2 a usage error or a rejected event.
|
|
15
17
|
import { spawnSync } from "node:child_process";
|
|
16
|
-
import { randomBytes } from "node:crypto";
|
|
18
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
17
19
|
import { appendFileSync, existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
|
|
18
|
-
import { isAbsolute, join, relative, resolve } from "node:path";
|
|
20
|
+
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
19
21
|
import { fileURLToPath } from "node:url";
|
|
20
22
|
|
|
21
23
|
export const STAGES = [
|
|
@@ -354,6 +356,94 @@ export function boxesToTests(report, dir) {
|
|
|
354
356
|
return report.boxes.slice(0, 60).map((b) => boxEntry(isObject(b) ? b : {}, dir));
|
|
355
357
|
}
|
|
356
358
|
|
|
359
|
+
// ── gate-evidence.mjs records ────────────────────────────────────────────────
|
|
360
|
+
|
|
361
|
+
// ralph-qa's gate-evidence.mjs writes one JSON line per gate run into <g>/evidence.md. Only `observed` lines
|
|
362
|
+
// (the runner ran the command and saw its exit) become tests; `reported` lines (what a model said) never do.
|
|
363
|
+
const GATE_STATUS = { pass: "pass", fail: "fail", timeout: "fail", misleading: "unverified" };
|
|
364
|
+
const sha256 = (b) => createHash("sha256").update(b).digest("hex");
|
|
365
|
+
const hostOs = () => (["linux", "darwin", "win32"].includes(process.platform) ? process.platform : "other");
|
|
366
|
+
|
|
367
|
+
function evidenceLines(text) {
|
|
368
|
+
return String(text).split(/\r?\n/).filter((l) => l.trim()).map((l) => {
|
|
369
|
+
try {
|
|
370
|
+
return JSON.parse(l);
|
|
371
|
+
} catch {
|
|
372
|
+
return null;
|
|
373
|
+
}
|
|
374
|
+
}).filter(isObject);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// The last observed record of each gate in iteration `iter`, the baseline records (iteration 0) and how many
|
|
378
|
+
// reported lines that iteration had.
|
|
379
|
+
export function observedOf(text, iter) {
|
|
380
|
+
const recs = evidenceLines(text);
|
|
381
|
+
const last = new Map();
|
|
382
|
+
for (const r of recs) if (r.kind === "observed" && r.iter === iter && typeof r.id === "string") last.set(r.id, r);
|
|
383
|
+
return { records: [...last.values()], base: recs.filter((r) => r.kind === "observed" && r.iter === 0),
|
|
384
|
+
reported: recs.filter((r) => r.kind === "reported" && r.iter === iter).length };
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// The recorded output file as it is now: its text when its sha256 is the recorded one, else why not. Only a file
|
|
388
|
+
// right in the gate folder (the folder of evidence.md, where gate-evidence.mjs writes them), so the shared view never
|
|
389
|
+
// carries a file from elsewhere a record names.
|
|
390
|
+
const inFolder = (p, dir) => {
|
|
391
|
+
try {
|
|
392
|
+
return realpathSync.native(dirname(resolve(p))) === realpathSync.native(dir);
|
|
393
|
+
} catch {
|
|
394
|
+
return false;
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
function outputOf(rec, gateDir) {
|
|
398
|
+
if (!inFolder(String(rec.output), gateDir)) return { why: "출력 파일이 게이트 기록 폴더 밖" };
|
|
399
|
+
try {
|
|
400
|
+
const buf = readFileSync(String(rec.output));
|
|
401
|
+
return sha256(buf) === rec.outputSha256 ? { text: decodeText(buf) } : { why: "출력 파일 sha256 이 기록과 다름" };
|
|
402
|
+
} catch {
|
|
403
|
+
return { why: "출력 파일을 읽지 못함" };
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// A failure the baseline had with the same command and signature (gate-evidence.mjs's own rule).
|
|
408
|
+
const sameAsBaseline = (rec, base) => base.some((b) => b.id === rec.id && b.verdict !== "pass" && b.cmd === rec.cmd
|
|
409
|
+
&& typeof b.signature === "string" && b.signature === rec.signature);
|
|
410
|
+
|
|
411
|
+
export function gateToTest(rec, out, baseline, log) {
|
|
412
|
+
const status = out.why ? "unverified" : GATE_STATUS[rec.verdict] ?? "unverified";
|
|
413
|
+
const ended = rec.timedOut ? "시간 초과" : rec.exit === null || rec.exit === undefined ? `신호 ${rec.signal}` : `종료 ${rec.exit}`;
|
|
414
|
+
const notes = [`${rec.verdict}${rec.why ? `(${rec.why})` : ""}`, `${String(rec.cmd).slice(0, 200)} ${ended}`,
|
|
415
|
+
baseline ? "기준선과 같은 실패" : "", out.why ?? ""].filter(Boolean);
|
|
416
|
+
return { where: `local:${rec.id}`.slice(0, 100), os: hostOs(), status, note: notes.join("; ").slice(0, 500), log };
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
const fenceFor = (text) => "`".repeat(Math.max(3, ...[...text.matchAll(/`+/g)].map((m) => m[0].length + 1)));
|
|
420
|
+
|
|
421
|
+
// The view qa/local-r<k>.md: every record's facts and its output, so the log can be read without the runner.
|
|
422
|
+
function gateView(round, entries) {
|
|
423
|
+
const parts = [`# 로컬 게이트 r${round} (gate-evidence.mjs 의 observed 기록, 반복 ${round})`, ""];
|
|
424
|
+
for (const { rec, out, test } of entries) {
|
|
425
|
+
const body = out.text ?? `(${out.why})`;
|
|
426
|
+
const fence = fenceFor(body);
|
|
427
|
+
parts.push(`## ${rec.id}: ${test.status}`, "", `- ${test.note}`, `- 폴더: ${rec.cwd}`, `- 출력: ${rec.output}`,
|
|
428
|
+
`- 출력 sha256: ${rec.outputSha256}`, `- 작업 트리 지문: ${rec.fingerprint}`, "", fence, body.trimEnd(), fence, "");
|
|
429
|
+
}
|
|
430
|
+
return parts.join("\n");
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// One tests[] entry per gate of iteration `round` from <g>/evidence.md, and the view they link to.
|
|
434
|
+
export function gatesToTests(text, round, dir, gateDir) {
|
|
435
|
+
const { records, base, reported } = observedOf(text, round);
|
|
436
|
+
if (!records.length) throw new UsageError(`반복 ${round} 의 observed 기록이 없습니다(reported ${reported}건은 받지 않음)`);
|
|
437
|
+
const log = `qa/local-r${round}.md`;
|
|
438
|
+
const entries = records.slice(0, 60).map((rec) => {
|
|
439
|
+
const out = outputOf(rec, gateDir);
|
|
440
|
+
return { rec, out, test: gateToTest(rec, out, sameAsBaseline(rec, base), log) };
|
|
441
|
+
});
|
|
442
|
+
mkdirSync(join(dir, "qa"), { recursive: true });
|
|
443
|
+
writeFileSync(join(dir, log), gateView(round, entries));
|
|
444
|
+
return { tests: entries.map((e) => e.test), reported, baseline: entries.filter((e) => e.test.note.includes("기준선과 같은 실패")).length };
|
|
445
|
+
}
|
|
446
|
+
|
|
357
447
|
// ── command line ─────────────────────────────────────────────────────────────
|
|
358
448
|
|
|
359
449
|
const FLAGS = new Set(["--base", "--runtime", "--stage", "--status", "--file", "--round", "--summary", "--reason", "--unverified", "--why"]);
|
|
@@ -455,6 +545,24 @@ const COMMANDS = {
|
|
|
455
545
|
const summary = `박스 ${tests.length}대: 통과 ${count("pass")}, 실패 ${count("fail")}, 미검증 ${count("unverified")}${untracked}`;
|
|
456
546
|
return withProgress(appendEvent(dir, { stage: o.stage ?? "qa", status: "note", summary, tests, ...(o.round ? { round: Number(o.round) } : {}) }));
|
|
457
547
|
},
|
|
548
|
+
gates: (o) => {
|
|
549
|
+
const dir = runDir(o);
|
|
550
|
+
if (!o.file || !o.round) throw new UsageError("--file <gate-evidence 의 evidence.md> 와 --round <k> 가 필요합니다");
|
|
551
|
+
const round = Number(o.round);
|
|
552
|
+
if (!Number.isInteger(round) || round < 1 || round > 99) throw new UsageError("--round 는 1~99 정수입니다");
|
|
553
|
+
let text;
|
|
554
|
+
try {
|
|
555
|
+
text = decodeText(readFileSync(o.file));
|
|
556
|
+
} catch (e) {
|
|
557
|
+
throw new Error(`게이트 기록을 읽지 못했습니다(${o.file}): ${e.message}`);
|
|
558
|
+
}
|
|
559
|
+
const { tests, reported, baseline } = gatesToTests(text, round, dir, dirname(resolve(o.file)));
|
|
560
|
+
const count = (s) => tests.filter((t) => t.status === s).length;
|
|
561
|
+
const summary = `로컬 게이트 ${tests.length}개: 통과 ${count("pass")}, 실패 ${count("fail")}, 미검증 ${count("unverified")}`
|
|
562
|
+
+ `, 기준선과 같은 실패 ${baseline}, 받지 않은 reported ${reported}건`;
|
|
563
|
+
const artifacts = [{ label: `로컬 게이트 r${round}`, path: `qa/local-r${round}.md` }];
|
|
564
|
+
return withProgress(appendEvent(dir, { stage: o.stage ?? "qa", status: "note", round, summary, tests, artifacts }));
|
|
565
|
+
},
|
|
458
566
|
// show is the first command of a resume, so it also re-makes the stage folders an older run may lack.
|
|
459
567
|
show: (o) => {
|
|
460
568
|
const dir = runDir(o);
|
|
@@ -469,7 +577,7 @@ export function main(argv, out = process.stdout, err = process.stderr) {
|
|
|
469
577
|
try {
|
|
470
578
|
const o = parseArgs(argv);
|
|
471
579
|
const run = COMMANDS[o._[0]];
|
|
472
|
-
if (!run) throw new UsageError("명령은 init, event, boxes, show 중 하나입니다");
|
|
580
|
+
if (!run) throw new UsageError("명령은 init, event, boxes, gates, show 중 하나입니다");
|
|
473
581
|
out.write(`${JSON.stringify(run(o), null, 1)}\n`);
|
|
474
582
|
return 0;
|
|
475
583
|
} catch (e) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ultra-init
|
|
3
|
-
description: "아이디어나 대략적인 요구, 새 프로젝트를 한 번의 지시로 받아 계획, 구현, QA 통과까지 자율 실행. `ralplan`, `ralph`,
|
|
4
|
-
argument-hint: "[--short|--deliberate] [--gated] [--qa tests,build,lint,typecheck] [--critic=architect|critic|codex] <브리프 / 만들 것>"
|
|
3
|
+
description: "아이디어나 대략적인 요구, 새 프로젝트를 한 번의 지시로 받아 계획, 구현, QA 통과까지 자율 실행. `ralplan`, `ralph`, 두 런타임 모두 `ralph-qa` 의 독립 QA 게이트를 차례로 씀. 'ultra-init'/'알아서 만들어'/'핸즈오프 빌드'/'idea to passing' 시 사용."
|
|
4
|
+
argument-hint: "[--short|--deliberate] [--gated] [--qa tests,build,lint,typecheck,scenarios] [--critic=architect|critic|codex] <브리프 / 만들 것>"
|
|
5
5
|
level: 4
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -22,7 +22,7 @@ ralplan --deliberate → ralph → QA gate → complete
|
|
|
22
22
|
|
|
23
23
|
**Order note:** the literal request listed `ralplan --deliberate → ralph → ultragoal → ultrawork → ultraqa`. On OMC 5 three of those changed:
|
|
24
24
|
- **No ultrawork step.** OMC 5.0.0 retired `ultrawork` (replacement: `execute` / `team`); ralph delegates its stories to parallel agents itself.
|
|
25
|
-
- **No ultraqa.** OMC 5.0.0 retired it; Phase 3 runs its
|
|
25
|
+
- **No ultraqa.** OMC 5.0.0 retired it; Phase 3 runs banker's `ralph-qa` on both runtimes instead (on Codex too, where OMX still ships its own).
|
|
26
26
|
- **No ultragoal ledger.** OMC 5.6.1's `omc ultragoal checkpoint` records progress only for a goal started with `complete-goals`, and only with a snapshot of the Claude Code `/goal` that goal arms. Arming `/goal` would put a second Stop-hook loop beside ralph's, so ultra-init does not use the ledger. The run stays resumable through the plan file and ralph's PRD (Phase 4). If a durable multi-goal ledger is what the user wants, that is the separate `/oh-my-claudecode:ultragoal` workflow.
|
|
27
27
|
|
|
28
28
|
So the effective order is `ralplan → ralph → QA gate`. This is intentional, not a mistake.
|
|
@@ -39,7 +39,7 @@ So the effective order is `ralplan → ralph → QA gate`. This is intentional,
|
|
|
39
39
|
Several bundled skills are loop/persistence engines. To prevent competing loops, **only ONE loop authority is active at a time, and the phases run strictly sequentially** (a phase fully completes before the next begins):
|
|
40
40
|
|
|
41
41
|
1. In **Phase 2, ralph is the sole loop authority** ("the boulder never stops"). Let its loop run to completion. Do **NOT** arm a Claude Code `/goal` Stop-hook loop beside it.
|
|
42
|
-
2. **The QA gate runs only in Phase 3, AFTER ralph has finished**, as the terminal QA sub-gate — never concurrently with ralph.
|
|
42
|
+
2. **The QA gate runs only in Phase 3, AFTER ralph has finished**, as the terminal QA sub-gate — never concurrently with ralph. banker's `ralph-qa` owns that judge → fix loop on both runtimes; ultra-init owns no loop.
|
|
43
43
|
3. **There is no ultrawork phase.** OMC 5.0.0 retired `ultrawork`; ralph's own parallel delegation covers it inside Phase 2.
|
|
44
44
|
</Loop_Authority_Rules>
|
|
45
45
|
|
|
@@ -48,12 +48,14 @@ Several bundled skills are loop/persistence engines. To prevent competing loops,
|
|
|
48
48
|
### Phase 0 — Preflight (준비)
|
|
49
49
|
- Resolve the brief from the skill arguments. If it is empty, ask once for the brief, then proceed.
|
|
50
50
|
- Parse flags: planning depth (`--deliberate` = default, `--short` = lighter ralplan), `--gated`, `--qa <dims>`, `--critic=...`. An old `--plan-id <id>` (the retired ledger's id) is ignored; say so.
|
|
51
|
-
- **OMC prerequisite (Claude Code: OMC 5 with a matching `omc` CLI)**: this skill orchestrates OMC's `ralplan`/`ralph
|
|
51
|
+
- **OMC prerequisite (Claude Code: OMC 5 with a matching `omc` CLI)**: this skill orchestrates OMC's `ralplan`/`ralph`, then banker's `ralph-qa` as the QA gate. OMC 5's `ralph` runs `omc ralph verify` on its first iteration and stops when the command is missing, and a global `omc` CLI older than the plugin (4.x) lacks it. Judge by the output, not the exit code (given `--help`, a 4.x CLI prints its general help and exits 0; without `--help` an unknown command makes the CLI launch Claude Code, so keep it):
|
|
52
52
|
```bash
|
|
53
53
|
omc ralph verify --help 2>&1 | grep -q 'Usage: omc ralph verify' && echo "omc ok" || echo "omc CLI missing or too old"
|
|
54
54
|
```
|
|
55
55
|
If the check fails, **guide installation or update first** via `/banker:setup` → oh-my-claudecode (or the `setup-omc` skill / `npm install -g oh-my-claude-sisyphus@latest`), then resume once it passes. There is no way around a missing or stale CLI: ralph itself stops without `omc ralph verify`, so do not start Phase 1.
|
|
56
|
-
- **런타임 매핑 (Claude Code ↔ Codex).** `ralplan`·`ralph`·`cancel` 은 Claude Code에선 OMC, **Codex에선 oh-my-codex(OMX)가 제공하는 동명 스킬**이다(Codex는 `omx setup` 전제, 점검은 `omx --version`). OMX 의 `ralph` 는 `omc` CLI 를 쓰지 않으므로 위 `omc` 점검은 Claude Code 에만 해당한다. Phase 3 QA 게이트는 Claude Code(
|
|
56
|
+
- **런타임 매핑 (Claude Code ↔ Codex).** `ralplan`·`ralph`·`cancel` 은 Claude Code에선 OMC, **Codex에선 oh-my-codex(OMX)가 제공하는 동명 스킬**이다(Codex는 `omx setup` 전제, 점검은 `omx --version`). OMX 의 `ralph` 는 `omc` CLI 를 쓰지 않으므로 위 `omc` 점검은 Claude Code 에만 해당한다. Phase 3 QA 게이트는 두 런타임 모두 banker `ralph-qa` 다: Claude Code `Skill("banker:ralph-qa")`, Codex npm 길 `$banker-ralph-qa`, 플러그인 길 `$banker:ralph-qa`. Codex 에는 Skill 도구가 없으니 그 `SKILL.md` 를 읽고 그대로 따른다(npm 길 `<S>/../banker-ralph-qa/SKILL.md`, 플러그인 길 `<S>/../ralph-qa/SKILL.md`, `<S>` 는 이 스킬 폴더). `<RQ>` 는 ralph-qa 의 `references` 폴더다(Claude Code 와 Codex 플러그인 길 `<S>/../ralph-qa/references`, Codex npm 길 `<S>/../banker-ralph-qa/references`). 아래 Phase들의 `Skill("oh-my-claudecode:<name>")` 표기는 Claude Code 기준 — **Codex 런타임에선 OMX의 해당 스킬을 적용**한다.
|
|
57
|
+
- **Codex 의 tmux 밖 실행.** OMX 의 런타임 워크플로(`ralph`, `team` 등)는 OMX tmux 런타임을 요구한다. OMX 의 `AGENTS.md` 는 tmux 밖(Codex App, 일반 `codex`, `codex exec`)이면 그 사실을 알리고 가장 가까운 대체 경로로 계속하라고 정한다(oh-my-codex 0.20.2 `templates/AGENTS.md`). 그래서 tmux 밖이라는 사실만으로는 멈추지 않는다. 그 단계는 이 세션이 그 스킬의 `SKILL.md` 절차를 네이티브 하위 에이전트로 그대로 따르고, 보고에 `<단계>: tmux 밖 대체 실행(OMX 런타임 없음)` 한 줄을 적는다. 종결 낱말은 다른 멈춤 조건과 마지막 ralph-qa 판정으로만 정한다. 대체 실행도 할 수 없으면(하위 에이전트 기능이 꺼짐 등) `STOPPED(omx-runtime-unavailable)` 로 멈추고 tmux 안의 OMX 에서 다시 실행하라고 안내한다.
|
|
58
|
+
- **Codex 의 계획과 상태 경로.** 이 문서의 `.omc/plans/`, `.omc/state/sessions/<id>/prd.json` 은 Claude Code(OMC) 경로다. Codex 에서는 OMX 경로를 쓴다: 계획은 `.omx/plans/`(ralplan 이 쓰는 `prd-*.md`, `test-spec-*.md`), ralph 의 진행 기록은 `.omx/state/<scope>/ralph-progress.json`. Codex 에서 `.omc/` 아래에 계획을 쓰지 않는다.
|
|
57
59
|
|
|
58
60
|
### Phase 1 — PLAN: ralplan --deliberate (합의 계획)
|
|
59
61
|
- Invoke `Skill("oh-my-claudecode:ralplan")` with `--deliberate <brief>` in **non-interactive** mode (so it produces the consensus-approved plan, marks it `pending approval`, and **stops without launching team/ralph itself** — ultra-init controls the hand-off).
|
|
@@ -62,30 +64,32 @@ Several bundled skills are loop/persistence engines. To prevent competing loops,
|
|
|
62
64
|
- Autonomy: treat the consensus-approved plan as approved-for-execution and continue. (`--gated` → pause here for user approval, then continue.)
|
|
63
65
|
|
|
64
66
|
### Before Phase 2 — record what already fails
|
|
65
|
-
-
|
|
66
|
-
-
|
|
67
|
-
-
|
|
67
|
+
- Make the gate folder with `node '<RQ>/gate-evidence.mjs' init --cwd '<repo>'` (its `dir` is the gate folder `<g>`) and run each targeted QA dimension's command once on the unchanged tree, through ralph-qa's runner, as iteration 0: `node '<RQ>/gate-evidence.mjs' run --dir '<g>' --id <dimension> --cmd '<command>' --timeout <seconds> --iter 0 --cwd '<repo>'`. One command per dimension (no `&&` or `;` chains), a `--timeout` on each; `scenarios` has no baseline (its rows test the change).
|
|
68
|
+
- This **pre-change record** (iteration 0 in `<g>/evidence.md`) is the QA gate's baseline: ralph-qa counts a failure with the same command and failure signature as not this change's (`baseline`). It covers checks outside ralph's feedback commands, and on Codex it is the only baseline (OMX `ralph` keeps none). On Codex the runner writes outside the workspace: ask for approval to run it outside the sandbox.
|
|
69
|
+
- Never use `git stash` or `git reset` for this; if the tree already has changes, take the record from a clean copy of HEAD (`git worktree add --detach <tmp> HEAD`, run with `--cwd <tmp>`, then `git worktree remove <tmp>`). A fresh worktree has no installed dependencies (`node_modules`, a venv): link or install them there first, and confirm the commands really ran — a record made only of "command not found" errors is no baseline. The runner writes the folder a command ran in as `<repo>` in the failure signature, so a failure in the copy and the same failure in the repo match.
|
|
70
|
+
- The record lives in `<g>`; if the session may compact or end before Phase 3, put the `<g>` path in the `ready-compact` note. The gate folder lives until Phase 3 has its end word: no cleanup's day rule takes it (ralph-qa's gate folder rule).
|
|
71
|
+
- **Not a git repo** (common for a new project): if `init` (or `run`) stops with `not-a-git-tree` (exit 3, nothing made or run), first check that the folder the stop names (`checked` in its JSON, an absolute path) is the target repo; if not, call it again with `--cwd '<repo>'`. Only when the target really is no git repo: the gates cannot have evidence (the work tree fingerprint sees no change). Take no baseline, and in Phase 3 hand ralph-qa no `--gates`; it then writes `게이트: 선언 없음(git 저장소 아님)` in its report and seat instructions. Never run `git init` yourself: tell the user that `git init` and a first commit make the gates work next time. The same on both runtimes (Claude Code, and Codex on the npm and the plugin route).
|
|
68
72
|
|
|
69
73
|
### Phase 2 — EXECUTE: ralph (영속 실행)
|
|
70
74
|
- Invoke `Skill("oh-my-claudecode:ralph")` and pass **the plan path plus its stories and acceptance criteria** as ralph's input, so ralph's `prd.json` refinement (its Step 1c) adopts the high-quality, task-specific criteria already produced in Phase 1 — skipping generic "Implementation is complete" PRD theater. Thread `--critic=...` through if specified.
|
|
71
75
|
- **No questions mid-run:** ralph 5.6.1 asks the user once for the PRD's `repoQualityClass` (`prototype`, `production` or `library`) when the task does not say. Infer it from repo signals (CI config, test depth, published package metadata) and put it in the handoff; let ralph ask only when the signals genuinely conflict.
|
|
72
|
-
- ralph first records the feedback baseline (`omc ralph verify --write-baseline`: the failures that already existed), then iterates **story-by-story**, delegating to parallel agents where stories allow, until all stories `passes: true`, followed by **reviewer verification → mandatory ai-slop-cleaner deslop → post-deslop regression re-verify**. ralph is the loop authority for this phase. Note its session id (the `<id>` in its PRD path `.omc/state/sessions/<id>/prd.json`) and the baseline failures it reports at its closeout
|
|
76
|
+
- ralph first records the feedback baseline (`omc ralph verify --write-baseline`: the failures that already existed), then iterates **story-by-story**, delegating to parallel agents where stories allow, until all stories `passes: true`, followed by **reviewer verification → mandatory ai-slop-cleaner deslop → post-deslop regression re-verify**. ralph is the loop authority for this phase. Note its session id (the `<id>` in its PRD path `.omc/state/sessions/<id>/prd.json`) for a resume, and the baseline failures it reports at its closeout for the Phase 4 summary.
|
|
73
77
|
- **Feedback commands must print only failures.** OMC 5.6.1's `omc ralph verify` fingerprints every output line and normalizes only `<number><unit>` durations, timestamps, `/tmp` paths and hex ids, so a summary line that changes between runs or when tests are added reads as a NEW failure (node:test's default reporter: `ℹ duration_ms 151.4`, `ℹ tests 8` — red on every run with no change). Have ralph set the PRD `feedbackCommands` before it records the baseline to forms that are constant on success and name each failure (node:test: `FORCE_COLOR=0 NODE_NO_WARNINGS=1 node --test --test-reporter=dot 2>&1 | grep -Ev '^[.X]+$'` — the variables keep color codes from slipping past the filter and process-id warnings out of the output; adapt the form on Windows). If the gate still flags only such lines, fix the commands and re-record ralph's baseline on the current tree (`omc ralph verify --write-baseline`); the pre-change record still tells old failures from new ones. Never edit the baseline file by hand; never stash or reset.
|
|
74
78
|
- Do not interrupt on "The boulder never stops" continuations — that signal means ralph's iteration continues. Let it run to completion.
|
|
75
79
|
|
|
76
|
-
### Phase 3 — QA GATE (QA 순환)
|
|
77
|
-
- After ralph completes,
|
|
78
|
-
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
-
|
|
80
|
+
### Phase 3 — QA GATE: banker ralph-qa (QA 순환)
|
|
81
|
+
- After ralph completes, invoke ralph-qa once with `--gates=<dimensions> --lens=both`: every dimension the project supports (default `typecheck,lint,build,tests`, or the `--qa` list; `scenarios` adds adversarial scenario rows). One run covers every dimension: its gate conjunct holds only when each one does.
|
|
82
|
+
- Hand it the plan path with its stories and acceptance criteria, the change since `HEAD` as Phase 2 began, the gate folder `<g>` with its iteration-0 baseline (ralph-qa uses it, runs no iteration 0 of its own and does not remove it), and each dimension's one command and timeout. Add the acceptance criterion "each dimension's real command ran through the runner (`gate-evidence.mjs run`) on the tree being judged, as an `observed` record"; a model's account of a command (`reported`) is not evidence. `<g>` holds the gate records only: ralph-qa sends any external-seat payload from a folder of its own.
|
|
83
|
+
- With `scenarios`: ralph-qa's nine adversarial classes (malformed input, repeated interruption, prompt injection, cancel and resume, stale state, dirty work tree, hung command, flaky test, misleading success output) each get a scenario row run as `scenario-<n>`, or a one-line reason it does not apply.
|
|
84
|
+
- Never fix a baseline failure here; report it apart. A baseline failure whose failing lines point at a file the change touched counts as new, as in ralph: the seats raise it as a blocker.
|
|
85
|
+
- If `<g>` is gone (the runner stops with `not-a-run-folder`: a logout or reboot emptied `$XDG_RUNTIME_DIR`, or it was removed): make a new one with `gate-evidence.mjs init` and hand that, with no iteration 0. Never run iteration 0 on the changed tree. Failures that were there before then count as this change's: put the line `gate baseline: none (<g> was gone)` in the summary, with ralph's closeout baseline list beside it.
|
|
86
|
+
- ralph-qa owns the loop: its seats judge, the author fixes, it runs the gates again and the same seats judge again, up to its `--max` (5). ultra-init adds no cycle. Read its end word (the word before any parenthesis): `APPROVE` is green; `ITERATE` (its `--max` spent; `원인 gate` when only the gates held it) or `INCONCLUSIVE` is a stop: report its verdict line, gate block and blockers left. Afterwards run `node '<RQ>/gate-evidence.mjs' cleanup --dir '<g>'` (a `<g>` named `ralph-qa.*`, made before this version, goes with `node '<RQ>/seat-run.mjs' cleanup --dir '<g>'`).
|
|
83
87
|
- This is a belt-and-suspenders gate over ralph's own regression: a final all-green check under ultra-init's authority (ralph has already finished, so there is no competing loop).
|
|
84
88
|
|
|
85
89
|
### Phase 4 — COMPLETE (완료 / 정리)
|
|
86
90
|
- `Skill("oh-my-claudecode:cancel")` → clear ralph / mode state cleanly (don't leave stale state files).
|
|
87
|
-
- Emit a **concise, evidence-backed summary**: what was planned (plan path), stories delivered, files touched, reviewer verdict, deslop result,
|
|
88
|
-
- **Resuming an interrupted run:** the plan file in `.omc/plans/` and ralph's PRD (`.omc/state/sessions/<id>/prd.json`, with its stories' `passes` flags) are the durable record. Hand both to a new `ralph` run; for a new session, prepare it with `ready-compact --hand-off`, which must also carry the pre-change record and the first ralph session id. On resume,
|
|
91
|
+
- Emit a **concise, evidence-backed summary**: what was planned (plan path), stories delivered, files touched, reviewer verdict, deslop result, ralph-qa's verdict line with its gate block (per dimension), and the baseline failures that predate the change (the `baseline` gates and ralph's closeout list), listed apart.
|
|
92
|
+
- **Resuming an interrupted run:** the plan file in `.omc/plans/` and ralph's PRD (`.omc/state/sessions/<id>/prd.json`, with its stories' `passes` flags) are the durable record. Hand both to a new `ralph` run; for a new session, prepare it with `ready-compact --hand-off`, which must also carry the `<g>` path (the pre-change record) and the first ralph session id. On resume, Phase 3 judges against the iteration-0 records in `<g>`; never run iteration 0 again on the half-changed tree, and do not judge by the baseline a new ralph records there: either would excuse regressions made before the interruption. The same goes for a resume in the same session.
|
|
89
93
|
|
|
90
94
|
<Stop_Conditions>
|
|
91
95
|
Even in autonomous mode, STOP and report when:
|
|
@@ -94,6 +98,9 @@ Even in autonomous mode, STOP and report when:
|
|
|
94
98
|
- The `omc` CLI check in Phase 0 fails and the user does not update it — ralph cannot run.
|
|
95
99
|
- The same failure recurs **3×** across iterations — surface it as a potential fundamental problem (mirrors the early exit of ralph and the QA gate).
|
|
96
100
|
- ralplan cannot reach consensus within 5 iterations → present the best plan and ask whether to proceed.
|
|
101
|
+
- Phase 3's ralph-qa ends `ITERATE` (its `--max` spent) or `INCONCLUSIVE` → report its verdict line and blockers; do not claim the gate passed.
|
|
102
|
+
|
|
103
|
+
After STOPPED, change no file, not even a one-line fix: report only, until the user gives a new instruction. Nothing in this skill (its description's "one-line fix" pointer included) authorizes an edit after a stop.
|
|
97
104
|
|
|
98
105
|
Otherwise: do not stop, and do not ask for permission between phases.
|
|
99
106
|
</Stop_Conditions>
|
|
@@ -102,12 +109,13 @@ Otherwise: do not stop, and do not ask for permission between phases.
|
|
|
102
109
|
- [ ] Phase 0: on Claude Code the `omc` CLI answered `omc ralph verify --help` with its usage (Codex: `omx --version`)
|
|
103
110
|
- [ ] Phase 1: consensus-approved plan in `.omc/plans/` with ADR, ordered stories, testable acceptance criteria, and an expanded test plan (deliberate)
|
|
104
111
|
- [ ] Phase 2: every ralph story `passes: true`; reviewer verification passed; ai-slop-cleaner deslop done; post-deslop regression green
|
|
105
|
-
- [ ] Phase
|
|
112
|
+
- [ ] Before Phase 2: each targeted dimension but `scenarios` ran once through `gate-evidence.mjs run --iter 0` on the unchanged tree
|
|
113
|
+
- [ ] Phase 3: ralph-qa (`--gates=<dimensions>`) ended `APPROVE` on `observed` gate records for every targeted dimension (typecheck / lint / build / tests, and scenarios when asked); baseline failures reported apart, not fixed
|
|
106
114
|
- [ ] Phase 4: mode state cancelled & cleaned; summary names the plan path
|
|
107
115
|
- [ ] Final summary emitted with fresh evidence (no "should" / "looks good" claims — show actual command output)
|
|
108
116
|
</Final_Checklist>
|
|
109
117
|
|
|
110
118
|
## Notes
|
|
111
|
-
- **Thin-orchestrator rule:** always invoke the real skills/CLI; never duplicate their internals here
|
|
112
|
-
- **Overrides recap:** `--short` (lighter ralplan), `--gated` (approval pause after planning), `--qa tests,build` (
|
|
119
|
+
- **Thin-orchestrator rule:** always invoke the real skills/CLI; never duplicate their internals here. Identifier reference: `ralplan`, `ralph`, `cancel` are **skills** → `Skill("oh-my-claudecode:<name>")`, and banker's `ralph-qa` → `Skill("banker:ralph-qa")`; `architect`, `critic`, `executor`, `verifier`, `qa-tester` are **agents** → `Task(subagent_type="oh-my-claudecode:<name>", ...)`. If an `oh-my-claudecode:<name>` Skill call ever errors with "Agent type not found", you used `Task` for a skill — retry via the `Skill` tool (do not substitute a similarly-named agent).
|
|
120
|
+
- **Overrides recap:** `--short` (lighter ralplan), `--gated` (approval pause after planning), `--qa tests,build` (the ralph-qa `--gates` list; add `scenarios` for adversarial rows), `--critic=architect|critic|codex` (ralph reviewer). `--plan-id` went away with the ledger step.
|
|
113
121
|
- **Relationship to autopilot:** ultra-init is autopilot-shaped, but adds explicit **deliberate** consensus planning up front and an explicit **terminal QA gate**. If the user wants the stock autonomous pipeline instead, that's `autopilot`; for a durable multi-goal ledger across sessions, `ultragoal`.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# NOTICE - 출처 (ultraqa)
|
|
2
|
+
|
|
3
|
+
이 스킬은 oh-my-codex 의 `ultraqa` 스킬을 본떴다.
|
|
4
|
+
|
|
5
|
+
| 항목 | 내용 |
|
|
6
|
+
|---|---|
|
|
7
|
+
| 원본 | oh-my-codex 0.20.2 의 `skills/ultraqa/SKILL.md` |
|
|
8
|
+
| 저장소 | https://github.com/Yeachan-Heo/oh-my-codex |
|
|
9
|
+
| 저작자 | Yeachan Heo |
|
|
10
|
+
| 라이선스 | MIT |
|
|
11
|
+
| 재사용 범위 | 구조(목표 6종, 9분류 시나리오 행렬, 순환 5회, 안전 경계, 종료 5종, 보고서 꼴)를 각색. 문장은 banker 문체로 새로 씀. 코드는 가져오지 않음 |
|
|
12
|
+
| 바꾼 것 | OMX 전용 수단(`/prompts:*`, `omx state`, `/cancel`)을 Claude Code 의 `Plan` 에이전트, 세션 자신, tmux 직접 구동, 실행 폴더로 바꿈. 종료 코드는 실행기(`references/gate-evidence.mjs`)가 관측한 것만 증거로 씀. COMPLETE 는 `references/uqa-run.mjs status` 가 허용할 때만 |
|
|
13
|
+
|
|
14
|
+
## MIT License
|
|
15
|
+
|
|
16
|
+
Copyright (c) Yeachan Heo
|
|
17
|
+
|
|
18
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
19
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
20
|
+
in the Software without restriction, including without limitation the rights
|
|
21
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
22
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
23
|
+
furnished to do so, subject to the following conditions:
|
|
24
|
+
|
|
25
|
+
The above copyright notice and this permission notice shall be included in all
|
|
26
|
+
copies or substantial portions of the Software.
|
|
27
|
+
|
|
28
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
29
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
30
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
31
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
32
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
33
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
34
|
+
SOFTWARE.
|