Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
693ead0
docs(plan): issue train 0927 roadmap (triage, wp2-wp4 diff-level docs)
lidge-jun Sep 27, 2026
09e9cb7
docs(plan): fold audit rounds 1-3 and re-plan #255 as gitignore parti…
lidge-jun Sep 27, 2026
c94bb04
docs(plan): fold audit round 4 (gitignore atomicity, parent ignore, t…
lidge-jun Sep 27, 2026
e4016f2
docs(plan): record audit rounds and builder workspace rule
lidge-jun Sep 27, 2026
e486f83
docs(plan): fold wp2 architect consultation
lidge-jun Sep 27, 2026
cc5bd48
docs(plan): fold wp2 reflection edge cases
lidge-jun Sep 27, 2026
4113d92
docs(plan): consolidate wp2 amendments (gitignore publication, UPS sw…
lidge-jun Sep 27, 2026
c048886
docs(plan): fix UPS handler signature and cap return contract
lidge-jun Sep 27, 2026
9b09b09
fix(pabcd-state): release unbound IDLE goals (#253)
lidge-jun Sep 27, 2026
45eeaa0
fix(pabcd-state): honor project and environment hook switch (#252)
lidge-jun Sep 27, 2026
ca6727c
fix(pabcd-state): gate worker receipts only in active B/C (#251)
lidge-jun Sep 27, 2026
3ab8699
docs(pabcd): explain hook policy switch (#252)
lidge-jun Sep 27, 2026
e08f874
docs(pabcd): describe executor and worker receipt scope (#251)
lidge-jun Sep 27, 2026
63f3b0e
test(pabcd-state): lock explicit trigger requests (#250)
lidge-jun Sep 27, 2026
8a2609a
fix(pabcd-state): require explicit phase and loop requests (#250)
lidge-jun Sep 27, 2026
1469933
fix(pabcd-state): persist per-turn Stop cap fields (#254)
lidge-jun Sep 27, 2026
880ba6e
fix(pabcd-state): reset Stop cap per user turn and notify once (#254)
lidge-jun Sep 27, 2026
d8ea3fd
test: align trigger expectations with explicit requests (#250)
lidge-jun Sep 27, 2026
9c36b46
merge #252 PABCD switch (012)
lidge-jun Sep 27, 2026
dc492ec
merge #253 idle goal release (013)
lidge-jun Sep 27, 2026
202c2da
merge #254 per-turn Stop cap (014)
lidge-jun Sep 27, 2026
737d557
merge #251 worker gate (015)
lidge-jun Sep 27, 2026
82b394c
refactor(pabcd-state): use the shared PABCD policy reader in the Suba…
lidge-jun Sep 27, 2026
7df4c1b
fix(pabcd-state): ignore runtime state on first directory creation (#…
lidge-jun Sep 27, 2026
dcdb44c
fix(codexclaw): route project-local writers through ignore helper (#255)
lidge-jun Sep 27, 2026
6a49387
merge #250 trigger narrowing (016)
lidge-jun Sep 27, 2026
f0d5956
test(pabcd-state): #250 checks ignore #254 turn-budget bookkeeping
lidge-jun Sep 27, 2026
c8b649d
merge #255 codexclaw .gitignore on first folder creation (011)
lidge-jun Sep 27, 2026
c058adf
build: regenerate dist for wp2 hook runtime fixes
lidge-jun Sep 27, 2026
216e15b
build: track new codexclaw-dir dist outputs
lidge-jun Sep 27, 2026
5fcf859
docs: publish measured test count (3649)
lidge-jun Sep 27, 2026
a9f6826
docs(changelog): wp2 hook runtime fixes
lidge-jun Sep 27, 2026
13bac9d
fix(pabcd-state): negated requests never arm or inject (#250)
lidge-jun Sep 27, 2026
1b3fed3
fix(pabcd-state): scope request negation to the codexclaw action (#250)
lidge-jun Sep 27, 2026
011efa3
docs: publish measured test count (3650)
lidge-jun Sep 27, 2026
19ceb05
fix(pabcd-state): recognize indirect refusals and split a refused mod…
lidge-jun Sep 27, 2026
c12343a
fix(pabcd-state): treat "can you not" and "prefer not to" as refusals…
lidge-jun Sep 27, 2026
4ee1112
fix(pabcd-state): cxc-loop resume and continue requests arm after cla…
lidge-jun Sep 27, 2026
5178e26
docs(plan): treat queued hosted CI as a wp5 external wait
lidge-jun Sep 27, 2026
29e34de
test(pabcd-state): resolve the CLI entry with fileURLToPath for Windo…
lidge-jun Sep 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,22 @@ All notable changes to codexclaw are documented here. The format follows

## [Unreleased]

### Added

- `CODEXCLAW_PABCD=off` (or `on`) and project `codexclaw.json` `{"pabcd": {"enabled": false}}` turn the PABCD hook policy off while keeping the worktree, memory-write, automation-ownership and apply_patch lint guards and recall active. A recognized environment value wins over the project file in both directions (#252).
- When codexclaw creates a project's `.codexclaw` folder, it also writes `.codexclaw/.gitignore` so session state, ledgers and evidence stay out of git; user-authored `rules/*.md` stay committable unless an ancestor ignore rule hides the folder. Existing `.codexclaw` folders are never modified. Lazy creation of session state is deferred (#255, partial).

### Changed

- The absolute Stop continuation cap (24) now counts per genuine user turn instead of per session, and the release prints one notice per turn (#254).

### Fixed

- Ordinary words (for example "interview", "keep going until", "끝까지 진행해", quoted or fenced examples) no longer inject PABCD phase directives or arm the loop; hints need an explicit codexclaw request such as `cxc-pabcd` or `cxc-loop` (#250).
- The SubagentStop evidence gate no longer blocks Codex's built-in `worker` outside an active PABCD build or check cycle; registered `executor` stays gated while PABCD is on (#251).
- An active native goal without a bound goalplan no longer blocks Stop at IDLE (#253).


## [0.2.39] - 2026-09-24

### Added
Expand Down
2 changes: 1 addition & 1 deletion README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

<p align="center">
<a href="https://github.com/lidge-jun/codexclaw/actions/workflows/ci.yml"><img src="https://github.com/lidge-jun/codexclaw/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
<img src="https://img.shields.io/badge/tests-3%2C609-brightgreen" alt="3,609 tests">
<img src="https://img.shields.io/badge/tests-3%2C650-brightgreen" alt="3,650 tests">
<img src="https://img.shields.io/badge/skills-29-blue" alt="29 skills">
<img src="https://img.shields.io/badge/hooks-29-blue" alt="29 hooks">
<a href="https://lidge-jun.github.io/codexclaw/"><img src="https://img.shields.io/badge/docs-codexclaw-black" alt="Documentation"></a>
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

<p align="center">
<a href="https://github.com/lidge-jun/codexclaw/actions/workflows/ci.yml"><img src="https://github.com/lidge-jun/codexclaw/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
<img src="https://img.shields.io/badge/tests-3%2C609-brightgreen" alt="3,609 tests">
<img src="https://img.shields.io/badge/tests-3%2C650-brightgreen" alt="3,650 tests">
<img src="https://img.shields.io/badge/skills-29-blue" alt="29 skills">
<img src="https://img.shields.io/badge/hooks-29-blue" alt="29 hooks">
<a href="https://lidge-jun.github.io/codexclaw/"><img src="https://img.shields.io/badge/docs-codexclaw-black" alt="Documentation"></a>
Expand Down
2 changes: 1 addition & 1 deletion README.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

<p align="center">
<a href="https://github.com/lidge-jun/codexclaw/actions/workflows/ci.yml"><img src="https://github.com/lidge-jun/codexclaw/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
<img src="https://img.shields.io/badge/tests-3%2C609-brightgreen" alt="3,609 tests">
<img src="https://img.shields.io/badge/tests-3%2C650-brightgreen" alt="3,650 tests">
<img src="https://img.shields.io/badge/skills-29-blue" alt="29 skills">
<img src="https://img.shields.io/badge/hooks-29-blue" alt="29 hooks">
<a href="https://lidge-jun.github.io/codexclaw/"><img src="https://img.shields.io/badge/docs-codexclaw-black" alt="Documentation"></a>
Expand Down
60 changes: 60 additions & 0 deletions devlog/_plan/260927_issue_train/000_plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Issue train 2026-09-27: hook runtime fixes, agent-thread permissions, goalplan decisions

Codexclaw has four confirmed defects in its hook runtime, one host workaround worth shipping, and three small opt-in improvements among the 22 open issues. The defects are: ordinary prompt words inject PABCD directives (#250), the SubagentStop evidence gate blocks Codex's built-in `worker` in sessions that never used PABCD (#251), the Stop hook blocks every session with an active native goal even when no goalplan is bound (#253), and SessionStart creates unignored `.codexclaw` state in fresh working directories (#255, partial fix). The host workaround covers threads that Codex Desktop creates through `create_thread` with reduced permission even when the user runs full access. This unit fixes #250/#251/#253, partially fixes #255 by adding a `.gitignore` at first directory creation, adds the opt-in permission hook and advisory, adds a PABCD off switch (#252), a per-turn Stop budget (#254) and plan-local pending decisions (#262), and records a triage decision for every open issue (001).

Reader: a maintainer deciding whether to merge these changes into dev; familiarity with the pabcd-state hook component and the goalplan CLI is assumed.

## Loop contract

- Loop archetype: satisfy-spec HOTL, docs-first (LOOP-DOCS-FIRST-01).
- Trigger: user request on 2026-09-27 to fix the real issues and worthwhile improvements among the open issues, plus the agent-thread permission problem found in the same chat, and put them into dev, through cxc-loop with unlimited gpt-6-sol dispatch.
- Goal: wp2-wp4 merged into `dev` through ordinary PRs after hosted CI; every open issue has a recorded decision; fully fixed issues are closed with PR links; #255 stays open with the partial-fix PR linked and lazy creation deferred.
- Non-goals: dev to main promotion, release, version bump, tags, npm publish; Codex core or Desktop changes; other repositories; the deferred and declined proposals in 001.
- Verifier: per-phase focused `node --test` files named in each decade doc; at every C, `npm run build`, the focused tests through `cxc receipt test`, then full `npm test`, `node plugins/codexclaw/scripts/gate.mjs`, `node plugins/codexclaw/scripts/inventory.mjs --check --tests <measured total>` and `node plugins/codexclaw/scripts/platform-smoke.mjs`; hosted CI on each PR head (jobs actually ran, head SHA, event, run id). Skill prose changes are read by no test; their review is human (PLAN-VERIFIER-REAL-01).
- Stop condition: all seven goalplan criteria met with fresh evidence, or a real blocker after root-cause work.
- Memory artifact: this unit and `.codexclaw/evidence/01a0e313-aa5c-72a0-aecc-59a966bfca9c/`.
- Expected terminal outcomes: DONE (PRs merged, issues dispositioned); BLOCKED (CI infrastructure or branch protection outside scope); NEEDS_HUMAN (a default-on behavior change the user must choose); UNSAFE (a change would weaken a safety gate).
- Resource bounds: this checkout (`/Users/jun/.codex/worktrees/902d/codexclaw`), task-owned worktrees created with `create_worktree` for parallel builders, `gh` with the user's credentials. Writes limited to the IN scope below. No token or wall-clock bound was stated; host limits apply.

## Scope and file map

IN (details in each decade doc):

```
plugins/codexclaw/components/pabcd-state/{src,dist,test} wp2 (010 overview, 011_issue255_codexclaw_gitignore.md, 012-016), wp3 (020), wp4 (030)
plugins/codexclaw/components/cxc-ops/{src,dist,test} wp2 (011 first-directory writers), wp3 (hook-trust)
plugins/codexclaw/components/bg-wake, subagent-config, messenger-bridge/{src,dist,test} wp2 (011 cwd first-directory writers)
plugins/codexclaw/hooks/*.json, .codex-plugin/plugin.json wp3 (two new hooks)
plugins/codexclaw/skills/{pabcd,loop,dev}/references/*.md wp2 (015, 012), wp3 (021), wp4 (030)
plugins/codexclaw/inventory.json, README family counts every phase that changes tests or hooks
```

OUT: Codex core/Desktop, host automation mutation handler (#213), SessionStart family detection from the host (#247), anything listed as defer or decline in 001.

## Ordered work phases

- wp1 (this cycle): docs-only roadmap: 001 triage, 002 architect consultation, 010-016, 020-021, 030, 040. No production edits.
- wp2: hook runtime fixes (010 overview; 011_issue255_codexclaw_gitignore.md, #255 partial fix; 012 #252 PABCD switch, 013 #253 IDLE goal release, 014 #254 per-turn Stop budget, 015 #251 worker gate, 016 #250 trigger narrowing). Foundation first: 011 adds the shared first-directory helper without changing SessionStart state creation; 012 adds the switch every later PABCD handler consults; 013 and 014 then change Stop continuation; 015 and 016 are leaf policy changes. Built in parallel by gpt-6-sol builders on separate branches in task-owned worktrees, merged in that order.
- wp3: agent-created thread permissions (020 hook and advisory, 021 dispatch guidance plus #265 checkpoint guidance). After wp2 so the read-only advisory can follow 011's directory contract and 012's switch semantics.
- wp4: goalplan pending decisions (030, #262). Independent of wp3; after wp2 so Stop/IDLE logic changes are settled before readiness semantics change.
- wp5: delivery and issue disposition (040).

Delivery: one ordinary PR per implementation work phase from a `codex/issue-train-wpN` branch into `dev`, each merged after its hosted CI passes and the next phase rebased onto the new `dev`. No native stacks. Main owns git, the FSM, integration and delivery; gpt-6-sol subagents draft docs, build within disjoint scopes or task-owned worktrees, and review.

Builder workspaces: for parallel builders inside a work phase, main creates one managed worktree per builder with `create_worktree` (ref = the phase branch) and dispatches a gpt-6-sol subagent that passes that worktree path as the shell `workdir` on every command and commits on its own `codex/issue-train-wpN-<slug>` branch there. Subagents inherit this session's full-access permission, which avoids the reduced-permission start that `create_thread` children can get (001, agent-created thread section). Main merges builder branches into the phase branch in the order the decade doc gives, then runs the phase gates in this checkout.

## Issue acceptance mapping

| Issue | Decision | Where it lands |
|---|---|---|
| #250 | fix | 016 |
| #251 | fix | 015 |
| #252 | implement (narrowed) | 012 |
| #253 | fix | 013 |
| #254 | implement | 014 |
| #255 | partial fix (gitignore); lazy creation deferred because stateless sessions affect evidence/goal gates and atomic publication | 011_issue255_codexclaw_gitignore.md |
| #262 | implement | 030 |
| #265 | guidance only | 021 |
| agent-thread permissions (no issue) | implement | 020, 021 |
| #209 #213 #247 #256 #257 #258 #259 #260 #263 #264 #266 #267 #268 | defer | 001 |
| #261 | decline | 001 |
34 changes: 34 additions & 0 deletions devlog/_plan/260927_issue_train/001_research.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Triage of the 22 open issues (2026-09-27)

Six gpt-6-sol explorers verified each issue against `dev` at `958441a9` (read-only, source anchors in their returns); main accepted their verdicts with the adjustments noted. REAL means the shipped behavior is wrong; PROPOSAL means the report asks for new behavior.

| Issue | Verdict | Decision | Reason |
|---|---|---|---|
| #209 pending worktree thread has no clientThreadId to threadId path | NOT-REPRODUCED in plugin | defer | The gap is in the Desktop creation wrapper; codexclaw already keeps provisional and canonical ids apart (dispatch-surfaces.md:114-129, check-lane-packet.mjs:96-119). Needs a host completion event. |
| #213 automation ids are host-global | PARTIAL | defer | The ownership hook already denies foreign update/delete on hooked calls (automation-ownership-gate.ts:37-62). The remaining hole is atomic authorization inside the host mutation handler. |
| #247 identify collab family at SessionStart | PROPOSAL | defer | SessionStart has no tool catalog or family field (fallback-dispatch-cli.ts:33-39); a plugin-only fix would guess. Needs a host signal. |
| #250 trigger and loop-arm heuristics match ordinary words | REAL | fix (016) | detectTrigger and detectLoopArmRequest match bare mentions and generic persistence phrases (hook.ts:238-285) and inject directives into headless runs. |
| #251 SubagentStop gate blocks built-in worker | REAL | fix (015) | The gate checks agent type without checking whether the parent armed a PABCD cycle (subagent-evidence.ts:471). |
| #252 no supported PABCD off switch | PROPOSAL | implement narrowed (012) | A blanket pabcd-state no-op would also remove worktree, memory-write and automation guards (inventory.json:175-205); a PABCD-policy switch keeps them. |
| #253 GOAL-IDLE-CONTINUE-01 blocks every active-goal session | REAL | fix (013) | handleStop blocks at IDLE whenever a native goal is active, even with no state or goalplan (hook.ts:1781-1787; hook-continuation.test.ts:506 pins it). |
| #254 MAX_STOP_BLOCKS_TOTAL never resets | PROPOSAL (behavior intended) | implement (014) | The cap is documented as per-session (hook.ts:1371); long goal sessions still lose continuation silently. A per-real-user-turn budget keeps the unattended bound. |
| #255 SessionStart writes session state into every cwd | REAL | partial fix: `.codexclaw/.gitignore` on first directory creation (011_issue255_codexclaw_gitignore.md); lazy creation deferred | `handleSessionStart` calls `ensureState` unconditionally (`hook.ts:572-575`, `state.ts:368-381`). The issue is low severity and offers an ignore-file alternative. Audit round 3 showed that stateless sessions affect executor evidence and goal-complete gates (`goal-gate.ts:215-236`) and conditional atomic publication (`state.ts:607-617`); lazy creation needs its own design. |
| #256 independent verification receipt | PROPOSAL | defer | Receipts store a joined command string with no argv, cwd or output digests (receipt-cli.ts:170-172); a rerun cannot be reconstructed reliably yet. |
| #257 strict accepted-progress report | PROPOSAL | defer | Review rounds attach to plan audit, not completed work (review-round-cli.ts:230-235); needs a post-implementation acceptance record first (#256). |
| #258 verbatim archive of user-typed prompts | PROPOSAL | defer | UserPromptSubmit carries no typed-versus-injected provenance (hook.ts:134, parse.ts:65); the archive cannot promise what it claims. |
| #259 provenance on peer prompts | PROPOSAL | defer | An unauthenticated text envelope that suppresses PABCD parsing would let anyone type it; needs authenticated sender metadata from the host. |
| #260 unit fields and cxc loop check | PROPOSAL | defer | Fields would be dropped by the reviver today (goalplan.ts:548); the external-wait part is covered by #262's decision links. |
| #261 reviewer panel per round | PROPOSAL | decline | Turning lanes and synthesis into gates reverses the deliberate non-blocking review round (orchestrate-cli.ts:65); parallel reviewers already work under guidance. |
| #262 pending decisions in goalplans | PROPOSAL | implement (030) | Opt-in plan-local record; readiness derives waits from open decisions. |
| #263 PreCompact checkpoint hook | PROPOSAL | defer | Codex supports PreCompact (hooks/src/schema.rs:347), but the proposal adds several stores; revisit after #255 settles cwd writes. |
| #264 measured-state snapshot after compaction | PROPOSAL | defer | Readers map absence to defaults (state.ts:486) and bg listing writes corrections (registry.ts:110-154); needs a strict read contract first. |
| #265 on-disk progress checkpoint for workers | PROPOSAL | guidance only (021) | Useful as a packet convention; a new CLI verb is not needed yet. |
| #266 host hygiene doctor | PROPOSAL | defer | Process ownership across platforms is not establishable; bg reconcile writes (registry.ts:106-146). |
| #267 suggested wave width | PROPOSAL | defer | Family, native limit and open-child count are not observable at SessionStart (dispatch-card.ts:24-36). |
| #268 compact-at-clean-boundary advisory | PROPOSAL | defer | No token usage parsing exists and Stop systemMessage display is unverified (stop.rs:288). |

Declined and deferred issues stay open with a comment linking this record, except #261, which is closed as declined. #255 also stays open after its partial `.gitignore` fix, with the PR linked and lazy creation deferred.

## Agent-created thread permissions (no issue)

Measured on this Mac on 2026-09-27. Rollouts with `thread_source=agent_created_thread` started with `approval_policy=on-request` and `workspace-write` in 7 of about 356 September cases (plus 8 archived on 09-23), including a projectless thread on 09-27, while their parents ran `never` with `danger-full-access`. The Desktop per-thread store held 5 `:workspace` entries out of 1,159. The only command-approval responses in the retained Desktop logs (05:06 and 08:53 UTC on 09-27) came from such children; thread `01a0e145` contains the exact `git fetch origin dev --quiet` command approved at 08:53. Subagents followed their parent in every case (5,336 never to never, 40 on-request to on-request). Codex runs PermissionRequest hooks before the user approval UI (codex-rs/core/src/tools/approvals.rs:505-525), and the bundled runtime 0.158.0-alpha.2.1 contains that path. Upstream: openai/codex #33282, #40793, #41167.
Loading
Loading