diff --git a/.codexclaw/goalplans/opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr/goalplan.json b/.codexclaw/goalplans/opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr/goalplan.json deleted file mode 100644 index 937dba65c..000000000 --- a/.codexclaw/goalplans/opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr/goalplan.json +++ /dev/null @@ -1,356 +0,0 @@ -{ - "objective": "opencodex 저장소 거버넌스 및 기여 정책 4건을 PABCD 다중 work-phase 루프로 처리한다. WP1 문서화 우선 사이클, WP2 dev2-go 기반 PR 및 포팅/리베이스 PR 허용 정책, WP3 대상 PR 두 개로 분할, WP4 Wibias 메인테이너 추가. 검증은 실제 파일과 명령 출력으로만. 서브에이전트는 gpt-5.6-terra medium 일반 티어 활용.", - "slug": "opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr", - "createdAt": "2026-07-27T00:41:29.352Z", - "updatedAt": "2026-07-27T04:58:54.547Z", - "activeWorkPhaseId": "wp8", - "workPhases": [ - { - "id": "wp1", - "title": "docs-only 로드맵 사이클: devlog/_plan/260727_governance_intake/ 000/010/020/030 작성", - "status": "done", - "tasks": [ - { - "id": "wp1-t1", - "title": "000 현황 조사: MAINTAINERS.md/CODEOWNERS/AGENTS.md/CONTRIBUTING 및 브랜치 실측", - "status": "done" - }, - { - "id": "wp1-t2", - "title": "010 dev2-go 기반 PR + 포팅/리베이스 PR 허용 정책 diff-level 안", - "status": "done" - }, - { - "id": "wp1-t3", - "title": "020 대상 PR 분할 안 (어떤 PR을 어떤 경계로 두 개로)", - "status": "done" - }, - { - "id": "wp1-t4", - "title": "030 Wibias 메인테이너 추가 diff-level 안", - "status": "done" - } - ], - "criteriaIds": [ - "c1" - ] - }, - { - "id": "wp2", - "title": "브랜치 정책 문서화 (문서 전용): dev2-go 통합선 + 포팅/리베이스 PR 환영", - "status": "done", - "tasks": [ - { - "id": "wp2-t1", - "title": "AGENTS.md Branch policy + Review guidelines", - "status": "done" - }, - { - "id": "wp2-t2", - "title": "CONTRIBUTING.md Branches 절", - "status": "done" - }, - { - "id": "wp2-t3", - "title": "MAINTAINERS.md 리뷰/머지 정책", - "status": "done" - } - ], - "criteriaIds": [ - "c2" - ] - }, - { - "id": "wp4", - "title": "Wibias 메인테이너 추가 (MAINTAINERS.md + CODEOWNERS)", - "status": "done", - "tasks": [ - { - "id": "wp4-t1", - "title": "MAINTAINERS.md Current maintainers 표에 @Wibias 추가", - "status": "done" - }, - { - "id": "wp4-t2", - "title": ".github/CODEOWNERS 기본 리뷰어 및 보안 경로 갱신", - "status": "done" - }, - { - "id": "wp4-t3", - "title": "Maintainer changes 절차 이행 기록", - "status": "done" - } - ], - "criteriaIds": [ - "c4" - ] - }, - { - "id": "wp3", - "title": "대상 PR 두 개로 분할 (WP4 이후 — 분할 대상 #518은 Wibias 소유이므로 메인테이너 지위가 선행)", - "status": "done", - "tasks": [ - { - "id": "wp3-t1", - "title": "020 문서가 지정한 분할 대상 및 경계 확정", - "status": "done" - }, - { - "id": "wp3-t2", - "title": "분할 브랜치 생성 및 커밋 분리", - "status": "done" - }, - { - "id": "wp3-t3", - "title": "typecheck + 관련 테스트 통과 확인", - "status": "done" - } - ], - "criteriaIds": [ - "c3" - ] - }, - { - "id": "wp5", - "title": "PR 타깃 게이트 재설계 (enforce-pr-target.yml) — 사용자 승인 완료, allow-list 방식 채택", - "status": "done", - "tasks": [ - { - "id": "wp5-t1", - "title": "040 문서에 승인 결과와 채택안(c: allow-list) 확정 기록", - "status": "done" - }, - { - "id": "wp5-t2", - "title": "enforce-pr-target.yml: EXPECTED_BASE -> ALLOWED_BASES allow-list", - "status": "done" - }, - { - "id": "wp5-t3", - "title": "tests/ci-workflows.test.ts: dev2-go 통과 / 그 외 차단 / 복원 시나리오", - "status": "done" - }, - { - "id": "wp5-t4", - "title": "AGENTS.md/CONTRIBUTING.md/MAINTAINERS.md 서술을 실제 동작에 동기화", - "status": "done" - }, - { - "id": "wp5-t5", - "title": "독립 감사 + 변이 회귀 재실행 (신규 allow-list 우회 변이 포함)", - "status": "pending" - }, - { - "id": "wp5-t6", - "title": "CI 트리거 갭 해소: ci.yml/service-lifecycle.yml pull_request에 dev2-go 추가 + 드리프트 테스트", - "status": "done" - } - ], - "criteriaIds": [ - "c5" - ] - }, - { - "id": "wp6", - "title": "enforce-pr-target.yml 특성화 테스트 — 현재 동작을 고정 (승인 불필요)", - "status": "done", - "tasks": [ - { - "id": "wp6-t1", - "title": "현재 워크플로 계약을 tests/ci-workflows.test.ts에 고정", - "status": "done" - }, - { - "id": "wp6-t2", - "title": "050에서 관측한 상태 마커 정합성 결함을 테스트로 표현", - "status": "done" - }, - { - "id": "wp6-t3", - "title": "bun test tests/ci-workflows.test.ts 통과 확인", - "status": "done" - } - ], - "criteriaIds": [ - "c6" - ] - }, - { - "id": "wp7", - "title": "특성화 테스트 하드닝 — 감사 2/3라운드가 찾은 우회 봉쇄 (wp6 조기 종료 후속)", - "status": "done", - "tasks": [ - { - "id": "wp7-t1", - "title": "감사 2라운드가 찾은 6가지 우회 봉쇄 (잡 인벤토리/잡 권한/스텝 수/블록 주석/복원 분기/pull_number 바인딩)", - "status": "done" - }, - { - "id": "wp7-t2", - "title": "알려진 변이 10종 재주입 검증, 워크플로 원복 확인", - "status": "done" - }, - { - "id": "wp7-t3", - "title": "감사 3라운드 (독립 서브에이전트, 새 각도)", - "status": "done" - }, - { - "id": "wp7-t4", - "title": "3라운드 지적 반영 후 커밋 및 dev 푸시", - "status": "done" - }, - { - "id": "wp7-t5", - "title": "감사 3라운드 FAIL(14건) → 부정 목록을 허용 목록으로 반전", - "status": "done" - }, - { - "id": "wp7-t6", - "title": "감사 4라운드 FAIL(12건, 전부 스크립트 내부) → 실행 하네스 도입", - "status": "done" - }, - { - "id": "wp7-t7", - "title": "감사 5라운드 FAIL(6건, 하네스 충실도) → 하네스를 실제 러너에 맞춤 + 시나리오 3개", - "status": "done" - }, - { - "id": "wp7-t8", - "title": "감사 6~10라운드 대응 (하네스 충실도 + 계약 어설션)", - "status": "done" - }, - { - "id": "wp7-t9", - "title": "감사 11~14라운드 대응 (트리거 모양, 도달 가능 상태, 버전 스큐, 스키마 truthiness 계약)", - "status": "done" - } - ], - "criteriaIds": [ - "c7" - ] - }, - { - "id": "wp8", - "title": "게이트를 main으로 승격 (fast-forward) — pull_request_target은 기본 브랜치 워크플로를 실행하므로 이것 없이는 발효되지 않음", - "status": "deferred", - "tasks": [ - { - "id": "wp8-t1", - "title": "dev HEAD b4a9fe5c 호스팅 CI success 확인 (Cross-platform CI + Service lifecycle)", - "status": "deferred" - }, - { - "id": "wp8-t2", - "title": "main..dev 98커밋 범위에 릴리스 파이프라인/보안 리뷰 대상 변경이 있는지 확인", - "status": "deferred" - }, - { - "id": "wp8-t3", - "title": "git push origin b4a9fe5c:main (fast-forward, 로컬 체크아웃은 dev 유지)", - "status": "deferred" - }, - { - "id": "wp8-t4", - "title": "승격 후 원격 main의 enforce-pr-target.yml에 ALLOWED_BASES 존재 확인 + c5 met 기록", - "status": "deferred" - } - ], - "criteriaIds": [], - "note": "사용자가 세션 범위를 dev로 좁힘(\"일단 dev에서만 처리해\"). 사전 감사도 DO NOT PROMOTE 판정: 승격 범위가 게이트 한정이 아니라 main..dev 98커밋/9172줄이고, main 푸시는 deploy-docs(실제 Pages 배포)를 트리거한다. 메인테이너의 명시적 수용이 선행 조건. 계획서: devlog/_plan/260727_governance_intake/070_main_promotion.md", - "blocker": "EXTERNAL: main 승격은 (a) 사용자가 이번 세션 범위에서 제외했고(\"일단 dev에서만 처리해\"), (b) 사전 감사가 DO NOT PROMOTE 판정을 냈다 — 승격 범위가 게이트 한정이 아니라 main..dev 98커밋/9172줄이며 main 푸시는 deploy-docs(실제 GitHub Pages 배포)를 트리거하므로 메인테이너의 명시적 수용이 선행 조건이다. 에이전트 권한으로 해소할 수 없다." - }, - { - "id": "wp9", - "title": "ocx account 인증 코드를 셸 인자에서 stdin으로 (WP8 사전 감사 High 지적)", - "status": "done", - "tasks": [ - { - "id": "wp9-t1", - "title": "stdin 읽기 헬퍼 + 주입 가능한 deps (runtime-api.ts)", - "status": "done" - }, - { - "id": "wp9-t2", - "title": "account code 위치 인자 / login --code를 선택으로, 기본 stdin, '-'는 명시적 stdin", - "status": "done" - }, - { - "id": "wp9-t3", - "title": "인자 사용 시 stderr 경고 (값은 절대 에코 금지)", - "status": "done" - }, - { - "id": "wp9-t4", - "title": "tests/cli-account.test.ts 회귀 + 독립 감사", - "status": "done" - } - ], - "criteriaIds": [] - } - ], - "criteria": [ - { - "id": "c1", - "scenario": "WP1 docs-only 사이클이 끝나면 devlog/_plan/260727_governance_intake/ 아래 000/010/020/030 문서가 존재하고 각각 변경 파일 경로와 정확한 문구를 담는다. 프로덕션 코드 변경은 0건이다.", - "expectedEvidence": "ls devlog/_plan/260727_governance_intake/ 출력 + git show --stat 으로 src/ 변경 0건 확인", - "capturedEvidence": "ls devlog/_plan/260727_governance_intake/ → 000_survey.md, 010_branch_policy.md, 011_audit_round1.md, 012_audit_round2.md, 013_audit_round3_and_scope_split.md, 020_pr_split.md, 030_maintainer_wibias.md, 040_pr_target_gate.md (8개). git diff --name-only edf3b2c6..HEAD | rg -v '^devlog/' | wc -l → 0 (프로덕션 코드 변경 0건). 커밋 f43ead8c..e0d600f3 (9개). 독립 감사 6회: 1~5차 FAIL, 6차 NEAR-PASS.", - "status": "met" - }, - { - "id": "c2", - "scenario": "AGENTS.md/CONTRIBUTING.md/MAINTAINERS.md 세 파일 모두에서 dev2-go가 정식 통합선으로 문서화되고, 포팅/리베이스 PR이 환영 대상으로 명시되며, 현재 자동화가 dev2-go PR에 [WRONG BRANCH]를 붙인다는 사실이 숨겨지지 않고 적힌다. .github/ 변경은 0건이다.", - "expectedEvidence": "rg -n 'dev2-go' 세 파일 + rg -n -i 'porting|rebase' + rg -n 'WRONG BRANCH' + git diff --name-only에 .github/ 없음", - "capturedEvidence": "rg -c dev2-go AGENTS.md/CONTRIBUTING.md/MAINTAINERS.md → 2/1/2. rg -c -i \"porting|rebase\" AGENTS.md CONTRIBUTING.md → 1/1. rg -c \"WRONG BRANCH\" → 2/1/1 (세 파일 모두 현 자동화 동작 명시). git diff --name-only | rg \"^\\.github/\" → 0건 (워크플로 미변경). docs-site 5개 로케일(en/ko/ja/ru/zh-cn) 각 dev2-go 1건. 커밋 a37cc55b, e4062e32. 독립 감사 2라운드 VERDICT: PASS.", - "status": "met" - }, - { - "id": "c3", - "scenario": "지정된 PR이 두 개의 독립적인 변경으로 분리되고, 각각 bun run typecheck 통과 및 관련 테스트 통과가 증명된다.", - "expectedEvidence": "git log --oneline 분리 브랜치 + bun run typecheck exit 0 + bun test 관련 파일 결과", - "capturedEvidence": "SRC=d93b46932b58b963ea5dfa27dee5c63f3a7b0f2a 고정. B(codex/catalog-written-signal, PR #526): typecheck exit 0, 22 pass 0 fail, 6파일. A(codex/app-server-restart, PR #527): typecheck exit 0, 22 pass 1 skip 0 fail, 15파일. 합집합 검증 diff pr518-manifest split-union → IDENTICAL (21파일). SRC 불변 재확인. 계획 경계 가정 3회 실측 정정: config-routes.ts, gui i18n syncStaleHint, codex-models-cache-invalidate.test.ts 전부 A 소속.", - "status": "met" - }, - { - "id": "c4", - "scenario": "MAINTAINERS.md의 Current maintainers 표에 @Wibias 행이 있고 .github/CODEOWNERS의 기본 리뷰어에 @Wibias가 포함되며, Maintainer changes 절차 이행이 기록된다.", - "expectedEvidence": "rg -n 'Wibias' MAINTAINERS.md .github/CODEOWNERS 출력", - "capturedEvidence": "rg -c Wibias MAINTAINERS.md → 2 (표 행 + change log). rg -c Wibias .github/CODEOWNERS → 1 (기본 리뷰어 * 규칙만). 보안 경로 미포함 검증 → 0건. MAINTAINERS.md 표 3행. 감사 확인: CODEOWNERS 마지막 매칭 우선 규칙으로 @Wibias는 /src/oauth/, /.github/, /scripts/release.ts, /MAINTAINERS.md, /SECURITY.md, /package.json, /bun.lock의 코드오너가 아님(GitHub API errors:[]). 커밋 01e831d0, 71e43d9c, 491373f3.", - "status": "met" - }, - { - "id": "c5", - "scenario": "enforce-pr-target.yml이 dev2-go PR을 정당하게 통과시키고, 그 외 타깃은 차단·복원 경로가 회귀 테스트로 덮이며, PR을 받는 브랜치는 CI 트리거도 함께 받는다. actor 검증 + head SHA 바인딩은 040 문서의 근거 셋에 따라 채택하지 않았다 (강제력 없는 자동 판정 대신 리뷰가 잡는다). main 승격으로 실제 발효된다.", - "expectedEvidence": "워크플로 diff + 신규 테스트 통과 출력 + main 승격 확인", - "capturedEvidence": "커밋: d761e880 (ALLOWED_BASES allow-list, 워크플로 5지점) / 10b1d2aa (문서 8종, 5개 로케일 포함) / 5229717b (ci.yml+service-lifecycle.yml PR 트리거에 dev2-go) / 76c25710 (하네스 node24 충실도 + 트리거 키집합 고정 + live base 코멘트 어설션) / 2b03e908 (ci.yml paths 양쪽 트리거 정확 집합 고정) / 99679376 (040 문서에 15~17라운드 기록). 검증: bun x tsc --noEmit exit 0; bun run test 4945 pass / 0 fail / 24352 expect(); bun test tests/ci-workflows.test.ts 52 pass / 0 fail / 548 expect(). 변이 회귀: mut16 12/12, mut17 5/5, mut18 5/5 (봉쇄 전 5종 전부 SURVIVED), mut20 8/8 (봉쇄 전 4종 SURVIVED) 전부 CAUGHT. 독립 감사 3라운드: 15=FAIL(5건) -> 76c25710, 16=FAIL(1건) -> 2b03e908, 17=PASS (12/12 CAUGHT, 무해 생존 2건 근거 기록). 미충족 잔여: main 승격 (승인 완료, 다음 work-phase). [세션 종료 시점] dev 쪽 조건은 전부 충족(워크플로 diff + ci-workflows 테스트 통과 + 변이 회귀 전건 CAUGHT). 남은 조건인 'main 승격으로 발효'만 미충족이며, 이는 사용자가 이번 세션 범위에서 제외했다. origin/main은 origin/dev의 조상이라 fast-forward 가능한 상태로 남아 있다.", - "status": "deferred", - "blocker": "EXTERNAL: 'main 승격으로 발효' 조건만 미충족. 승격 권한/수용은 메인테이너 결정이며 사용자가 범위에서 제외했다." - }, - { - "id": "c6", - "scenario": "tests/ci-workflows.test.ts에 enforce-pr-target.yml 테스트가 존재하고, 현재 동작(pull_request_target 트리거 집합, EXPECTED_BASE, 제목 prefix, draft 전환, checkout/PR코드실행 없음, 최소 권한)을 고정한다. WP5에서 게이트를 바꿀 때 이 테스트가 회귀 그물이 된다.", - "expectedEvidence": "bun test tests/ci-workflows.test.ts 통과 출력 + rg enforce-pr-target tests/ci-workflows.test.ts", - "capturedEvidence": "tests/ci-workflows.test.ts에 PR target enforcement 테스트 3개(rg -c → 3). bun test → 14 pass 0 fail 282 expect(). bun run typecheck exit 0. 4라운드 적대적 변이 감사: 1차 FAIL(문자열 매칭 구멍 3), 2차 FAIL(YAML 문법 우회 5), 3차 FAIL(함수 shadow), 4차 PASS. 최종적으로 Bun.YAML 파싱 + quote-aware 주석 제거 + 함수 선언 개수/mutation 결속. 통과하는 변이는 전부 고의적 무력화만 남음.", - "status": "met" - }, - { - "id": "c7", - "scenario": "enforce-pr-target.yml 특성화 테스트가 알려진 모든 우회 변이를 잡는다", - "expectedEvidence": "변이 주입 스크립트 출력에서 알려진 변이 전부 CAUGHT, survived=none. 기준선 bun test 통과, bun run typecheck 오류 0. 독립 감사(gpt-5.6-terra) verdict PASS 또는 NEAR-PASS.", - "capturedEvidence": "변이 회귀 12개 스크립트 131종 전수: 알려진 무해 6종(context-eventname, core-tostring, promise-identity, err-tostringtag, response-headers, comment-after-write)과 들여쓰기 no-op 2종 외 전부 CAUGHT, git status --short .github/ clean. 기준선 bun test tests/ci-workflows.test.ts -> 44 pass / 0 fail / 485 expect(). bun run test -> 4937 pass / 0 fail / 24289 expect() exit 0. bun x tsc --noEmit exit 0. 독립 감사(gpt-5.6-terra, agent 019fa18f) 14라운드 verdict NEAR-PASS, 잔여 지적 1건은 dbd558e1로 봉쇄 후 CAUGHT 확인.", - "status": "met" - }, - { - "id": "c9", - "scenario": "ocx account login/code가 인증 코드를 셸 히스토리와 프로세스 목록에 남기지 않는 경로를 기본으로 제공하고, 인자 경로를 쓰면 값을 노출하지 않는 경고가 나온다.", - "expectedEvidence": "테스트 통과 출력 + 인자 경고 어설션 + 값 미노출 어설션", - "capturedEvidence": "구현: d4dfa24e(stdin 기본 경로), e7f5bef5(공백 문법 redact + 중복 --code 거부), d3dc9d79(미지 플래그를 코드로 먹지 않음), f10c5060(비밀 옵션 뒤 토큰은 모양 무관 은닉, -- 구분자 건너뜀, account code 잔여 위치 인자 은닉, 종료된 stdin 즉시 실패), 1de43286(CR/LF 줄바꿈 고정). 검증: bun run test 4965 pass / 0 fail / 24429 expect(); bun x tsc --noEmit exit 0; bun test tests/cli-account.test.ts 62 pass / 0 fail / 276 expect(). 변이: mut23 10/10 CAUGHT, mut21 9/9 CAUGHT, mut22 4/4 CAUGHT. 독립 감사 2라운드: R2 FAIL(High 2 + Medium 1 + Low 1, 전부 프로브로 실측 재현) → 수정 → R3 VERDICT: PASS. 잔여: `--code --nope`는 --nope를 값으로 간주해 은닉(사용 오류 메시지는 --code를 여전히 지목) — 진단성보다 노출 차단 우선.", - "status": "met" - } - ], - "host": { - "armed": false, - "armedAt": null, - "source": "none" - } -} \ No newline at end of file diff --git a/.codexclaw/goalplans/opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr/ledger.jsonl b/.codexclaw/goalplans/opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr/ledger.jsonl deleted file mode 100644 index 4cabb8387..000000000 --- a/.codexclaw/goalplans/opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr/ledger.jsonl +++ /dev/null @@ -1,21 +0,0 @@ -{"ts":"2026-07-27T00:41:29.353Z","slug":"opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr","event":"created","detail":"init objective=\"opencodex 저장소 거버넌스 및 기여 정책 4건을 PABCD 다중 work-phase 루프로 처리한다. WP1 문서화 우선 사이클, WP2 dev2-go 기반 PR 및 포팅/리베이스 PR 허용 정책, WP3 대상 PR 두 개로 분할, WP4 Wibias 메인테이너 추가. 검증은 실제 파일과 명령 출력으로만. 서브에이전트는 gpt-5.6-terra medium 일반 티어 활용.\" criteria=0"} -{"ts":"2026-07-27T01:18:20.834Z","slug":"opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr","event":"workphase_done","detail":"closed wp1"} -{"ts":"2026-07-27T01:18:20.834Z","slug":"opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr","event":"workphase_started","detail":"started wp2"} -{"ts":"2026-07-27T01:26:02.696Z","slug":"opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr","event":"workphase_done","detail":"closed wp2"} -{"ts":"2026-07-27T01:26:02.696Z","slug":"opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr","event":"workphase_started","detail":"started wp4"} -{"ts":"2026-07-27T01:32:20.967Z","slug":"opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr","event":"workphase_done","detail":"closed wp4"} -{"ts":"2026-07-27T01:32:20.967Z","slug":"opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr","event":"workphase_started","detail":"started wp3"} -{"ts":"2026-07-27T01:45:55.340Z","slug":"opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr","event":"workphase_done","detail":"closed wp3"} -{"ts":"2026-07-27T01:45:55.340Z","slug":"opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr","event":"workphase_started","detail":"started wp5"} -{"ts":"2026-07-27T02:09:28.671Z","slug":"opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr","event":"workphase_done","detail":"closed wp6"} -{"ts":"2026-07-27T02:09:28.671Z","slug":"opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr","event":"workphase_started","detail":"started wp5"} -{"ts": "2026-07-27T02:12:28.095252Z", "slug": "opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr", "event": "workphase_started", "detail": "started wp7 (P-phase amendment: wp6 closed before the round-2 audit returned FAIL; hardening is the next unit, LOOP-UNIT-CHAIN-01)"} -{"ts":"2026-07-27T02:14:19.004Z","slug":"opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr","event":"workphase_done","detail":"closed wp7"} -{"ts":"2026-07-27T02:14:19.004Z","slug":"opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr","event":"workphase_started","detail":"started wp5"} -{"ts":"2026-07-27T03:11:25Z","slug":"opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr","event":"workphase_started","detail":"re-activated wp7: rounds 7-10 hardening was the unit actually worked; wp5 remains blocked on user approval and was parked back to pending"} -{"ts":"2026-07-27T03:39:57.830Z","slug":"opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr","event":"workphase_done","detail":"closed wp7"} -{"ts":"2026-07-27T03:39:57.830Z","slug":"opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr","event":"workphase_started","detail":"started wp5"} -{"ts":"2026-07-27T03:40:13Z","event":"work-phase-complete","workPhaseId":"wp7","criterion":"c7","status":"met","evidence":"rounds 11-14 audited; 131 mutation variants CAUGHT except 6 proven-harmless; suite 4937 pass/0 fail; typecheck 0; commits 5f7afc21, dbd558e1"} -{"ts":"2026-07-27T04:17:39.364Z","slug":"opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr","event":"workphase_done","detail":"closed wp5"} -{"ts":"2026-07-27T04:58:54.547Z","slug":"opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr","event":"workphase_done","detail":"closed wp9"} -{"ts":"2026-07-27T04:58:54.547Z","slug":"opencodex-4-pabcd-work-phase-wp1-wp2-dev2-go-pr","event":"workphase_started","detail":"started wp8"} diff --git a/.codexclaw/goalplans/opencodex-live-unfinished-issues-and-prs-triage/goalplan.json b/.codexclaw/goalplans/opencodex-live-unfinished-issues-and-prs-triage/goalplan.json deleted file mode 100644 index bf89c77b1..000000000 --- a/.codexclaw/goalplans/opencodex-live-unfinished-issues-and-prs-triage/goalplan.json +++ /dev/null @@ -1,365 +0,0 @@ -{ - "objective": "OpenCodex live unfinished issues and PRs triage against current GitHub state. Scope: repository lidge-jun/opencodex, dev target only, worktree . First work-phase is docs-only manifest/devlog: fetch live open PRs and open issues via gh, record current number/title/state/base/head/mergeable/checks/reviews/labels, classify every item into merge now, takeover-fix, comment/request-changes, needs-author-rebase, needs-human/security, later/enhancement, upstream-tracking, or close, and produce a priority table. Later work-phases process exactly one PR or one issue per full PABCD cycle. Allowed: directly fix bugfix/simple safe items on dev, create PRs, wait for CI, squash merge, and close linked issues when live evidence proves safety. Out of scope: main/preview/release branches, automatic merge of security/auth/permission/data-migration/privilege-boundary work, and unapproved GUI/UX decisions except the approved OpenRouter Free separate-provider direction. Terminal outcomes: DONE when all safe live items are processed and manifest evidence is current; NOOP when an item needs no action after live check; NEEDS_HUMAN or UNSAFE for risk-bound/security/UX-decision items; BLOCKED for external author/rebase/CI or upstream dependency; BUDGET_EXHAUSTED only if explicit runtime bounds are hit. Verification: gh live snapshots, code/diff review for candidate PRs, CI/check URLs where actions occur, comments/merge/close URLs for external state changes, and devlog evidence committed locally before completion.", - "slug": "opencodex-live-unfinished-issues-and-prs-triage", - "createdAt": "2026-07-27T10:35:02.724Z", - "updatedAt": "2026-07-27T12:25:15.899Z", - "activeWorkPhaseId": "WP8", - "workPhases": [ - { - "id": "WP0", - "title": "Live GitHub triage manifest and priority table", - "status": "done", - "tasks": [ - { - "id": "WP0-T1", - "title": "Refresh dev branch/worktree state from origin/dev without touching main/preview/release branches", - "status": "done" - }, - { - "id": "WP0-T2", - "title": "Query all current open PRs and issues via gh with state/base/head/mergeable/checks/reviews/labels", - "status": "done" - }, - { - "id": "WP0-T3", - "title": "Write numbered docs-first devlog manifest and priority table", - "status": "done" - }, - { - "id": "WP0-T4", - "title": "Append follow-up one-item work-phases for safe merge/fix/close candidates discovered by the manifest", - "status": "done" - } - ], - "criteriaIds": [ - "C-WP0-LIVE-MANIFEST" - ] - }, - { - "id": "WP1", - "title": "PR #526 catalog write signal rebase and coverage decision", - "status": "done", - "tasks": [ - { - "id": "WP1-T1", - "title": "Re-check PR #526 live head, checks, diff, and independent review", - "status": "done" - }, - { - "id": "WP1-T2", - "title": "Take over rebase/tests or leave a documented blocker for PR #526 only", - "status": "done" - } - ], - "criteriaIds": [ - "C-WP1-PR526" - ] - }, - { - "id": "WP9", - "title": "Dev baseline checkout blocker from devlog gitlinks", - "status": "done", - "tasks": [ - { - "id": "WP9-T1", - "title": "Confirm current dev gitlink/.gitmodules mismatch and whether devlog chase checkouts are required tracked inputs", - "status": "done" - }, - { - "id": "WP9-T2", - "title": "Remove or repair only the accidental devlog gitlinks on a dev-target branch", - "status": "done" - }, - { - "id": "WP9-T3", - "title": "Verify checkout/submodule commands and open/merge the dev baseline CI fix before rerunning PR #526", - "status": "done" - } - ], - "criteriaIds": [ - "C-WP9-DEVLOG-GITLINK" - ] - }, - { - "id": "WP10", - "title": "Dev baseline Desktop 3P target-platform path fix", - "status": "done", - "tasks": [ - { - "id": "WP10-T1", - "title": "Confirm hosted Windows failure and local Desktop 3P path resolver cause", - "status": "done" - }, - { - "id": "WP10-T2", - "title": "Patch target-platform-specific path joining and regression tests on a dev-target branch", - "status": "done" - }, - { - "id": "WP10-T3", - "title": "Verify locally, push PR, wait for hosted checks, and squash merge if green", - "status": "done" - } - ], - "criteriaIds": [ - "C-WP10-DESKTOP3P-PATH" - ] - }, - { - "id": "WP2", - "title": "PR #528 image bridge credential-origin request changes", - "status": "pending", - "tasks": [ - { - "id": "WP2-T1", - "title": "Re-check PR #528 live head, checks, diff, and independent review", - "status": "pending" - }, - { - "id": "WP2-T2", - "title": "Post request-changes comment for credential-origin binding and stale checks", - "status": "pending" - } - ], - "criteriaIds": [ - "C-WP2-PR528" - ] - }, - { - "id": "WP11", - "title": "PR #526 final rerun and merge after dev baseline fixes", - "status": "done", - "tasks": [ - { - "id": "WP11-T1", - "title": "Rebase PR #526 branch onto current origin/dev after WP9/WP10", - "status": "done" - }, - { - "id": "WP11-T2", - "title": "Run local targeted verification and push the rebased PR head", - "status": "done" - }, - { - "id": "WP11-T3", - "title": "Wait for hosted checks and squash merge PR #526 if the latest head is clean", - "status": "done" - } - ], - "criteriaIds": [ - "C-WP11-PR526-FINAL" - ] - }, - { - "id": "WP3", - "title": "Issue #543 Claude queued_command support reply", - "status": "pending", - "tasks": [ - { - "id": "WP3-T1", - "title": "Verify existing debug capture switch and issue context", - "status": "pending" - }, - { - "id": "WP3-T2", - "title": "Post one maintainer comment requesting marker frames", - "status": "pending" - } - ], - "criteriaIds": [ - "C-WP3-ISSUE543" - ] - }, - { - "id": "WP4", - "title": "Issue #547 Claude Desktop custom-model visibility reply", - "status": "pending", - "tasks": [ - { - "id": "WP4-T1", - "title": "Verify issue #547 context and likely evidence gaps", - "status": "pending" - }, - { - "id": "WP4-T2", - "title": "Post one maintainer comment requesting generated config/log/profile evidence", - "status": "pending" - } - ], - "criteriaIds": [ - "C-WP4-ISSUE547" - ] - }, - { - "id": "WP5", - "title": "Issue #545 64-token classifier investigation", - "status": "pending", - "tasks": [ - { - "id": "WP5-T1", - "title": "Trace max_tokens/max_output_tokens path for Desktop 3P classifier requests", - "status": "pending" - }, - { - "id": "WP5-T2", - "title": "Fix if local bug is proven; otherwise comment with exact evidence needed", - "status": "pending" - } - ], - "criteriaIds": [ - "C-WP5-ISSUE545" - ] - }, - { - "id": "WP6", - "title": "PR #527 wrong-base handling", - "status": "done", - "tasks": [ - { - "id": "WP6-T1", - "title": "Re-check #527 after #526 decision", - "status": "pending" - }, - { - "id": "WP6-T2", - "title": "Retarget/request rebase or leave blocker; do not merge in same phase as #526", - "status": "pending" - } - ], - "criteriaIds": [ - "C-WP6-PR527" - ] - }, - { - "id": "WP7", - "title": "Issue #418 V2 custom delegation investigation", - "status": "done", - "tasks": [ - { - "id": "WP7-T1", - "title": "Read custom-parent/custom-child delegation code path and issue evidence", - "status": "done" - }, - { - "id": "WP7-T2", - "title": "Fix or comment with code pointers and required reproduction evidence", - "status": "done" - } - ], - "criteriaIds": [ - "C-WP7-ISSUE418" - ] - }, - { - "id": "WP8", - "title": "Issue #509 JS heap watchdog investigation", - "status": "in_progress", - "tasks": [ - { - "id": "WP8-T1", - "title": "Trace RSS/heap watchdog logic and issue evidence", - "status": "pending" - }, - { - "id": "WP8-T2", - "title": "Fix or comment with code pointers and blocker", - "status": "pending" - } - ], - "criteriaIds": [ - "C-WP8-ISSUE509" - ] - } - ], - "criteria": [ - { - "id": "C-WP0-LIVE-MANIFEST", - "scenario": "Live GitHub state has been refreshed and every open PR/open issue is classified into the requested triage buckets.", - "expectedEvidence": "devlog/_plan/260727_live_unfinished_triage/ numbered manifest files with gh snapshot timestamp, PR/issue lists, classification rationale, and priority table.", - "capturedEvidence": "WP0 closed by cxc D at 2026-07-27T10:46:14Z. Commit 58b247ac records devlog/_plan/260727_live_unfinished_triage. C check: open PR count 14 with numbers 355,424,429,447,461,491,493,495,498,512,526,527,528,533; open issue count 23 with numbers 42,92,95,177,178,201,241,294,386,401,414,415,417,418,425,462,476,509,521,540,543,545,547; manifest has unsafe merge-now entries 0.", - "status": "met" - }, - { - "id": "C-WP1-PR526", - "scenario": "PR #526 is either taken over with rebase/direct coverage or left open with a fresh blocker comment.", - "expectedEvidence": "live PR head/checks, independent review verdict, test evidence or comment URL.", - "capturedEvidence": "WP1 closed by cxc D at 2026-07-27T11:01:22Z. Same-repo branch codex/catalog-written-signal was rebased onto origin/dev@7fcaa9119253d010393cb457427a2868cd935718 and pushed at 43d0efff4569711ed192e09d4d87b62fc803153c. Local pre-push passed typecheck, lint:gui, bun test 5051 pass/0 fail/24881 assertions, privacy scan, and React Doctor. Hosted Issue quality tests/test failed before tests during checkout with fatal missing .gitmodules mapping for devlog/_chase/_cca; origin/dev has the same gitlink mismatch. Merge held pending WP9 baseline checkout repair.", - "status": "met" - }, - { - "id": "C-WP9-DEVLOG-GITLINK", - "scenario": "The dev baseline checkout blocker caused by tracked devlog gitlinks without .gitmodules mappings is fixed or proven to require human direction.", - "expectedEvidence": "git tree/submodule evidence, commit/PR URL, local checkout/submodule verification, and hosted CI rerun evidence if pushed.", - "capturedEvidence": "WP9 closed by cxc D at 2026-07-27T11:11:58Z. Branch codex/devlog-gitlink-ci-fix removed exactly three accidental 160000 gitlinks without .gitmodules mappings: devlog/_chase/_cca, devlog/_chase/_litellm, and devlog/_fin/opencode-cursor. Local verification: git ls-files -s found no 160000 entries; git submodule status --recursive exit 0; git diff --check origin/dev exit 0. PR #550 https://github.com/lidge-jun/opencodex/pull/550 passed hosted checks and was squash-merged into origin/dev at ff831858388179d3f76f4dd7c119d84470214fa6.", - "status": "met" - }, - { - "id": "C-WP10-DESKTOP3P-PATH", - "scenario": "The dev baseline Desktop 3P path resolver returns target-platform separators across hosted OSes and unblocks PR #526 CI.", - "expectedEvidence": "code pointers, targeted Bun test output, TypeScript output, diff-check output, PR URL, hosted check evidence, and merge SHA if green.", - "capturedEvidence": "WP10 branch codex/desktop3p-path-windows-ci commit f6d2881dd422830eece502e0ba8de493205fe9d1 patched src/claude/desktop-3p-paths.ts to use target-platform posix/win32 joins and updated tests/desktop-3p.test.ts plus tests/claude-desktop-config-path.test.ts. Local verification: bun test tests/desktop-3p.test.ts tests/claude-desktop-config-path.test.ts = 30 pass/0 fail; bun x tsc --noEmit exit 0; git diff --check origin/dev exit 0. Prepush full gate: 5047 pass/0 fail, privacy scan passed, GUI doctor skipped. Independent C review Aquinas PASS. PR #552 https://github.com/lidge-jun/opencodex/pull/552 passed hosted CodeRabbit, enforce-target, label, react-doctor, ubuntu-latest, macos-latest, windows-latest, and all npm-global matrix jobs; squash-merged at 2026-07-27T11:43:58Z as origin/dev 7c74e0a22ec96dd5849d3d7253758f0ab15d9737. Remote topic branch deleted.", - "status": "met" - }, - { - "id": "C-WP2-PR528", - "scenario": "PR #528 receives a request-changes comment for credential-origin binding and stale checks.", - "expectedEvidence": "live PR head/checks, independent review verdict, and comment/review URL.", - "capturedEvidence": "", - "status": "open" - }, - { - "id": "C-WP11-PR526-FINAL", - "scenario": "PR #526 is rebased after dev baseline blockers, verified on the latest head, and merged if clean.", - "expectedEvidence": "rebase head SHA, local test/typecheck/diff-check output, pushed head SHA, hosted check list, merge commit URL/SHA or blocker evidence.", - "capturedEvidence": "WP11 closed by cxc D at 2026-07-27T12:05:44Z merge evidence. Branch codex/catalog-written-signal was rebased on origin/dev@7c74e0a22ec96dd5849d3d7253758f0ab15d9737 and pushed at ce716cc117ab23e4420c8c9fe860959968f66cdc. Local targeted verification passed: bun test tests/codex-refresh.test.ts tests/codex-sync-api.test.ts tests/injection-model-api.test.ts = 24 pass/0 fail/112 assertions; bun x tsc --noEmit exit 0; git diff --check origin/dev exit 0. Pre-push full gate passed: bun run test = 5051 pass/0 fail/24881 assertions, privacy scan passed, GUI doctor skipped. Hosted checks on PR #526 head ce716cc117ab23e4420c8c9fe860959968f66cdc all succeeded: CodeRabbit, label, react-doctor, ubuntu-latest, macos-latest, windows-latest, and npm-global ubuntu/macos/windows. Pre-merge gate passed: remote dev stayed 7c74e0a22ec96dd5849d3d7253758f0ab15d9737, PR head matched ce716cc117ab23e4420c8c9fe860959968f66cdc, mergeable MERGEABLE/CLEAN and REST mergeable_state clean. PR #526 https://github.com/lidge-jun/opencodex/pull/526 was squash-merged into dev at 2026-07-27T12:05:44Z as 9dd3c42dae2e7feda3581c6d477cf5a0d6e646bf. Remote codex/catalog-written-signal branch was preserved at ce716cc117ab23e4420c8c9fe860959968f66cdc.", - "status": "met" - }, - { - "id": "C-WP3-ISSUE543", - "scenario": "Issue #543 receives a concrete support reply naming the existing debug capture switch and requested evidence.", - "expectedEvidence": "comment URL plus code/docs pointers for `ocx debug claude` or `OCX_CLAUDE_DEBUG=1`.", - "capturedEvidence": "", - "status": "open" - }, - { - "id": "C-WP4-ISSUE547", - "scenario": "Issue #547 receives a concrete evidence request for Claude Desktop custom-model visibility.", - "expectedEvidence": "comment URL plus requested config/log/profile evidence.", - "capturedEvidence": "", - "status": "open" - }, - { - "id": "C-WP5-ISSUE545", - "scenario": "Issue #545 is narrowed to a proven local fix or exact remaining evidence need.", - "expectedEvidence": "code pointers, test/command output if fixed, PR/comment URL.", - "capturedEvidence": "", - "status": "open" - }, - { - "id": "C-WP6-PR527", - "scenario": "PR #527 wrong-base state is resolved or documented after PR #526 decision.", - "expectedEvidence": "live base/check state and retarget/request-rebase/comment URL.", - "capturedEvidence": "WP6 closed by cxc D at 2026-07-27T12:16:35Z. Live PR #527 remained OPEN on base codex/catalog-written-signal@ce716cc117ab23e4420c8c9fe860959968f66cdc with head codex/app-server-restart@a64aa585630f664a83c25253497a62810133e832, mergeable CONFLICTING and mergeStateStatus DIRTY. PR #526 had merged to dev as 9dd3c42dae2e7feda3581c6d477cf5a0d6e646bf. Topology showed #527 still carried duplicate old #526 commit 1ba588eff663a5be846a8723b90a452dca8cd04c; merge-tree against current dev conflicted in tests/codex-refresh.test.ts and tests/injection-model-api.test.ts. Independent A review returned GO-WITH-FIXES and the blocker was folded into the comment plan. Posted maintainer comment https://github.com/lidge-jun/opencodex/pull/527#issuecomment-5091163284 requesting a clean rebuild from current dev, dropping 1ba588e, preserving the Grok diagnostic, and retargeting after rebuild. No retarget, push, merge, or branch deletion was performed.", - "status": "met" - }, - { - "id": "C-WP7-ISSUE418", - "scenario": "Issue #418 has a proven fix or a fresh investigation comment with code pointers.", - "expectedEvidence": "test/command output if fixed, otherwise comment URL plus code pointers.", - "capturedEvidence": "WP7 closed as NOOP/comment-request-changes at 2026-07-27. Live issue #418 remains OPEN with bug label. Existing comments already satisfy this phase's intended maintainer action: owner request https://github.com/lidge-jun/opencodex/issues/418#issuecomment-5069836945 asks for raw provider tool-call, Responses event, and child lifecycle trace; reporter acknowledgement https://github.com/lidge-jun/opencodex/issues/418#issuecomment-5070272410 says same-run failing spawn_agent trace is still unavailable until usage limit clears; collaborator cross-link https://github.com/lidge-jun/opencodex/issues/418#issuecomment-5085535548 keeps #418 separate from #92 pending the three-boundary capture. Code review found no proven local argument-drop path: parser copies tool parameters at src/responses/parser.ts:134-139; OpenAI-compatible adapter forwards parameters at src/adapters/openai-chat.ts:432-445; provider function.arguments fragments are accumulated at src/adapters/openai-chat.ts:749-768; bridge forwards deltas at src/bridge.ts:610-617 and materializes {} only when accumulated bytes are empty at src/bridge.ts:366-375. No GitHub comment, close, merge, or code change was performed.", - "status": "met" - }, - { - "id": "C-WP8-ISSUE509", - "scenario": "Issue #509 heap watchdog gap has a proven fix or a fresh investigation comment with code pointers.", - "expectedEvidence": "test/command output if fixed, otherwise comment URL plus code pointers.", - "capturedEvidence": "", - "status": "open" - } - ], - "host": { - "armed": true, - "armedAt": "2026-07-27T10:35:02.725Z", - "source": "freeze" - } -} diff --git a/.codexclaw/goalplans/opencodex-live-unfinished-issues-and-prs-triage/ledger.jsonl b/.codexclaw/goalplans/opencodex-live-unfinished-issues-and-prs-triage/ledger.jsonl deleted file mode 100644 index 07d4aeae8..000000000 --- a/.codexclaw/goalplans/opencodex-live-unfinished-issues-and-prs-triage/ledger.jsonl +++ /dev/null @@ -1,24 +0,0 @@ -{"ts":"2026-07-27T10:35:02.725Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"created","detail":"init objective=\"OpenCodex live unfinished issues and PRs triage against current GitHub state. Scope: repository lidge-jun/opencodex, dev target only, worktree . First work-phase is docs-only manifest/devlog: fetch live open PRs and open issues via gh, record current number/title/state/base/head/mergeable/checks/reviews/labels, classify every item into merge now, takeover-fix, comment/request-changes, needs-author-rebase, needs-human/security, later/enhancement, upstream-tracking, or close, and produce a priority table. Later work-phases process exactly one PR or one issue per full PABCD cycle. Allowed: directly fix bugfix/simple safe items on dev, create PRs, wait for CI, squash merge, and close linked issues when live evidence proves safety. Out of scope: main/preview/release branches, automatic merge of security/auth/permission/data-migration/privilege-boundary work, and unapproved GUI/UX decisions except the approved OpenRouter Free separate-provider direction. Terminal outcomes: DONE when all safe live items are processed and manifest evidence is current; NOOP when an item needs no action after live check; NEEDS_HUMAN or UNSAFE for risk-bound/security/UX-decision items; BLOCKED for external author/rebase/CI or upstream dependency; BUDGET_EXHAUSTED only if explicit runtime bounds are hit. Verification: gh live snapshots, code/diff review for candidate PRs, CI/check URLs where actions occur, comments/merge/close URLs for external state changes, and devlog evidence committed locally before completion.\" criteria=0"} -{"ts":"2026-07-27T10:46:14.884Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"workphase_done","detail":"closed WP0"} -{"ts":"2026-07-27T10:46:14.884Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"workphase_started","detail":"started WP1"} -{"ts":"2026-07-27T11:01:22.413Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"workphase_done","detail":"closed WP1"} -{"ts":"2026-07-27T11:01:22.413Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"workphase_started","detail":"started WP2"} -{"ts":"2026-07-27T11:11:58.894Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"workphase_done","detail":"closed WP9"} -{"ts":"2026-07-27T11:11:58.894Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"workphase_started","detail":"started WP2"} -{"ts":"2026-07-27T11:46:27.214Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"workphase_done","detail":"closed WP10"} -{"ts":"2026-07-27T11:46:27.214Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"workphase_started","detail":"started WP2"} -{"ts":"2026-07-27T11:47:00.000Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"workphase_started","detail":"started WP11"} -{"ts":"2026-07-27T12:05:44.000Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"task_done","detail":"WP11-T1 rebased codex/catalog-written-signal onto origin/dev@7c74e0a22ec96dd5849d3d7253758f0ab15d9737"} -{"ts":"2026-07-27T12:05:44.000Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"task_done","detail":"WP11-T2 verified locally and pushed ce716cc117ab23e4420c8c9fe860959968f66cdc"} -{"ts":"2026-07-27T12:05:44.000Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"task_done","detail":"WP11-T3 hosted checks passed and PR #526 squash-merged as 9dd3c42dae2e7feda3581c6d477cf5a0d6e646bf"} -{"ts":"2026-07-27T12:05:44.000Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"criterion_met","detail":"C-WP11-PR526-FINAL evidence in devlog/_plan/260727_wp11-pr526-final-rerun-merge/011_phase1_evidence.md"} -{"ts":"2026-07-27T12:05:44.000Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"workphase_done","detail":"closed WP11"} -{"ts":"2026-07-27T12:05:44.000Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"workphase_started","detail":"started WP2"} -{"ts":"2026-07-27T12:08:50.093Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"workphase_done","detail":"closed WP11"} -{"ts":"2026-07-27T12:08:50.093Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"workphase_started","detail":"started WP3"} -{"ts":"2026-07-27T12:09:30.000Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"steering","detail":"corrected next active work-phase from WP3 to WP6 because PR #527 explicitly depends on the PR #526 decision; WP2 and WP3 remain pending"} -{"ts":"2026-07-27T12:09:30.000Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"workphase_started","detail":"started WP6"} -{"ts":"2026-07-27T12:16:35.216Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"workphase_done","detail":"closed WP6"} -{"ts":"2026-07-27T12:16:35.216Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"workphase_started","detail":"started WP7"} -{"ts":"2026-07-27T12:25:15.900Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"workphase_done","detail":"closed WP7"} -{"ts":"2026-07-27T12:25:15.900Z","slug":"opencodex-live-unfinished-issues-and-prs-triage","event":"workphase_started","detail":"started WP8"} diff --git a/.github/scripts/pr-labeler.test.cjs b/.github/scripts/pr-labeler.test.cjs index 71afd7836..1c6193754 100644 --- a/.github/scripts/pr-labeler.test.cjs +++ b/.github/scripts/pr-labeler.test.cjs @@ -165,8 +165,15 @@ describe("pr-labeler workflow", () => { it("keeps trusted default-branch checkout, concurrency cancel, and minimal permissions", () => { assert.match(workflow, /ref:\s*\$\{\{\s*github\.event\.repository\.default_branch\s*\}\}/); assert.match(workflow, /cancel-in-progress:\s*true/); - assert.match(workflow, /pull-requests:\s*read/); assert.match(workflow, /issues:\s*write/); - assert.doesNotMatch(workflow, /pull-requests:\s*write/); + // The issues label endpoints are shared with pull requests: writing a label + // onto a PR number needs pull_requests=write alongside issues=write, which + // GitHub reports as `issues=write; pull_requests=write`. Pinning this to + // read made the workflow fail closed on the first PR that actually needed a + // label applied (#565), so write is the minimum here, not an escalation. + assert.match(workflow, /pull-requests:\s*write/); + // contents stays read — the labeler never pushes. + assert.match(workflow, /contents:\s*read/); + assert.doesNotMatch(workflow, /contents:\s*write/); }); }); diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml index 8bc529b51..348620fca 100644 --- a/.github/workflows/pr-labeler.yml +++ b/.github/workflows/pr-labeler.yml @@ -17,8 +17,14 @@ concurrency: permissions: contents: read - # pulls.get only needs read; label mutations use the issues API. - pull-requests: read + # pulls.get only needs read, but the issues label endpoints are shared with + # pull requests: adding or removing a label on a PR number is rejected with + # "Resource not accessible by integration" unless the token also carries + # pull_requests=write (the API reports `issues=write; pull_requests=write` + # in x-accepted-github-permissions). Read-only here silently worked while + # every run happened to be a no-op sync, and failed on the first PR that + # actually needed a label written. + pull-requests: write issues: write jobs: diff --git a/.gitignore b/.gitignore index 8ee0b5d9c..e35cc4ee6 100644 --- a/.gitignore +++ b/.gitignore @@ -8,8 +8,14 @@ devlog/ .opencode/ # Local agent/session artifacts +# These are per-machine agent state (goalplans, ledgers, evidence scratch). +# They are never part of the product and must not be committed, not even with +# `git add -f` — see tests/repo-hygiene.test.ts, which fails if any path here +# becomes tracked again. .codexclaw/ +**/.codexclaw/ .omo/ +**/.omo/ # Test-generated artifacts tests/.tmp-*/ diff --git a/devlog/.DS_Store b/devlog/.DS_Store deleted file mode 100644 index 9ac38fcbe..000000000 Binary files a/devlog/.DS_Store and /dev/null differ diff --git a/devlog/_plan/.DS_Store b/devlog/_plan/.DS_Store deleted file mode 100644 index 3a1ad0021..000000000 Binary files a/devlog/_plan/.DS_Store and /dev/null differ diff --git a/package.json b/package.json index f02953c8f..735df8a60 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@bitkyc08/opencodex", - "version": "2.7.41", + "version": "2.7.42", "description": "Universal provider proxy for OpenAI Codex & Claude Code — use any LLM with Codex CLI/App/SDK and Claude Code", "type": "module", "main": "./bin/package-main.mjs", diff --git a/src/providers/registry.ts b/src/providers/registry.ts index c55b544fb..5902c5b29 100644 --- a/src/providers/registry.ts +++ b/src/providers/registry.ts @@ -978,7 +978,6 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [ authKind: "key", dashboardUrl: "https://ollama.com/settings/keys", // Live IDs verified 2026-07-10; qwen3-coder:480b retires 2026-07-15. - // Evidence: .codexclaw/evidence/260710_wp9_ollama_cloud_model_ids.md. models: ["glm-5.2", "deepseek-v4-pro", "qwen3-coder:480b", "gpt-oss:120b", "kimi-k2.6", "minimax-m3", "qwen3.5:397b", "gemma4:31b"], defaultModel: "glm-5.2", noVisionModels: [ diff --git a/src/service.ts b/src/service.ts index a68300827..7a2dec314 100644 --- a/src/service.ts +++ b/src/service.ts @@ -9,11 +9,11 @@ import { execFileSync, execSync } from "node:child_process"; import { chmodSync, existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs"; import { homedir } from "node:os"; import { dirname, join, resolve } from "node:path"; -import { expandUserPath, getConfigDir, readPid, removePid, removeRuntimePort } from "./config"; +import { getConfigDir, readPid, removePid, removeRuntimePort } from "./config"; import { loadConfig } from "./config"; import { restoreNativeCodex } from "./codex/inject"; import { stripGrokConfig } from "./grok/inject"; -import { isWslRuntime } from "./codex/home"; +import { isWslRuntime, resolveCodexHomeDir } from "./codex/home"; import { durableBunPath, durableBunRuntime } from "./lib/bun-runtime"; import { isProcessAlive, stopProxy } from "./lib/process-control"; import { serviceApiTokenFilePath } from "./lib/service-secrets"; @@ -87,8 +87,9 @@ function serviceStatePaths(): string[] { } function currentCodexHome(): string { - const raw = process.env.CODEX_HOME?.trim(); - return raw ? resolve(expandUserPath(raw)) : join(homedir(), ".codex"); + // Service ownership must use the same CODEX_HOME resolver as Codex injection, + // tray startup, and the rest of the runtime. On this host that is E:\\codex. + return resolveCodexHomeDir(); } function currentOpenCodexHome(): string { @@ -1069,6 +1070,9 @@ export function windowsTaskRegistrationHealthy( const action = taskXmlSection(scrubbed, "Exec"); // A self-closing leaves an empty section, so look for the element // itself — scoped to so a decoy elsewhere cannot satisfy it. + const registeredAction = action.toLowerCase(); + const registeredCommand = `${taskXmlString(wscript)}`.toLowerCase(); + const registeredArguments = `${taskXmlString(`/b /nologo "${launcher}"`)}`.toLowerCase(); return taskXmlElementCount(triggers, "LogonTrigger") > 0 && taskXmlOptionalValueEquals(trigger, "Enabled", "true") && /\s*InteractiveToken\s*<\/LogonType>/i.test(principal) @@ -1076,8 +1080,9 @@ export function windowsTaskRegistrationHealthy( && taskXmlOptionalValueEquals(settings, "Enabled", "true") && /\s*IgnoreNew\s*<\/MultipleInstancesPolicy>/i.test(settings) && /\s*PT0S\s*<\/ExecutionTimeLimit>/i.test(settings) - && action.includes(`${taskXmlString(wscript)}`) - && action.includes(`${taskXmlString(`/b /nologo "${launcher}"`)}`); + // Windows paths are case-insensitive; schtasks may normalize their casing. + && registeredAction.includes(registeredCommand) + && registeredAction.includes(registeredArguments); } export interface WindowsSchedulerXmlState { diff --git a/src/tray/windows.ts b/src/tray/windows.ts index d7aae3163..0207baefc 100644 --- a/src/tray/windows.ts +++ b/src/tray/windows.ts @@ -1,11 +1,11 @@ import { execFile, execFileSync, spawn } from "node:child_process"; import { createHash } from "node:crypto"; import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs"; -import { homedir } from "node:os"; import { join, resolve } from "node:path"; -import { expandUserPath, getConfigDir } from "../config"; +import { getConfigDir } from "../config"; import { durableBunPath } from "../lib/bun-runtime"; import { hardenSecretDir, hardenSecretPath } from "../lib/windows-secret-acl"; +import { resolveCodexHomeDir } from "../codex/home"; const RUN_KEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"; const RUN_PARENT_KEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion"; @@ -75,8 +75,10 @@ function sourceTrayIconPaths(): string[] { } function currentCodexHome(): string { - const raw = process.env.CODEX_HOME?.trim(); - return raw ? resolve(expandUserPath(raw)) : join(homedir(), ".codex"); + // Keep the tray's listener/launcher target aligned with Codex's active home. + // This matters on the Windows desktop setup, where CODEX_HOME is E:\\codex + // instead of the historical %USERPROFILE%\\.codex fallback. + return resolveCodexHomeDir(); } function currentEntry(): WindowsTrayEntry { diff --git a/tests/repo-hygiene.test.ts b/tests/repo-hygiene.test.ts new file mode 100644 index 000000000..07fcae065 --- /dev/null +++ b/tests/repo-hygiene.test.ts @@ -0,0 +1,57 @@ +import { describe, expect, test } from "bun:test"; +import { fileURLToPath } from "node:url"; + +const repoRoot = fileURLToPath(new URL("../", import.meta.url)); + +/** + * Local agent/session state must never reach a commit. + * + * `.gitignore` alone does not enforce this: `git add -f` overrides it silently, + * and once a path is tracked the ignore rule stops applying to it entirely. The + * `.codexclaw/` goalplans and ledgers were committed exactly that way and rode + * along into `main` and `preview` before anyone noticed. + * + * This test closes that gap by asserting against the real index instead of the + * ignore file, so a forced add fails CI on the commit that introduces it. + */ +const FORBIDDEN_TRACKED_DIRS = [".codexclaw", ".omo", ".claude", "node_modules", ".tmp"]; + +const FORBIDDEN_TRACKED_FILENAMES = [".DS_Store", "Thumbs.db"]; + +function trackedFiles(): string[] { + const result = Bun.spawnSync(["git", "ls-files"], { cwd: repoRoot }); + if (result.exitCode !== 0) { + throw new Error(`git ls-files failed: ${new TextDecoder().decode(result.stderr)}`); + } + return new TextDecoder() + .decode(result.stdout) + .split("\n") + .map((line) => line.trim()) + .filter(Boolean); +} + +describe("repository hygiene", () => { + test("no local agent or session state is tracked", () => { + const offenders = trackedFiles().filter((path) => + path.split("/").some((segment) => FORBIDDEN_TRACKED_DIRS.includes(segment)), + ); + + expect(offenders).toEqual([]); + }); + + test("no OS metadata files are tracked", () => { + const offenders = trackedFiles().filter((path) => + FORBIDDEN_TRACKED_FILENAMES.includes(path.split("/").pop() ?? ""), + ); + + expect(offenders).toEqual([]); + }); + + test("gitignore still declares the agent-state directories", async () => { + const ignore = await Bun.file(new URL("../.gitignore", import.meta.url)).text(); + + for (const dir of FORBIDDEN_TRACKED_DIRS) { + expect(ignore).toContain(`${dir}/`); + } + }); +});