Skip to content

Commit 44cc0b7

Browse files
zenusclaude
andcommitted
Migrate bitlesson and config infrastructure to staging branch
Cherry-pick bitlesson workflow, config-loader, model-router, and config-driven defaults from feat/rlcr-loop-improvements (e3af54c) onto origin/dev (1267861) via staging worktree. 29 files: 10 A-class (whole-file bitlesson), 7 B-class (config infra), 2 D-class (new test files), 10 C-class (mixed hunks extracted). Excludes non-bitlesson/config changes (codex-worker, continue-rlcr-loop, ask-codex routing, gen-plan template, etc.). All 8 test suites pass (88 tests, 0 failures). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1267861 commit 44cc0b7

29 files changed

Lines changed: 3873 additions & 178 deletions

.gitignore

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
# Scratchpad
22
temp
33

4-
# Humanize state directories (used by start-rlcr-loop)
5-
.humanize*
4+
# Local Claude client settings
5+
/.claude/settings.json
6+
7+
# Humanize state directories (runtime-generated, project-local)
8+
.humanize/
9+
10+
# Project-level bitlesson knowledge base (runtime-generated, project-local)
11+
/bitlesson.md
612

713
# Python cache
814
__pycache__/

agents/bitlesson-selector.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
name: bitlesson-selector
3+
description: Selects required BitLesson entries for a specific sub-task. Use before execution for every task or sub-task.
4+
model: haiku
5+
tools: Read, Grep
6+
---
7+
8+
# BitLesson Selector
9+
10+
You select which lessons from `bitlesson.md` must be applied for a given sub-task.
11+
12+
## Input
13+
14+
You will receive:
15+
- Current sub-task description
16+
- Related file paths
17+
- The project `bitlesson.md` content
18+
19+
## Cross-Agent Review Context
20+
21+
- This agent markdown serves as the prompt specification for BitLesson selection.
22+
- Runtime execution happens via `scripts/bitlesson-select.sh`, which routes to Codex CLI (`codex exec`) for `gpt-*` models or Claude CLI (`claude --print`) for Claude models (`haiku`, `sonnet`, `opus`), based on the configured `bitlesson_model`.
23+
- Your lesson selection will be consumed by Claude and can be reviewed by Codex in later rounds.
24+
- Return deterministic output so cross-agent review can validate your decision quickly.
25+
26+
## Decision Rules
27+
28+
1. Match only lessons that are directly relevant to the sub-task scope and failure mode.
29+
2. Prefer precision over recall: do not include weakly related lessons.
30+
3. If nothing is relevant, return `NONE`.
31+
32+
## Output Format (Stable)
33+
34+
Return exactly:
35+
36+
```text
37+
LESSON_IDS: <comma-separated lesson IDs or NONE>
38+
RATIONALE: <one concise sentence>
39+
```
40+
41+
No extra sections.

commands/start-rlcr-loop.md

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ If the pre-check passed (or was skipped), execute the setup script to initialize
6868
This command starts an iterative development loop where:
6969

7070
1. You execute the implementation plan with task-tag routing
71-
- `coding` tasks: Claude executes directly
72-
- `analyze` tasks: execute via `/humanize:ask-codex`
71+
- `coding` tasks: execute via the configured coding worker (see `coding_worker_model` config key)
72+
- `analyze` tasks: execute via the configured analyzing worker (see `analyzing_worker_model` config key)
7373
2. Write a summary of your work to the specified summary file
7474
3. When you try to exit, Codex reviews your summary
7575
4. If Codex finds issues, you receive feedback and continue
@@ -89,7 +89,7 @@ This loop uses a **Goal Tracker** to prevent goal drift across iterations:
8989
### Key Features
9090
1. **Acceptance Criteria**: Each task maps to a specific AC - nothing can be "forgotten"
9191
2. **Task Tag Routing**: Every task should carry `coding` or `analyze` tag from plan generation
92-
- `coding -> Claude`, `analyze -> Codex`
92+
- `coding -> worker`, `analyze -> analyzer`
9393
3. **Plan Evolution Log**: If you discover the plan needs changes, document the change with justification
9494
4. **Explicit Deferrals**: Deferred tasks require strong justification and impact analysis
9595
5. **Full Alignment Checks**: At configurable intervals (default every 5 rounds: rounds 4, 9, 14, etc.), Codex conducts a comprehensive goal alignment audit. Use `--full-review-round N` to customize (min: 2)
@@ -106,6 +106,21 @@ This loop uses a **Goal Tracker** to prevent goal drift across iterations:
106106
3. **Be thorough**: Include details about what was implemented, files changed, and tests added
107107
4. **No cheating**: Do not try to exit the loop by editing state files or running cancel commands
108108
5. **Trust the process**: Codex's feedback helps improve the implementation
109+
6. **Delegated agent context is mandatory**: Every delegated agent call must explicitly mention the worker/reviewer relationship and that review is **independent** (cross-vendor style), even if all models are OpenAI today.
110+
111+
## BitLesson Workflow (Project Level)
112+
113+
Each project must maintain its own `.humanize/bitlesson.md` file.
114+
If missing, `start-rlcr-loop` initializes it automatically with a strict template.
115+
116+
Per round requirements:
117+
1. Read `.humanize/bitlesson.md` before execution
118+
2. Run `bitlesson-selector` for each task/sub-task
119+
3. Apply selected lesson IDs (or `NONE`) during implementation
120+
4. Include `## BitLesson Delta` in the round summary with `Action: none|add|update`
121+
122+
If a problem is solved only after multiple rounds, add or update a precise lesson entry in `.humanize/bitlesson.md` (specific problem + specific solution).
123+
By default, empty `.humanize/bitlesson.md` does not block `Action: none`; use `--require-bitlesson-entry-for-none` to enforce strict blocking.
109124

110125
## Stopping the Loop
111126

@@ -117,7 +132,7 @@ This loop uses a **Goal Tracker** to prevent goal drift across iterations:
117132

118133
The RLCR loop has two phases within the active loop:
119134

120-
1. **Implementation Phase**: Work by task tags (`coding -> Claude`, `analyze -> /humanize:ask-codex`), then Codex reviews your summary
135+
1. **Implementation Phase**: Work by task tags (`coding -> configured coding worker via coding_worker_model`, `analyze -> configured analyzing worker via analyzing_worker_model`), then Codex reviews your summary
121136
2. **Review Phase**: After COMPLETE, `codex review` checks code quality with `[P0-9]` severity markers
122137

123138
The `--base-branch` option specifies the base branch for code review comparison. If not provided, it auto-detects from: remote default > local main > local master.

config/default_config.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"coding_worker_model": "gpt-5.3-codex",
3+
"coding_worker_effort": "xhigh",
4+
"analyzing_worker_model": "gpt-5.2",
5+
"analyzing_worker_effort": "xhigh",
6+
"task_reviewer_model": "gpt-5.2",
7+
"task_reviewer_effort": "xhigh",
8+
"loop_reviewer_model": "gpt-5.2",
9+
"loop_reviewer_effort": "high",
10+
"bitlesson_model": "haiku",
11+
"agent_teams": false,
12+
"chinese_plan": false,
13+
"gen_plan_mode": "discussion",
14+
"coding_worker": "Codex worker (via configured coding_worker_model)",
15+
"analyzing_worker": "Codex (via configured analyzing_worker_model)",
16+
"reviewer": "Codex reviewer (via configured task_reviewer_model)"
17+
}

hooks/lib/loop-common.sh

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,19 @@ readonly FIELD_FULL_REVIEW_ROUND="full_review_round"
3838
readonly FIELD_ASK_CODEX_QUESTION="ask_codex_question"
3939
readonly FIELD_SESSION_ID="session_id"
4040
readonly FIELD_AGENT_TEAMS="agent_teams"
41+
readonly FIELD_DELEGATION_ENFORCEMENT="delegation_enforcement"
42+
readonly FIELD_LOOP_REVIEWER_EFFORT="loop_reviewer_effort"
4143

42-
# Default Codex configuration (single source of truth - all scripts reference this)
44+
# Default Codex configuration (from merged config during library setup).
4345
# Both use :- so scripts can override before sourcing (e.g. PR loop sets different model/effort).
44-
#
45-
# Default model for Codex operations (same model for both plugin and skill mode)
46-
DEFAULT_CODEX_MODEL="${DEFAULT_CODEX_MODEL:-gpt-5.4}"
47-
DEFAULT_CODEX_EFFORT="${DEFAULT_CODEX_EFFORT:-high}"
46+
DEFAULT_CODEX_MODEL="${DEFAULT_CODEX_MODEL:-}"
47+
DEFAULT_CODEX_EFFORT="${DEFAULT_CODEX_EFFORT:-}"
48+
DEFAULT_LOOP_REVIEWER_MODEL="${DEFAULT_LOOP_REVIEWER_MODEL:-}"
49+
DEFAULT_LOOP_REVIEWER_EFFORT="${DEFAULT_LOOP_REVIEWER_EFFORT:-}"
50+
51+
# Default worker configuration (used by /humanize:codex-worker).
52+
DEFAULT_CODEX_WORKER_MODEL="${DEFAULT_CODEX_WORKER_MODEL:-}"
53+
DEFAULT_CODEX_WORKER_EFFORT="${DEFAULT_CODEX_WORKER_EFFORT:-}"
4854

4955
# Codex review markers
5056
readonly MARKER_COMPLETE="COMPLETE"
@@ -157,6 +163,48 @@ is_deeply_nested() {
157163

158164
# Source template loader
159165
LOOP_COMMON_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"
166+
LOOP_COMMON_PLUGIN_ROOT="$(cd "$LOOP_COMMON_DIR/../.." && pwd)"
167+
export PLUGIN_ROOT="${PLUGIN_ROOT:-$LOOP_COMMON_PLUGIN_ROOT}"
168+
169+
_lc_errexit=false; [[ -o errexit ]] && _lc_errexit=true
170+
_lc_nounset=false; [[ -o nounset ]] && _lc_nounset=true
171+
_lc_pipefail=false; [[ -o pipefail ]] && _lc_pipefail=true
172+
source "$LOOP_COMMON_PLUGIN_ROOT/scripts/lib/config-loader.sh"
173+
$_lc_errexit && set -e || set +e
174+
$_lc_nounset && set -u || set +u
175+
$_lc_pipefail && set -o pipefail || set +o pipefail
176+
unset _lc_errexit _lc_nounset _lc_pipefail
177+
178+
_LOOP_COMMON_PROJECT_ROOT="${CLAUDE_PROJECT_DIR:-$(pwd)}"
179+
# Config loading is best-effort: callers like setup-rlcr-loop.sh have their own
180+
# authoritative dependency checks (jq, codex) that produce clear error messages.
181+
# Suppress stderr to avoid noisy intermediate errors (e.g., "jq: command not found")
182+
# before the caller's check runs, and use || true so a config-load failure does not
183+
# abort sourcing before those checks are reached.
184+
_LOOP_COMMON_CONFIG="$(load_merged_config "$LOOP_COMMON_PLUGIN_ROOT" "$_LOOP_COMMON_PROJECT_ROOT" 2>/dev/null)" || true
185+
186+
_cfg_analyzing_model="$(get_config_value "$_LOOP_COMMON_CONFIG" analyzing_worker_model 2>/dev/null || jq -r '.analyzing_worker_model // empty' "$LOOP_COMMON_PLUGIN_ROOT/config/default_config.json" 2>/dev/null || true)"
187+
_cfg_analyzing_effort="$(get_config_value "$_LOOP_COMMON_CONFIG" analyzing_worker_effort 2>/dev/null || jq -r '.analyzing_worker_effort // empty' "$LOOP_COMMON_PLUGIN_ROOT/config/default_config.json" 2>/dev/null || true)"
188+
_cfg_coding_model="$(get_config_value "$_LOOP_COMMON_CONFIG" coding_worker_model 2>/dev/null || jq -r '.coding_worker_model // empty' "$LOOP_COMMON_PLUGIN_ROOT/config/default_config.json" 2>/dev/null || true)"
189+
_cfg_coding_effort="$(get_config_value "$_LOOP_COMMON_CONFIG" coding_worker_effort 2>/dev/null || jq -r '.coding_worker_effort // empty' "$LOOP_COMMON_PLUGIN_ROOT/config/default_config.json" 2>/dev/null || true)"
190+
_cfg_reviewer_model="$(get_config_value "$_LOOP_COMMON_CONFIG" loop_reviewer_model 2>/dev/null || jq -r '.loop_reviewer_model // empty' "$LOOP_COMMON_PLUGIN_ROOT/config/default_config.json" 2>/dev/null || true)"
191+
_cfg_reviewer_effort="$(get_config_value "$_LOOP_COMMON_CONFIG" loop_reviewer_effort 2>/dev/null || jq -r '.loop_reviewer_effort // empty' "$LOOP_COMMON_PLUGIN_ROOT/config/default_config.json" 2>/dev/null || true)"
192+
193+
# Default analyzer configuration (used by codex analyzing/review worker flows).
194+
# Hard fallbacks guard against jq being absent or config loading failing entirely;
195+
# the literals here must match the values in config/default_config.json.
196+
DEFAULT_CODEX_MODEL="${DEFAULT_CODEX_MODEL:-${_cfg_analyzing_model:-gpt-5.2}}"
197+
DEFAULT_CODEX_EFFORT="${DEFAULT_CODEX_EFFORT:-${_cfg_analyzing_effort:-xhigh}}"
198+
199+
# Default worker configuration (used by /humanize:codex-worker).
200+
DEFAULT_CODEX_WORKER_MODEL="${DEFAULT_CODEX_WORKER_MODEL:-${_cfg_coding_model:-gpt-5.3-codex}}"
201+
DEFAULT_CODEX_WORKER_EFFORT="${DEFAULT_CODEX_WORKER_EFFORT:-${_cfg_coding_effort:-xhigh}}"
202+
DEFAULT_LOOP_REVIEWER_MODEL="${DEFAULT_LOOP_REVIEWER_MODEL:-${_cfg_reviewer_model:-gpt-5.2}}"
203+
DEFAULT_LOOP_REVIEWER_EFFORT="${DEFAULT_LOOP_REVIEWER_EFFORT:-${_cfg_reviewer_effort:-high}}"
204+
205+
unset _cfg_analyzing_model _cfg_analyzing_effort _cfg_coding_model _cfg_coding_effort _cfg_reviewer_model _cfg_reviewer_effort
206+
unset _LOOP_COMMON_PROJECT_ROOT _LOOP_COMMON_CONFIG
207+
160208
source "$LOOP_COMMON_DIR/template-loader.sh"
161209

162210
# Initialize template directory (can be overridden by sourcing script)
@@ -330,6 +378,8 @@ _parse_state_fields() {
330378
STATE_ASK_CODEX_QUESTION=$(echo "$STATE_FRONTMATTER" | grep "^${FIELD_ASK_CODEX_QUESTION}:" | sed "s/${FIELD_ASK_CODEX_QUESTION}: *//" | tr -d ' ' || true)
331379
STATE_SESSION_ID=$(echo "$STATE_FRONTMATTER" | grep "^${FIELD_SESSION_ID}:" | sed "s/${FIELD_SESSION_ID}: *//" || true)
332380
STATE_AGENT_TEAMS=$(echo "$STATE_FRONTMATTER" | grep "^${FIELD_AGENT_TEAMS}:" | sed "s/${FIELD_AGENT_TEAMS}: *//" | tr -d ' ' || true)
381+
STATE_DELEGATION_ENFORCEMENT=$(echo "$STATE_FRONTMATTER" | grep "^${FIELD_DELEGATION_ENFORCEMENT}:" | sed "s/${FIELD_DELEGATION_ENFORCEMENT}: *//" | tr -d ' ' || true)
382+
STATE_LOOP_REVIEWER_EFFORT=$(echo "$STATE_FRONTMATTER" | grep "^${FIELD_LOOP_REVIEWER_EFFORT}:" | sed "s/${FIELD_LOOP_REVIEWER_EFFORT}: *//" | tr -d ' ' || true)
333383
}
334384

335385
# Parse state file frontmatter and set variables (tolerant mode with defaults)
@@ -349,6 +399,8 @@ _parse_state_fields() {
349399
# STATE_REVIEW_STARTED - "true" or "false"
350400
# STATE_FULL_REVIEW_ROUND - interval for Full Alignment Check (default: 5)
351401
# STATE_ASK_CODEX_QUESTION - "true" or "false" (v1.6.5+)
402+
# STATE_AGENT_TEAMS - "true" or "false"
403+
# STATE_DELEGATION_ENFORCEMENT - "warn" or "strict"
352404
# Returns: 0 on success, 1 if file not found
353405
# Note: For strict validation, use parse_state_file_strict() instead
354406
parse_state_file() {
@@ -371,6 +423,7 @@ parse_state_file() {
371423
STATE_FULL_REVIEW_ROUND="${STATE_FULL_REVIEW_ROUND:-5}"
372424
STATE_ASK_CODEX_QUESTION="${STATE_ASK_CODEX_QUESTION:-true}"
373425
STATE_AGENT_TEAMS="${STATE_AGENT_TEAMS:-false}"
426+
STATE_DELEGATION_ENFORCEMENT="${STATE_DELEGATION_ENFORCEMENT:-warn}"
374427
# STATE_REVIEW_STARTED left as-is (empty if missing, to allow schema validation)
375428

376429
return 0
@@ -446,6 +499,7 @@ parse_state_file_strict() {
446499
STATE_FULL_REVIEW_ROUND="${STATE_FULL_REVIEW_ROUND:-5}"
447500
STATE_ASK_CODEX_QUESTION="${STATE_ASK_CODEX_QUESTION:-true}"
448501
STATE_AGENT_TEAMS="${STATE_AGENT_TEAMS:-false}"
502+
STATE_DELEGATION_ENFORCEMENT="${STATE_DELEGATION_ENFORCEMENT:-warn}"
449503

450504
return 0
451505
}

0 commit comments

Comments
 (0)