Commit f6fe8355 authored by whlwhlwhl's avatar whlwhlwhl
Browse files

Initial LightOp KernelPilot skill pack

parents
Pipeline #3628 canceled with stages
**Optional fallback**: if you could not safely update the mutable section of `goal-tracker.md` directly, include this section in your summary:
```markdown
## Goal Tracker Update Request
### Requested Changes:
- [E.g., "Mark Task X as completed with evidence: tests pass"]
- [E.g., "Add to Blocking Side Issues: bug Y blocks AC-2"]
- [E.g., "Add to Queued Side Issues: cleanup Z is non-blocking"]
- [E.g., "Plan Evolution: changed approach from A to B because..."]
- [E.g., "Defer Task Z because... (impact on AC: none/minimal)"]
### Justification:
[Explain why these changes are needed and how they serve the Ultimate Goal]
```
Codex will review your request and reconcile the Goal Tracker if justified.
# Methodology Analysis Phase
The RLCR loop has reached its exit point.
**Exit reason**: {{EXIT_REASON}} - {{EXIT_REASON_DESCRIPTION}}
**Rounds completed**: {{CURRENT_ROUND}} of {{MAX_ITERATIONS}}
Before the loop fully exits, please perform a methodology improvement analysis. This analysis helps improve the Humanize development methodology itself -- it is NOT about the project you just worked on.
## Instructions
### 1. Spawn an Opus Agent for Sanitized Analysis
Use the Agent tool with `model: "opus"` to spawn an analysis agent. Give it this task:
**Agent prompt**: Read the development records in `{{LOOP_DIR}}`:
- All files matching `round-*-summary.md`
- All files matching `round-*-review-result.md`
Analyze these records from a **pure methodology perspective** and write your findings to `{{LOOP_DIR}}/methodology-analysis-report.md`.
**CRITICAL SANITIZATION RULES** - The report MUST NOT contain:
- File paths, directory paths, or module paths
- Function names, variable names, class names, or method names
- Branch names, commit hashes, or git identifiers
- Business domain terms, product names, or feature names
- Code snippets or code fragments of any kind
- Raw error messages or stack traces
- Project-specific URLs or endpoints
- Any information that could identify the specific project
**Focus areas for analysis**:
- Iteration efficiency: Were rounds productive or did they repeat similar work?
- Feedback loop quality: Did reviewer feedback lead to meaningful improvements?
- Stagnation patterns: Were there signs of going in circles?
- Review effectiveness: Did reviews catch real issues or create false positives?
- Plan-to-execution alignment: Did execution follow the plan or drift?
- Round count vs. progress ratio: Was the number of rounds proportional to progress?
- Communication clarity: Were summaries and reviews clear and actionable?
**Output format**: Write a structured report with methodology improvement suggestions. Each suggestion should describe a general pattern observed and a concrete improvement to the RLCR methodology. If no improvements are found, write a brief note saying the methodology worked well for this session.
### 2. Read the Analysis Report
After the agent completes, read `{{LOOP_DIR}}/methodology-analysis-report.md`. ALL subsequent user-facing content MUST be derived solely from this report -- do NOT reference raw development records directly.
### 3. Handle Results
**If no improvements found**: Briefly inform the user that the methodology analysis found no significant improvement suggestions. Then write a completion note to `{{LOOP_DIR}}/methodology-analysis-done.md` and exit.
**If improvements found**:
a) Report to the user:
- Brief summary of the exit reason ({{EXIT_REASON}}: {{EXIT_REASON_DESCRIPTION}})
- Methodology improvement suggestions from the report
b) Use `AskUserQuestion` to ask if the user would like to help improve Humanize by opening a GitHub issue with these suggestions. Emphasize:
- This is completely voluntary
- The content is fully sanitized (no project-specific information)
- It helps improve the methodology for everyone
c) **If user declines**: Thank them, write completion marker to `{{LOOP_DIR}}/methodology-analysis-done.md`, and exit.
d) **If user agrees**:
- Draft a GitHub issue title and body from the analysis report
- Show the draft via a second `AskUserQuestion` for the user to review and confirm
- If confirmed: run `gh issue create --repo PolyArch/humanize --title "..." --body "..."`
- If `gh` is not available, provide the title and body so the user can create the issue manually
- Write completion marker to `{{LOOP_DIR}}/methodology-analysis-done.md` and exit
### 4. Completion Marker
You MUST write meaningful content to `{{LOOP_DIR}}/methodology-analysis-done.md` before exiting. This file signals that the analysis phase is complete. A brief summary of what was done (e.g., "Analysis complete, no suggestions" or "Analysis complete, issue filed") is sufficient.
---
Note: You MUST NOT try to exit by lying, editing loop state files, or executing `cancel-rlcr-loop`.
After completing the work, please:
0. If the `code-simplifier` plugin is installed, use it to review and optimize your code. Invoke via: `/code-simplifier`, `@agent-code-simplifier`, or `@code-simplifier:code-simplifier (agent)`
1. Commit your changes with a descriptive commit message
2. Write your work summary into @{{NEXT_SUMMARY_FILE}}
Your work is not finished. Read and execute the below with ultrathink.
## Original Implementation Plan
**IMPORTANT**: Before proceeding, review the original plan you are implementing:
@{{PLAN_FILE}}
This plan contains the full scope of work and requirements. Ensure your work aligns with this plan.
---
## Round Re-anchor (REQUIRED FIRST STEP)
Before writing code:
- Re-read @{{PLAN_FILE}}
- Re-read @{{GOAL_TRACKER_FILE}}
- Re-read the most recent round summaries/reviews that led to this round
- Write the current round contract to @{{ROUND_CONTRACT_FILE}}
Your round contract must contain:
- Exactly one **mainline objective**
- The 1-2 target ACs for this round
- Which issues are truly **blocking** that mainline objective
- Which issues are **queued** and explicitly out of scope
- Concrete success criteria for this round
Do not start implementation until the round contract exists.
## Task Lane Rules
Use the Task system (TaskCreate, TaskUpdate, TaskList) with one required tag per task:
- `[mainline]` for plan-derived work that directly advances this round's objective
- `[blocking]` for issues that prevent the mainline objective from succeeding safely
- `[queued]` for non-blocking bugs, cleanup, or follow-up work
Rules:
- `[mainline]` work is the round's primary success condition
- `[blocking]` work is allowed only when it truly blocks the mainline objective
- `[queued]` work must be documented but must NOT replace the round objective
- If a new bug does not block the current objective, tag it `[queued]` and keep moving on mainline work
Before executing each task in this round:
1. Read @{{BITLESSON_FILE}}
2. Run `bitlesson-selector` for each task/sub-task
3. Follow selected lesson IDs (or `NONE`) during implementation
---
Below is Codex's review result:
<!-- CODEX's REVIEW RESULT START -->
{{REVIEW_CONTENT}}
<!-- CODEX's REVIEW RESULT END -->
---
## Goal Tracker Reference
Before starting work, **read** @{{GOAL_TRACKER_FILE}} to understand:
- The Ultimate Goal and Acceptance Criteria you're working toward
- Which tasks are Active, Completed, or Deferred
- Which side issues are blocking vs queued
- Any Plan Evolution that has occurred
- The latest side-issue state that needs attention
**IMPORTANT**: Keep the mutable section of `goal-tracker.md` up to date during the round.
Do NOT change the immutable section after Round 0.
If you cannot safely reconcile the tracker yourself, include an optional "Goal Tracker Update Request" section in your summary (see below).
## Mainline Guardrails
- Keep the mainline objective from @{{ROUND_CONTRACT_FILE}} stable for this round
- Do not let queued issues take over the round
- If Codex reported several findings, classify them into:
- mainline gaps
- blocking side issues
- queued side issues
- Only mainline gaps and blocking side issues should drive the next code changes
**IMPORTANT**: Codex has found Open Question(s). You must use `AskUserQuestion` to clarify those questions with user first, before proceeding to resolve any other Codex's findings.
### Post-Alignment Check Action Items
This round follows a Full Goal Alignment Check. Pay special attention to:
- **Forgotten Items**: Codex may have identified tasks that were being ignored. Address them.
- **AC Status**: If any Acceptance Criteria were marked NOT MET, prioritize work toward those.
- **Deferred Items**: If any deferrals were flagged as unjustified, un-defer them now.
- **Queued Issues**: Keep non-blocking follow-up work queued unless it now clearly blocks mainline progress.
Note: Since `--push-every-round` is enabled, you must push your commits to remote after each round.
# Code Review Findings
You are in the **Review Phase**. Codex has performed a code review and found issues that need to be addressed.
## Required Re-anchor
Before touching code:
- Re-read the original plan at @{{PLAN_FILE}}
- Re-read the goal tracker at @{{GOAL_TRACKER_FILE}}
- Refresh the current round contract at @{{ROUND_CONTRACT_FILE}}
The round contract must preserve a single mainline objective. Code review findings do NOT automatically become the new round objective.
## Review Results
{{REVIEW_CONTENT}}
## Issue Classification
Classify each review finding before acting on it:
- **blocking side issue**: prevents the current mainline objective from succeeding safely or prevents review acceptance
- **queued side issue**: valid follow-up, but does not block the current round objective
Queued issues may be documented, but they must NOT take over the round.
## Task Rules
Every task must use one lane tag:
- `[blocking]` for review findings that must be fixed now
- `[queued]` for non-blocking follow-up work
Do not create new `[mainline]` tasks in review phase unless the review proves the previous mainline objective was incomplete.
## Instructions
1. **Refresh the round contract** at `{{ROUND_CONTRACT_FILE}}`
2. **Address blocking issues first** and keep the mainline objective stable
3. **Focus on fixes only** - do not add new features or make unrelated changes
4. **Commit your changes** after fixing the issues
5. **Write your summary** to: `{{SUMMARY_FILE}}`
## Summary Template
Your summary should include:
- The mainline objective for this round
- Which blocking issues were fixed
- Which issues were reclassified as queued follow-up
- How each fixed issue was resolved
- Any issues that could not be resolved (with explanation)
- Confirmation that `goal-tracker.md` was updated if the blocking/queued issue lists changed
- A Goal Tracker Update Request only if tracker reconciliation still needs Codex help
## Important Notes
- The COMPLETE signal has no effect during the review phase
- You must address the code review findings to proceed
- After you commit and write your summary, Codex will perform another code review
- The loop continues until no `[P0-9]` issues are found
# Code Review Phase - Round {{REVIEW_ROUND}}
This file documents the code review invocation for audit purposes.
Note: `codex review` does not accept prompt input; it performs automated code review based on git diff.
## Review Configuration
- **Base Branch**: {{BASE_BRANCH}}
- **Review Round**: {{REVIEW_ROUND}}
- **Timestamp**: {{TIMESTAMP}}
## What This Phase Does
1. Runs `codex review --base {{BASE_BRANCH}}` to perform automated code review
2. Scans output for `[P0-9]` severity markers indicating issues
3. If issues found: Returns fix prompt to Claude for remediation
4. If no issues: Transitions to Finalize Phase
## Expected Output Format
Codex review outputs issues in this format:
```
- [P0] Critical issue description - /path/to/file.py:line-range
Detailed explanation of the issue.
- [P1] High priority issue - /path/to/file.py:line-range
Detailed explanation.
```
## Files Generated
- `round-{{REVIEW_ROUND}}-review-prompt.md` - This audit file
- `round-{{REVIEW_ROUND}}-review-result.md` - Review output (in loop directory)
- `round-{{REVIEW_ROUND}}-codex-review.cmd` - Command invocation (in cache)
- `round-{{REVIEW_ROUND}}-codex-review.out` - Stdout capture (in cache)
- `round-{{REVIEW_ROUND}}-codex-review.log` - Stderr capture (in cache)
## Development History (Integral Context)
Accumulated commits since loop start (oldest first):
```
{{COMMIT_HISTORY}}
```
### Recent Round Files
Read these files before conducting your review to understand the trajectory of work:
{{RECENT_ROUND_FILES}}
Use this history to identify patterns across rounds: recurring issues, stalled progress, or drift from the mainline objective. Weight recent rounds more heavily but watch for systemic trends in the full commit log.
# FULL GOAL ALIGNMENT CHECK - Round {{CURRENT_ROUND}}
This is a **mandatory checkpoint** (at configurable intervals). You must conduct a comprehensive goal alignment audit.
## Original Implementation Plan
**IMPORTANT**: The original plan that Claude is implementing is located at:
@{{PLAN_FILE}}
You MUST read this plan file first to understand the full scope of work before conducting your review.
---
## Claude's Work Summary
<!-- CLAUDE's WORK SUMMARY START -->
{{SUMMARY_CONTENT}}
<!-- CLAUDE's WORK SUMMARY END -->
---
{{COMMIT_HISTORY_SECTION}}
## Part 1: Goal Tracker Audit (MANDATORY)
Read @{{GOAL_TRACKER_FILE}} and verify:
### 1.1 Acceptance Criteria Status
For EACH Acceptance Criterion in the IMMUTABLE SECTION:
| AC | Status | Evidence (if MET) | Blocker (if NOT MET) | Justification (if DEFERRED) |
|----|--------|-------------------|---------------------|----------------------------|
| AC-1 | MET / PARTIAL / NOT MET / DEFERRED | ... | ... | ... |
| ... | ... | ... | ... | ... |
### 1.2 Forgotten Items Detection
Compare the original plan (@{{PLAN_FILE}}) with the current goal-tracker:
- Are there tasks that are neither in "Active", "Completed", nor "Deferred"?
- Are there tasks marked "complete" in summaries but not verified?
- List any forgotten items found.
### 1.3 Deferred Items Audit
For each item in "Explicitly Deferred":
- Is the deferral justification still valid?
- Should it be un-deferred based on current progress?
- Does it contradict the Ultimate Goal?
### 1.4 Goal Completion Summary
```
Acceptance Criteria: X/Y met (Z deferred)
Active Tasks: N remaining
Estimated remaining rounds: ?
Critical blockers: [list if any]
```
## Part 2: Mainline Drift Audit (MANDATORY)
Determine whether the recent rounds are still serving the original plan:
- Is the current round's mainline objective clear and singular?
- Has Claude been advancing mainline ACs, or mostly clearing side issues?
- Which findings are true **blocking side issues** versus merely **queued side issues**?
Include a short drift summary:
```
Mainline Progress Verdict: ADVANCED / STALLED / REGRESSED
Blocking Side Issues: N
Queued Side Issues: N
```
The `Mainline Progress Verdict` line is mandatory. If you omit it, the Humanize stop hook will block the round and require the review to be rerun.
## Part 3: Implementation Review
- Conduct a deep critical review of the implementation
- Verify Claude's claims match reality
- Identify any gaps, bugs, or incomplete work
- Reference @{{DOCS_PATH}} for design documents
## Part 4: {{GOAL_TRACKER_UPDATE_SECTION}}
## Part 5: Progress Stagnation Check (MANDATORY for Full Alignment Rounds)
To implement the original plan at @{{PLAN_FILE}}, we have completed **{{COMPLETED_ITERATIONS}} iterations** (Round 0 to Round {{CURRENT_ROUND}}).
The project's `.humanize/rlcr/{{LOOP_TIMESTAMP}}/` directory contains the history of each round's iteration:
- Round input prompts: `round-N-prompt.md`
- Round output summaries: `round-N-summary.md`
- Round review prompts: `round-N-review-prompt.md`
- Round review results: `round-N-review-result.md`
**How to Access Historical Files**: Read the historical review results and summaries using file paths like:
- `@.humanize/rlcr/{{LOOP_TIMESTAMP}}/round-{{PREV_ROUND}}-review-result.md` (previous round)
- `@.humanize/rlcr/{{LOOP_TIMESTAMP}}/round-{{PREV_PREV_ROUND}}-review-result.md` (2 rounds ago)
- `@.humanize/rlcr/{{LOOP_TIMESTAMP}}/round-{{PREV_ROUND}}-summary.md` (previous summary)
**Your Task**: Review the historical review results, especially the **recent rounds** of development progress and review outcomes, to determine if the development has stalled.
**Signs of Stagnation** (circuit breaker triggers):
- Same issues appearing repeatedly across multiple rounds
- No meaningful progress on Acceptance Criteria over several rounds
- Claude making the same mistakes repeatedly
- Circular discussions without resolution
- No new code changes despite continued iterations
- Codex giving similar feedback repeatedly without Claude addressing it
**If development is stagnating**, write **STOP** (as a single word on its own line) as the last line of your review output @{{REVIEW_RESULT_FILE}} instead of COMPLETE.
## Part 6: Output Requirements
- If issues found OR any AC is NOT MET (including deferred ACs), write your findings to @{{REVIEW_RESULT_FILE}}
- Include specific action items for Claude to address, classified into:
- Mainline Gaps
- Blocking Side Issues
- Queued Side Issues
- **If development is stagnating** (see Part 4), write "STOP" as the last line
- **CRITICAL**: Only write "COMPLETE" as the last line if ALL ACs from the original plan are FULLY MET with no deferrals
- DEFERRED items are considered INCOMPLETE - do NOT output COMPLETE if any AC is deferred
- The ONLY condition for COMPLETE is: all original plan tasks are done, all ACs are met, no deferrals allowed
## Goal Tracker Update Requests (YOUR RESPONSIBILITY)
Claude should normally keep the **mutable section** of `goal-tracker.md` up to date directly. If Claude's summary contains a "Goal Tracker Update Request" section, or if you detect tracker drift during review, YOU must:
1. **Evaluate the tracker state**: Is the mutable section still aligned with the Ultimate Goal and current AC progress?
2. **If correction is needed**: Update @{{GOAL_TRACKER_FILE}} yourself with the requested changes:
- Move tasks between Active/Completed/Deferred sections as appropriate
- Add entries to "Plan Evolution Log" with round number and justification
- Add new issues to "Blocking Side Issues" or "Queued Side Issues" as appropriate
- **NEVER modify the IMMUTABLE SECTION** (Ultimate Goal and Acceptance Criteria)
3. **If you reject a requested tracker change**: Include in your review why it was rejected
Common update requests you should handle:
- Task completion: Move from "Active Tasks" to "Completed and Verified"
- New blocking issues: Add to "Blocking Side Issues"
- New queued issues: Add to "Queued Side Issues"
- Plan changes: Add to "Plan Evolution Log" with your assessment
- Deferrals: Only allow with strong justification; add to "Explicitly Deferred"
# Code Review - Round {{CURRENT_ROUND}}
## Original Implementation Plan
**IMPORTANT**: The original plan that Claude is implementing is located at:
@{{PLAN_FILE}}
You MUST read this plan file first to understand the full scope of work before conducting your review.
This plan contains the complete requirements and implementation details that Claude should be following.
Based on the original plan and @{{PROMPT_FILE}}, Claude claims to have completed the work. Please conduct a thorough critical review to verify this.
---
Below is Claude's summary of the work completed:
<!-- CLAUDE's WORK SUMMARY START -->
{{SUMMARY_CONTENT}}
<!-- CLAUDE's WORK SUMMARY END -->
---
{{COMMIT_HISTORY_SECTION}}
## Part 1: Implementation Review
- Your task is to conduct a deep critical review, focusing on finding implementation issues and identifying gaps between "plan-design" and actual implementation.
- Relevant top-level guidance documents, phased implementation plans, and other important documentation and implementation references are located under @{{DOCS_PATH}}.
- If Claude planned to defer any tasks to future phases in its summary, DO NOT follow its lead. Instead, you should force Claude to complete ALL tasks as planned.
- Such deferred tasks are considered incomplete work and should be flagged in your review comments, requiring Claude to address them.
- If Claude planned to defer any tasks, please explore the codebase in-depth and draft a detailed implementation plan. This plan should be included in your review comments for Claude to follow.
- Your review should be meticulous and skeptical. Look for any discrepancies, missing features, incomplete implementations.
- If Claude does not plan to defer any tasks, but honestly admits that some tasks are still pending (not yet completed), you should also include those pending tasks in your review.
- Your review should elaborate on those unfinished tasks, explore the codebase, and draft an implementation plan.
- A good engineering implementation plan should be **singular, directive, and definitive**, rather than discussing multiple possible implementation options.
- The implementation plan should be **unambiguous**, internally consistent, and coherent from beginning to end, so that **Claude can execute the work accurately and without error**.
## Part 2: Goal Alignment Check (MANDATORY)
Read @{{GOAL_TRACKER_FILE}} and verify:
1. **Acceptance Criteria Progress**: For each AC, is progress being made? Are any ACs being ignored?
2. **Forgotten Items**: Are there tasks from the original plan that are not tracked in Active/Completed/Deferred?
3. **Deferred Items**: Are deferrals justified? Do they block any ACs?
4. **Plan Evolution**: If Claude modified the plan, is the justification valid?
Include a brief Goal Alignment Summary in your review:
```
ACs: X/Y addressed | Forgotten items: N | Unjustified deferrals: N
```
## Part 3: Required Finding Classification
You MUST classify your findings into these lanes:
- **Mainline Gaps**: plan-derived work or AC progress that is missing, incomplete, or regressing
- **Blocking Side Issues**: bugs or implementation issues that block the current mainline objective from succeeding safely
- **Queued Side Issues**: valid non-blocking follow-up issues that should be documented but must NOT take over the next round
Also include a one-line verdict:
```
Mainline Progress Verdict: ADVANCED / STALLED / REGRESSED
```
This verdict line is mandatory. If you omit it, the Humanize stop hook will block the round and require the review to be rerun.
If Claude mostly worked on queued side issues and failed to advance the mainline, say so explicitly.
## Part 4: {{GOAL_TRACKER_UPDATE_SECTION}}
## Part 5: Output Requirements
- In short, your review comments can include: problems/findings/blockers; claims that don't match reality; implementation plans for deferred work (to be implemented now); implementation plans for unfinished work; goal alignment issues.
- Your output should be structured so Claude can tell which items are mainline gaps, blocking side issues, and queued side issues.
- If after your investigation the actual situation does not match what Claude claims to have completed, or there is pending work to be done, output your review comments to @{{REVIEW_RESULT_FILE}}.
- **CRITICAL**: Only output "COMPLETE" as the last line if ALL tasks from the original plan are FULLY completed with no deferrals
- DEFERRED items are considered INCOMPLETE - do NOT output COMPLETE if any task is deferred
- UNFINISHED items are considered INCOMPLETE - do NOT output COMPLETE if any task is pending
- The ONLY condition for COMPLETE is: all original plan tasks are done, all ACs are met, no deferrals or pending work allowed
- The word COMPLETE on the last line will stop Claude.
# <TITLE>
## Original Idea
<ORIGINAL_IDEA>
## Primary Direction: <PRIMARY_NAME>
### Rationale
<PRIMARY_RATIONALE>
### Approach Summary
<PRIMARY_APPROACH_SUMMARY>
### Objective Evidence
<PRIMARY_OBJECTIVE_EVIDENCE>
### Known Risks
<PRIMARY_KNOWN_RISKS>
## Alternative Directions Considered
<ALTERNATIVES>
## Synthesis Notes
<SYNTHESIS_NOTES>
# <Plan Title>
## Goal Description
<Clear, direct description of what needs to be accomplished>
## Acceptance Criteria
Following TDD philosophy, each criterion includes positive and negative tests for deterministic verification.
- AC-1: <First criterion>
- Positive Tests (expected to PASS):
- <Test case that should succeed when criterion is met>
- <Another success case>
- Negative Tests (expected to FAIL):
- <Test case that should fail/be rejected when working correctly>
- <Another failure/rejection case>
- AC-1.1: <Sub-criterion if needed>
- Positive: <...>
- Negative: <...>
- AC-2: <Second criterion>
- Positive Tests: <...>
- Negative Tests: <...>
...
## Path Boundaries
Path boundaries define the acceptable range of implementation quality and choices.
### Upper Bound (Maximum Acceptable Scope)
<Affirmative description of the most comprehensive acceptable implementation>
<This represents completing the goal without over-engineering>
Example: "The implementation includes X, Y, and Z features with full test coverage"
### Lower Bound (Minimum Acceptable Scope)
<Affirmative description of the minimum viable implementation>
<This represents the least effort that still satisfies all acceptance criteria>
Example: "The implementation includes core feature X with basic validation"
### Allowed Choices
<Options that are acceptable for implementation decisions>
- Can use: <technologies, approaches, patterns that are allowed>
- Cannot use: <technologies, approaches, patterns that are prohibited>
> **Note on Deterministic Designs**: If the draft specifies a highly deterministic design with no choices (e.g., "must use JSON format", "must use algorithm X"), then the path boundaries should reflect this narrow constraint. In such cases, upper and lower bounds may converge to the same point, and "Allowed Choices" should explicitly state that the choice is fixed per the draft specification.
## Feasibility Hints and Suggestions
> **Note**: This section is for reference and understanding only. These are conceptual suggestions, not prescriptive requirements.
### Conceptual Approach
<Text description, pseudocode, or diagrams showing ONE possible implementation path>
### Relevant References
<Code paths and concepts that might be useful>
- <path/to/relevant/component> - <brief description>
## Dependencies and Sequence
### Milestones
1. <Milestone 1>: <Description>
- Phase A: <...>
- Phase B: <...>
2. <Milestone 2>: <Description>
- Step 1: <...>
- Step 2: <...>
<Describe relative dependencies between components, not time estimates>
## Task Breakdown
Each task must include exactly one routing tag:
- `coding`: implemented by Claude
- `analyze`: executed via Codex (`/humanize:ask-codex`)
| Task ID | Description | Target AC | Tag (`coding`/`analyze`) | Depends On |
|---------|-------------|-----------|----------------------------|------------|
| task1 | <...> | AC-1 | coding | - |
| task2 | <...> | AC-2 | analyze | task1 |
## Claude-Codex Deliberation
### Agreements
- <Point both sides agree on>
### Resolved Disagreements
- <Topic>: Claude vs Codex summary, chosen resolution, and rationale
### Convergence Status
- Final Status: `converged` or `partially_converged`
## Pending User Decisions
- DEC-1: <Decision topic>
- Claude Position: <...>
- Codex Position: <...>
- Tradeoff Summary: <...>
- Decision Status: `PENDING` or `<User's final decision>`
## Implementation Notes
### Code Style Requirements
- Implementation code and comments must NOT contain plan-specific terminology such as "AC-", "Milestone", "Step", "Phase", or similar workflow markers
- These terms are for plan documentation only, not for the resulting codebase
- Use descriptive, domain-appropriate naming in code instead
## Output File Convention
This template is used to produce the main output file (e.g., `plan.md`).
### Translated Language Variant
When `alternative_plan_language` resolves to a supported language name through merged config loading, a translated variant of the output file is also written after the main file. Humanize loads config from merged layers in this order: default config, optional user config, then optional project config; `alternative_plan_language` may be set at any of those layers. The variant filename is constructed by inserting `_<code>` (the ISO 639-1 code from the built-in mapping table) immediately before the file extension:
- `plan.md` becomes `plan_<code>.md` (e.g. `plan_zh.md` for Chinese, `plan_ko.md` for Korean)
- `docs/my-plan.md` becomes `docs/my-plan_<code>.md`
- `output` (no extension) becomes `output_<code>`
The translated variant file contains a full translation of the main plan file's current content in the configured language. All identifiers (`AC-*`, task IDs, file paths, API names, command flags) remain unchanged, as they are language-neutral.
When `alternative_plan_language` is empty, absent, set to `"English"`, or set to an unsupported language, no translated variant is written. Humanize does not auto-create `.humanize/config.json` when no project config file is present.
# Refine Plan QA
## Summary
<Brief overview of the refinement process: how many comments were processed, what types of changes were made, and the overall outcome>
## Comment Ledger
<Table tracking all extracted comments with their metadata and disposition>
| CMT-ID | Classification | Location | Original Text (excerpt) | Disposition |
|--------|----------------|----------|-------------------------|-------------|
| CMT-1 | question | AC-2 | "Why do we need..." | Answered in QA, light plan clarification added |
| CMT-2 | change_request | Task Breakdown | "Delete task 5..." | Applied to plan, cross-references updated |
| CMT-3 | research_request | Dependencies | "Investigate config..." | Research completed, findings integrated |
<Disposition values: "answered", "applied", "researched", "deferred", "resolved">
## Answers
<Responses to question-type comments>
### CMT-1: <Question summary>
**Original Comment:**
```
<Full original comment text>
```
**Answer:**
<Detailed explanation addressing the question>
**Plan Changes:**
<Description of any light edits made to clarify the plan, or "None" if only answered in QA>
---
## Research Findings
<Results from research_request-type comments>
### CMT-3: <Research topic summary>
**Original Comment:**
```
<Full original comment text>
```
**Research Scope:**
<What was investigated: files examined, patterns analyzed, existing implementations reviewed>
**Findings:**
<Key discoveries and their implications for the plan>
**Impact on Plan:**
<How the research findings were integrated into the refined plan, or why they were deferred>
---
## Plan Changes Applied
<Documentation of all modifications made to the plan from change_request-type comments>
### CMT-2: <Change summary>
**Original Comment:**
```
<Full original comment text>
```
**Changes Made:**
<Detailed description of what was modified in the plan>
**Affected Sections:**
<List of plan sections that were updated to maintain consistency>
- Acceptance Criteria: <specific changes>
- Task Breakdown: <specific changes>
- Dependencies and Sequence: <specific changes>
- Other: <specific changes>
**Cross-Reference Updates:**
<Any AC-X, task ID, or milestone references that were updated to maintain consistency>
---
## Remaining Decisions
<Unresolved items that require user input or further clarification>
### DEC-X: <Decision topic>
**Related Comments:** CMT-4, CMT-7
**Context:**
<Background and why this decision is needed>
**Options:**
1. <Option A>: <description, tradeoffs>
2. <Option B>: <description, tradeoffs>
**Recommendation:**
<Suggested approach with rationale, or "No clear recommendation" if options are equally viable>
**Status:** PENDING
---
## Refinement Metadata
- **Input Plan:** <path/to/input-plan.md>
- **Output Plan:** <path/to/refined-plan.md>
- **QA Document:** <path/to/qa-document.md>
- **Total Comments Processed:** <count>
- Questions: <count>
- Change Requests: <count>
- Research Requests: <count>
- **Plan Sections Modified:** <list of sections>
- **Convergence Status:** <converged | partially_converged>
- **Refinement Date:** <YYYY-MM-DD>
#!/usr/bin/env bash
#
# Ask Codex - One-shot consultation with Codex
#
# Sends a question or task to codex exec and returns the response.
# This is an active, one-shot skill (unlike the passive RLCR loop).
#
# Usage:
# ask-codex.sh [--codex-model MODEL:EFFORT] [--codex-timeout SECONDS] [question...]
#
# Output:
# stdout: Codex's response (for Claude to read)
# stderr: Status/debug info (model, effort, log paths)
#
# Storage:
# Project-local: .humanize/skill/<unique-id>/{input,output,metadata}.md
# Cache: ~/.cache/humanize/<sanitized-path>/skill-<unique-id>/codex-run.{cmd,out,log}
#
set -euo pipefail
# ========================================
# Source Shared Libraries
# ========================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"
# Source portable timeout wrapper
source "$SCRIPT_DIR/portable-timeout.sh"
# Source shared loop library for DEFAULT_CODEX_MODEL and DEFAULT_CODEX_EFFORT
HOOKS_LIB_DIR="$(cd "$SCRIPT_DIR/../hooks/lib" && pwd)"
source "$HOOKS_LIB_DIR/loop-common.sh"
# ========================================
# Default Configuration
# ========================================
DEFAULT_ASK_CODEX_TIMEOUT=3600
CODEX_MODEL="$DEFAULT_CODEX_MODEL"
CODEX_EFFORT="$DEFAULT_CODEX_EFFORT"
CODEX_TIMEOUT="$DEFAULT_ASK_CODEX_TIMEOUT"
# ========================================
# Help
# ========================================
show_help() {
cat << 'HELP_EOF'
ask-codex - One-shot consultation with Codex
USAGE:
/humanize:ask-codex [OPTIONS] <question or task>
OPTIONS:
--codex-model <MODEL:EFFORT>
Codex model and reasoning effort (default from config, fallback gpt-5.5:high)
--codex-timeout <SECONDS>
Timeout for the Codex query in seconds (default: 3600)
-h, --help Show this help message
DESCRIPTION:
Sends a one-shot question or task to Codex and returns the response.
Unlike the RLCR loop, this is a single consultation without iteration.
The response is saved to .humanize/skill/<unique-id>/output.md for reference.
EXAMPLES:
/humanize:ask-codex How should I structure the authentication module?
/humanize:ask-codex --codex-model gpt-5.5:high What are the performance bottlenecks?
/humanize:ask-codex --codex-timeout 300 Review the error handling in src/api/
ENVIRONMENT:
HUMANIZE_CODEX_BYPASS_SANDBOX
Set to "true" or "1" to bypass Codex sandbox protections.
WARNING: This is dangerous. See README for details.
HELP_EOF
exit 0
}
# ========================================
# Parse Arguments
# ========================================
QUESTION_PARTS=()
OPTIONS_DONE=false
while [[ $# -gt 0 ]]; do
if [[ "$OPTIONS_DONE" == "true" ]]; then
# After first positional token or --, all remaining args are question text
QUESTION_PARTS+=("$1")
shift
continue
fi
case $1 in
-h|--help)
show_help
;;
--)
# Explicit end-of-options marker
OPTIONS_DONE=true
shift
;;
--codex-model)
if [[ -z "${2:-}" ]]; then
echo "Error: --codex-model requires a MODEL:EFFORT argument" >&2
exit 1
fi
# Parse MODEL:EFFORT format (same pattern as setup-rlcr-loop.sh)
if [[ "$2" == *:* ]]; then
CODEX_MODEL="${2%%:*}"
CODEX_EFFORT="${2#*:}"
else
CODEX_MODEL="$2"
CODEX_EFFORT="$DEFAULT_CODEX_EFFORT"
fi
shift 2
;;
--codex-timeout)
if [[ -z "${2:-}" ]]; then
echo "Error: --codex-timeout requires a number argument (seconds)" >&2
exit 1
fi
if ! [[ "$2" =~ ^[0-9]+$ ]]; then
echo "Error: --codex-timeout must be a positive integer (seconds), got: $2" >&2
exit 1
fi
CODEX_TIMEOUT="$2"
shift 2
;;
-*)
echo "Error: Unknown option: $1" >&2
echo "Use --help for usage information" >&2
exit 1
;;
*)
# First positional token: stop parsing options, rest is question
QUESTION_PARTS+=("$1")
OPTIONS_DONE=true
shift
;;
esac
done
# Join question parts into a single string
QUESTION="${QUESTION_PARTS[*]}"
# ========================================
# Validate Prerequisites
# ========================================
# Check codex is available
if ! command -v codex &>/dev/null; then
echo "Error: 'codex' command is not installed or not in PATH" >&2
echo "" >&2
echo "Please install Codex CLI: https://github.com/openai/codex" >&2
echo "Then retry: /humanize:ask-codex <your question>" >&2
exit 1
fi
# Check question is not empty
if [[ -z "$QUESTION" ]]; then
echo "Error: No question or task provided" >&2
echo "" >&2
echo "Usage: /humanize:ask-codex [OPTIONS] <question or task>" >&2
echo "" >&2
echo "For help: /humanize:ask-codex --help" >&2
exit 1
fi
# Validate codex model for safety (alphanumeric, hyphen, underscore, dot)
if [[ ! "$CODEX_MODEL" =~ ^[a-zA-Z0-9._-]+$ ]]; then
echo "Error: Codex model contains invalid characters" >&2
echo " Model: $CODEX_MODEL" >&2
echo " Only alphanumeric, hyphen, underscore, dot allowed" >&2
exit 1
fi
# Validate codex effort for safety (alphanumeric, hyphen, underscore)
if [[ ! "$CODEX_EFFORT" =~ ^[a-zA-Z0-9_-]+$ ]]; then
echo "Error: Codex effort contains invalid characters" >&2
echo " Effort: $CODEX_EFFORT" >&2
echo " Only alphanumeric, hyphen, underscore allowed" >&2
exit 1
fi
# ========================================
# Detect Project Root
# ========================================
PROJECT_ROOT="$(resolve_project_root)" || {
echo "Error: Cannot determine project root." >&2
echo " Set CLAUDE_PROJECT_DIR or run inside a git repository." >&2
exit 1
}
# ========================================
# Create Storage Directories
# ========================================
TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)
UNIQUE_ID="${TIMESTAMP}-$$-$(head -c 4 /dev/urandom | od -An -tx1 | tr -d ' \n')"
# Project-local storage: .humanize/skill/<unique-id>/
SKILL_DIR="$PROJECT_ROOT/.humanize/skill/$UNIQUE_ID"
mkdir -p "$SKILL_DIR"
# Cache storage: ~/.cache/humanize/<sanitized-path>/skill-<unique-id>/
# Falls back to project-local .humanize/cache/ if home cache is not writable
SANITIZED_PROJECT_PATH=$(echo "$PROJECT_ROOT" | sed 's/[^a-zA-Z0-9._-]/-/g' | sed 's/--*/-/g')
CACHE_BASE="${XDG_CACHE_HOME:-$HOME/.cache}"
CACHE_DIR="$CACHE_BASE/humanize/$SANITIZED_PROJECT_PATH/skill-$UNIQUE_ID"
if ! mkdir -p "$CACHE_DIR" 2>/dev/null; then
CACHE_DIR="$SKILL_DIR/cache"
mkdir -p "$CACHE_DIR"
echo "ask-codex: warning: home cache not writable, using $CACHE_DIR" >&2
fi
# ========================================
# Save Input
# ========================================
cat > "$SKILL_DIR/input.md" << EOF
# Ask Codex Input
## Question
$QUESTION
## Configuration
- Model: $CODEX_MODEL
- Effort: $CODEX_EFFORT
- Timeout: ${CODEX_TIMEOUT}s
- Timestamp: $TIMESTAMP
- Tool: codex
EOF
# ========================================
# Build Codex Command
# ========================================
# Build codex exec arguments (same pattern as loop-codex-stop-hook.sh)
CODEX_EXEC_ARGS=("-m" "$CODEX_MODEL")
if [[ -n "$CODEX_EFFORT" ]]; then
CODEX_EXEC_ARGS+=("-c" "model_reasoning_effort=${CODEX_EFFORT}")
fi
# Determine automation flag based on environment variable
CODEX_AUTO_FLAG="--full-auto"
if [[ "${HUMANIZE_CODEX_BYPASS_SANDBOX:-}" == "true" ]] || [[ "${HUMANIZE_CODEX_BYPASS_SANDBOX:-}" == "1" ]]; then
CODEX_AUTO_FLAG="--dangerously-bypass-approvals-and-sandbox"
fi
CODEX_EXEC_ARGS+=("$CODEX_AUTO_FLAG" "-C" "$PROJECT_ROOT")
# ========================================
# Save Debug Command
# ========================================
CODEX_CMD_FILE="$CACHE_DIR/codex-run.cmd"
CODEX_STDOUT_FILE="$CACHE_DIR/codex-run.out"
CODEX_STDERR_FILE="$CACHE_DIR/codex-run.log"
{
echo "# Codex ask-codex invocation debug info"
echo "# Timestamp: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "# Working directory: $PROJECT_ROOT"
echo "# Timeout: $CODEX_TIMEOUT seconds"
echo ""
echo "codex exec ${CODEX_EXEC_ARGS[*]} \"<prompt>\""
echo ""
echo "# Prompt content:"
echo "$QUESTION"
} > "$CODEX_CMD_FILE"
# ========================================
# Run Codex
# ========================================
echo "ask-codex: model=$CODEX_MODEL effort=$CODEX_EFFORT timeout=${CODEX_TIMEOUT}s" >&2
echo "ask-codex: cache=$CACHE_DIR" >&2
echo "ask-codex: running codex exec..." >&2
# Portable epoch-to-ISO8601 formatter (GNU date -d vs BSD date -r)
epoch_to_iso() {
local epoch="$1"
date -u -d "@$epoch" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null ||
date -u -r "$epoch" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null ||
echo "unknown"
}
START_TIME=$(date +%s)
CODEX_EXIT_CODE=0
printf '%s' "$QUESTION" | run_with_timeout "$CODEX_TIMEOUT" codex exec "${CODEX_EXEC_ARGS[@]}" - \
> "$CODEX_STDOUT_FILE" 2> "$CODEX_STDERR_FILE" || CODEX_EXIT_CODE=$?
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))
echo "ask-codex: exit_code=$CODEX_EXIT_CODE duration=${DURATION}s" >&2
# ========================================
# Handle Results
# ========================================
# Check for timeout
if [[ $CODEX_EXIT_CODE -eq 124 ]]; then
echo "Error: Codex timed out after ${CODEX_TIMEOUT} seconds" >&2
echo "" >&2
echo "Try increasing the timeout:" >&2
echo " /humanize:ask-codex --codex-timeout $((CODEX_TIMEOUT * 2)) <your question>" >&2
echo "" >&2
echo "Debug logs: $CACHE_DIR" >&2
# Save metadata even on timeout
cat > "$SKILL_DIR/metadata.md" << EOF
---
tool: codex
model: $CODEX_MODEL
effort: $CODEX_EFFORT
timeout: $CODEX_TIMEOUT
exit_code: 124
duration: ${DURATION}s
status: timeout
started_at: $(epoch_to_iso "$START_TIME")
---
EOF
exit 124
fi
# Check for non-zero exit
if [[ $CODEX_EXIT_CODE -ne 0 ]]; then
echo "Error: Codex exited with code $CODEX_EXIT_CODE" >&2
if [[ -s "$CODEX_STDERR_FILE" ]]; then
echo "" >&2
echo "Codex stderr (last 20 lines):" >&2
tail -20 "$CODEX_STDERR_FILE" >&2
fi
echo "" >&2
echo "Debug logs: $CACHE_DIR" >&2
# Save metadata
cat > "$SKILL_DIR/metadata.md" << EOF
---
tool: codex
model: $CODEX_MODEL
effort: $CODEX_EFFORT
timeout: $CODEX_TIMEOUT
exit_code: $CODEX_EXIT_CODE
duration: ${DURATION}s
status: error
started_at: $(epoch_to_iso "$START_TIME")
---
EOF
exit "$CODEX_EXIT_CODE"
fi
# Check for empty stdout
if [[ ! -s "$CODEX_STDOUT_FILE" ]]; then
echo "Error: Codex returned empty response" >&2
if [[ -s "$CODEX_STDERR_FILE" ]]; then
echo "" >&2
echo "Codex stderr (last 20 lines):" >&2
tail -20 "$CODEX_STDERR_FILE" >&2
fi
echo "" >&2
echo "Debug logs: $CACHE_DIR" >&2
cat > "$SKILL_DIR/metadata.md" << EOF
---
tool: codex
model: $CODEX_MODEL
effort: $CODEX_EFFORT
timeout: $CODEX_TIMEOUT
exit_code: 0
duration: ${DURATION}s
status: empty_response
started_at: $(epoch_to_iso "$START_TIME")
---
EOF
exit 1
fi
# ========================================
# Save Output and Metadata
# ========================================
# Save Codex response to project-local storage
cp "$CODEX_STDOUT_FILE" "$SKILL_DIR/output.md"
# Save metadata
cat > "$SKILL_DIR/metadata.md" << EOF
---
tool: codex
model: $CODEX_MODEL
effort: $CODEX_EFFORT
timeout: $CODEX_TIMEOUT
exit_code: 0
duration: ${DURATION}s
status: success
started_at: $(epoch_to_iso "$START_TIME")
---
EOF
echo "ask-codex: response saved to $SKILL_DIR/output.md" >&2
# ========================================
# Output Response
# ========================================
# Output Codex's response to stdout (clean output for Claude to read)
cat "$CODEX_STDOUT_FILE"
#!/usr/bin/env bash
#
# Ask Gemini - One-shot consultation with Gemini CLI
#
# Sends a question or task to gemini in non-interactive mode and returns
# the response. Gemini is always instructed to leverage Google Search
# for deep web research.
#
# Usage:
# ask-gemini.sh [--gemini-model MODEL] [--gemini-timeout SECONDS] [question...]
#
# Output:
# stdout: Gemini's response (for Claude to read)
# stderr: Status/debug info (model, log paths)
#
# Storage:
# Project-local: .humanize/skill/<unique-id>/{input,output,metadata}.md
# Cache: ~/.cache/humanize/<sanitized-path>/skill-<unique-id>/gemini-run.{cmd,out,log}
#
set -euo pipefail
# ========================================
# Source Shared Libraries
# ========================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"
# Source portable timeout wrapper
source "$SCRIPT_DIR/portable-timeout.sh"
# Shared project-root resolver (CLAUDE_PROJECT_DIR -> git toplevel, realpath-canonical)
source "$SCRIPT_DIR/../hooks/lib/project-root.sh"
# ========================================
# Default Configuration
# ========================================
DEFAULT_GEMINI_MODEL="gemini-3.1-pro-preview"
DEFAULT_ASK_GEMINI_TIMEOUT=3600
GEMINI_MODEL="$DEFAULT_GEMINI_MODEL"
GEMINI_TIMEOUT="$DEFAULT_ASK_GEMINI_TIMEOUT"
# ========================================
# Help
# ========================================
show_help() {
cat << 'HELP_EOF'
ask-gemini - One-shot deep-research consultation with Gemini
USAGE:
/humanize:ask-gemini [OPTIONS] <question or task>
OPTIONS:
--gemini-model <MODEL>
Gemini model name (default: gemini-3.1-pro-preview)
--gemini-timeout <SECONDS>
Timeout for the Gemini query in seconds (default: 3600)
-h, --help Show this help message
DESCRIPTION:
Sends a one-shot question or task to the Gemini CLI in non-interactive
mode (-p). The prompt is augmented with an instruction to perform web
research via Google Search, making this ideal for deep-research tasks
that benefit from up-to-date internet information.
The response is saved to .humanize/skill/<unique-id>/output.md for reference.
EXAMPLES:
/humanize:ask-gemini What are the latest best practices for Rust error handling?
/humanize:ask-gemini --gemini-model gemini-2.5-pro Review recent CVEs for OpenSSL 3.x
/humanize:ask-gemini --gemini-timeout 600 Compare React Server Components vs Astro Islands
ENVIRONMENT:
HUMANIZE_GEMINI_YOLO
Set to "true" or "1" to auto-approve all Gemini tool calls (--yolo).
Default behaviour uses --sandbox mode.
HELP_EOF
exit 0
}
# ========================================
# Parse Arguments
# ========================================
QUESTION_PARTS=()
OPTIONS_DONE=false
while [[ $# -gt 0 ]]; do
if [[ "$OPTIONS_DONE" == "true" ]]; then
QUESTION_PARTS+=("$1")
shift
continue
fi
case $1 in
-h|--help)
show_help
;;
--)
OPTIONS_DONE=true
shift
;;
--gemini-model)
if [[ -z "${2:-}" ]]; then
echo "Error: --gemini-model requires a MODEL argument" >&2
exit 1
fi
GEMINI_MODEL="$2"
shift 2
;;
--gemini-timeout)
if [[ -z "${2:-}" ]]; then
echo "Error: --gemini-timeout requires a number argument (seconds)" >&2
exit 1
fi
if ! [[ "$2" =~ ^[0-9]+$ ]]; then
echo "Error: --gemini-timeout must be a positive integer (seconds), got: $2" >&2
exit 1
fi
GEMINI_TIMEOUT="$2"
shift 2
;;
-*)
echo "Error: Unknown option: $1" >&2
echo "Use --help for usage information" >&2
exit 1
;;
*)
QUESTION_PARTS+=("$1")
OPTIONS_DONE=true
shift
;;
esac
done
# Join question parts into a single string
QUESTION="${QUESTION_PARTS[*]}"
# ========================================
# Validate Prerequisites
# ========================================
if ! command -v gemini &>/dev/null; then
echo "Error: 'gemini' command is not installed or not in PATH" >&2
echo "" >&2
echo "Please install Gemini CLI: npm install -g @google/gemini-cli or https://github.com/google-gemini/gemini-cli" >&2
echo "Then retry: /humanize:ask-gemini <your question>" >&2
exit 1
fi
if [[ -z "$QUESTION" ]]; then
echo "Error: No question or task provided" >&2
echo "" >&2
echo "Usage: /humanize:ask-gemini [OPTIONS] <question or task>" >&2
echo "" >&2
echo "For help: /humanize:ask-gemini --help" >&2
exit 1
fi
# Validate model name for safety (alphanumeric, hyphen, underscore, dot)
if [[ ! "$GEMINI_MODEL" =~ ^[a-zA-Z0-9._-]+$ ]]; then
echo "Error: Gemini model contains invalid characters" >&2
echo " Model: $GEMINI_MODEL" >&2
echo " Only alphanumeric, hyphen, underscore, dot allowed" >&2
exit 1
fi
# ========================================
# Detect Project Root
# ========================================
PROJECT_ROOT="$(resolve_project_root)" || {
echo "Error: Cannot determine project root." >&2
echo " Set CLAUDE_PROJECT_DIR or run inside a git repository." >&2
exit 1
}
# ========================================
# Create Storage Directories
# ========================================
TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)
UNIQUE_ID="${TIMESTAMP}-$$-$(head -c 4 /dev/urandom | od -An -tx1 | tr -d ' \n')"
# Project-local storage: .humanize/skill/<unique-id>/
SKILL_DIR="$PROJECT_ROOT/.humanize/skill/$UNIQUE_ID"
mkdir -p "$SKILL_DIR"
# Cache storage: ~/.cache/humanize/<sanitized-path>/skill-<unique-id>/
SANITIZED_PROJECT_PATH=$(echo "$PROJECT_ROOT" | sed 's/[^a-zA-Z0-9._-]/-/g' | sed 's/--*/-/g')
CACHE_BASE="${XDG_CACHE_HOME:-$HOME/.cache}"
CACHE_DIR="$CACHE_BASE/humanize/$SANITIZED_PROJECT_PATH/skill-$UNIQUE_ID"
if ! mkdir -p "$CACHE_DIR" 2>/dev/null; then
CACHE_DIR="$SKILL_DIR/cache"
mkdir -p "$CACHE_DIR"
echo "ask-gemini: warning: home cache not writable, using $CACHE_DIR" >&2
fi
# ========================================
# Save Input
# ========================================
cat > "$SKILL_DIR/input.md" << EOF
# Ask Gemini Input
## Question
$QUESTION
## Configuration
- Model: $GEMINI_MODEL
- Timeout: ${GEMINI_TIMEOUT}s
- Timestamp: $TIMESTAMP
- Tool: gemini
EOF
# ========================================
# Build Gemini Command
# ========================================
GEMINI_ARGS=("-m" "$GEMINI_MODEL")
# Determine approval mode
if [[ "${HUMANIZE_GEMINI_YOLO:-}" == "true" ]] || [[ "${HUMANIZE_GEMINI_YOLO:-}" == "1" ]]; then
GEMINI_ARGS+=("--yolo")
else
GEMINI_ARGS+=("--sandbox")
fi
# Use text output format for clean stdout
GEMINI_ARGS+=("-o" "text")
# Build the augmented prompt with web-search instruction
AUGMENTED_PROMPT="You MUST use Google Search to find the most up-to-date and accurate information before answering. Perform thorough web research. Cite sources where possible.
---
$QUESTION"
# ========================================
# Save Debug Command
# ========================================
GEMINI_CMD_FILE="$CACHE_DIR/gemini-run.cmd"
GEMINI_STDOUT_FILE="$CACHE_DIR/gemini-run.out"
GEMINI_STDERR_FILE="$CACHE_DIR/gemini-run.log"
{
echo "# Gemini ask-gemini invocation debug info"
echo "# Timestamp: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "# Working directory: $PROJECT_ROOT"
echo "# Timeout: $GEMINI_TIMEOUT seconds"
echo ""
echo "gemini ${GEMINI_ARGS[*]} -p \"<prompt>\""
echo ""
echo "# Prompt content:"
echo "$AUGMENTED_PROMPT"
} > "$GEMINI_CMD_FILE"
# ========================================
# Run Gemini
# ========================================
echo "ask-gemini: model=$GEMINI_MODEL timeout=${GEMINI_TIMEOUT}s" >&2
echo "ask-gemini: cache=$CACHE_DIR" >&2
echo "ask-gemini: running gemini -p ..." >&2
# Portable epoch-to-ISO8601 formatter
epoch_to_iso() {
local epoch="$1"
date -u -d "@$epoch" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null ||
date -u -r "$epoch" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null ||
echo "unknown"
}
START_TIME=$(date +%s)
GEMINI_EXIT_CODE=0
run_with_timeout "$GEMINI_TIMEOUT" gemini "${GEMINI_ARGS[@]}" -p "$AUGMENTED_PROMPT" \
> "$GEMINI_STDOUT_FILE" 2> "$GEMINI_STDERR_FILE" || GEMINI_EXIT_CODE=$?
END_TIME=$(date +%s)
DURATION=$((END_TIME - START_TIME))
echo "ask-gemini: exit_code=$GEMINI_EXIT_CODE duration=${DURATION}s" >&2
# ========================================
# Handle Results
# ========================================
if [[ $GEMINI_EXIT_CODE -eq 124 ]]; then
echo "Error: Gemini timed out after ${GEMINI_TIMEOUT} seconds" >&2
echo "" >&2
echo "Try increasing the timeout:" >&2
echo " /humanize:ask-gemini --gemini-timeout $((GEMINI_TIMEOUT * 2)) <your question>" >&2
echo "" >&2
echo "Debug logs: $CACHE_DIR" >&2
cat > "$SKILL_DIR/metadata.md" << EOF
---
tool: gemini
model: $GEMINI_MODEL
timeout: $GEMINI_TIMEOUT
exit_code: 124
duration: ${DURATION}s
status: timeout
started_at: $(epoch_to_iso "$START_TIME")
---
EOF
exit 124
fi
if [[ $GEMINI_EXIT_CODE -ne 0 ]]; then
echo "Error: Gemini exited with code $GEMINI_EXIT_CODE" >&2
if [[ -s "$GEMINI_STDERR_FILE" ]]; then
echo "" >&2
echo "Gemini stderr (last 20 lines):" >&2
tail -20 "$GEMINI_STDERR_FILE" >&2
fi
echo "" >&2
echo "Debug logs: $CACHE_DIR" >&2
cat > "$SKILL_DIR/metadata.md" << EOF
---
tool: gemini
model: $GEMINI_MODEL
timeout: $GEMINI_TIMEOUT
exit_code: $GEMINI_EXIT_CODE
duration: ${DURATION}s
status: error
started_at: $(epoch_to_iso "$START_TIME")
---
EOF
exit "$GEMINI_EXIT_CODE"
fi
if [[ ! -s "$GEMINI_STDOUT_FILE" ]]; then
echo "Error: Gemini returned empty response" >&2
if [[ -s "$GEMINI_STDERR_FILE" ]]; then
echo "" >&2
echo "Gemini stderr (last 20 lines):" >&2
tail -20 "$GEMINI_STDERR_FILE" >&2
fi
echo "" >&2
echo "Debug logs: $CACHE_DIR" >&2
cat > "$SKILL_DIR/metadata.md" << EOF
---
tool: gemini
model: $GEMINI_MODEL
timeout: $GEMINI_TIMEOUT
exit_code: 0
duration: ${DURATION}s
status: empty_response
started_at: $(epoch_to_iso "$START_TIME")
---
EOF
exit 1
fi
# ========================================
# Save Output and Metadata
# ========================================
cp "$GEMINI_STDOUT_FILE" "$SKILL_DIR/output.md"
cat > "$SKILL_DIR/metadata.md" << EOF
---
tool: gemini
model: $GEMINI_MODEL
timeout: $GEMINI_TIMEOUT
exit_code: 0
duration: ${DURATION}s
status: success
started_at: $(epoch_to_iso "$START_TIME")
---
EOF
echo "ask-gemini: response saved to $SKILL_DIR/output.md" >&2
# ========================================
# Output Response
# ========================================
cat "$GEMINI_STDOUT_FILE"
#!/usr/bin/env bash
set -euo pipefail
usage() {
cat <<'USAGE_EOF' >&2
Usage:
bitlesson-init.sh --project-root <dir> --template <path> [--bitlesson-relpath <relpath>]
Behavior:
- Default bitlesson-relpath: .humanize/bitlesson.md
- Creates <project-root>/<bitlesson-relpath> from template if missing
- Does not overwrite existing file
- Prints the resolved bitlesson file path to stdout on success
USAGE_EOF
}
PROJECT_ROOT=""
TEMPLATE_PATH=""
BITLESSON_RELPATH=".humanize/bitlesson.md"
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
usage
exit 0
;;
--project-root)
PROJECT_ROOT="${2:-}"
shift 2
;;
--template)
TEMPLATE_PATH="${2:-}"
shift 2
;;
--bitlesson-relpath)
BITLESSON_RELPATH="${2:-}"
shift 2
;;
*)
echo "Error: Unknown argument: $1" >&2
usage
exit 1
;;
esac
done
if [[ -z "$PROJECT_ROOT" ]]; then
echo "Error: --project-root is required" >&2
usage
exit 1
fi
if [[ -z "$TEMPLATE_PATH" ]]; then
echo "Error: --template is required" >&2
usage
exit 1
fi
if [[ ! -d "$PROJECT_ROOT" ]]; then
echo "Error: --project-root must be an existing directory: $PROJECT_ROOT" >&2
exit 1
fi
if [[ ! -f "$TEMPLATE_PATH" ]]; then
echo "Error: --template must be an existing file: $TEMPLATE_PATH" >&2
exit 1
fi
if [[ "$BITLESSON_RELPATH" = /* ]] || [[ "$BITLESSON_RELPATH" =~ (^|/)\.\.(/|$) ]]; then
echo "Error: --bitlesson-relpath must be a relative path without '..': $BITLESSON_RELPATH" >&2
exit 1
fi
PROJECT_ROOT_ABS="$(cd "$PROJECT_ROOT" && pwd -P)"
BITLESSON_FILE="$PROJECT_ROOT_ABS/$BITLESSON_RELPATH"
if [[ -e "$BITLESSON_FILE" && ! -f "$BITLESSON_FILE" ]]; then
echo "Error: BitLesson path exists but is not a regular file: $BITLESSON_FILE" >&2
exit 1
fi
if [[ ! -f "$BITLESSON_FILE" ]]; then
mkdir -p "$(dirname "$BITLESSON_FILE")"
cp "$TEMPLATE_PATH" "$BITLESSON_FILE"
fi
printf '%s\n' "$BITLESSON_FILE"
#!/usr/bin/env bash
set -euo pipefail
# ========================================
# Source Shared Libraries
# ========================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)"
source "$SCRIPT_DIR/lib/config-loader.sh"
source "$SCRIPT_DIR/lib/model-router.sh"
source "$SCRIPT_DIR/../hooks/lib/project-root.sh"
PLUGIN_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
PROJECT_ROOT="$(resolve_project_root)" || {
echo "Error: Cannot determine project root." >&2
echo " Set CLAUDE_PROJECT_DIR or run inside a git repository." >&2
exit 1
}
MERGED_CONFIG="$(load_merged_config "$PLUGIN_ROOT" "$PROJECT_ROOT")"
BITLESSON_MODEL="$(get_config_value "$MERGED_CONFIG" "bitlesson_model")"
BITLESSON_MODEL="${BITLESSON_MODEL:-haiku}"
CODEX_FALLBACK_MODEL="$(get_config_value "$MERGED_CONFIG" "codex_model")"
CODEX_FALLBACK_MODEL="${CODEX_FALLBACK_MODEL:-$DEFAULT_CODEX_MODEL}"
PROVIDER_MODE="$(get_config_value "$MERGED_CONFIG" "provider_mode")"
PROVIDER_MODE="${PROVIDER_MODE:-auto}"
# Source portable timeout wrapper
source "$SCRIPT_DIR/portable-timeout.sh"
# Source shared loop library (kept for consistency with ask-codex.sh)
HOOKS_LIB_DIR="$(cd "$SCRIPT_DIR/../hooks/lib" && pwd)"
source "$HOOKS_LIB_DIR/loop-common.sh"
usage() {
cat <<'USAGE_EOF' >&2
Usage:
bitlesson-select.sh --task <string> --paths <comma-separated> --bitlesson-file <path>
Output (exactly):
LESSON_IDS: <comma-separated IDs or NONE>
RATIONALE: <one concise sentence>
USAGE_EOF
}
TASK=""
PATHS=""
BITLESSON_FILE=""
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
usage
exit 0
;;
--task)
TASK="${2:-}"
shift 2
;;
--paths)
PATHS="${2:-}"
shift 2
;;
--bitlesson-file)
BITLESSON_FILE="${2:-}"
shift 2
;;
*)
echo "Error: Unknown argument: $1" >&2
usage
exit 1
;;
esac
done
if [[ -z "$TASK" ]]; then
echo "Error: --task is required and must be non-empty" >&2
usage
exit 1
fi
if [[ -z "$PATHS" ]]; then
echo "Error: --paths is required and must be non-empty" >&2
usage
exit 1
fi
if [[ -z "$BITLESSON_FILE" ]]; then
echo "Error: --bitlesson-file is required" >&2
usage
exit 1
fi
if [[ ! -f "$BITLESSON_FILE" ]]; then
echo "Error: BitLesson file not found: $BITLESSON_FILE" >&2
exit 1
fi
BITLESSON_CONTENT="$(cat "$BITLESSON_FILE")"
if [[ -z "$(printf '%s' "$BITLESSON_CONTENT" | tr -d ' \t\n\r')" ]]; then
echo "Error: BitLesson file is empty (whitespace only): $BITLESSON_FILE" >&2
exit 1
fi
if ! printf '%s\n' "$BITLESSON_CONTENT" | grep -Eq '^[[:space:]]*##[[:space:]]+Lesson:'; then
printf 'LESSON_IDS: NONE\n'
printf 'RATIONALE: The BitLesson file has no recorded lessons yet.\n'
exit 0
fi
# ========================================
# Determine Provider from BITLESSON_MODEL
# ========================================
BITLESSON_PROVIDER="$(detect_provider "$BITLESSON_MODEL")"
if [[ "$PROVIDER_MODE" == "codex-only" ]] && [[ "$BITLESSON_PROVIDER" == "claude" ]]; then
BITLESSON_MODEL="$CODEX_FALLBACK_MODEL"
BITLESSON_PROVIDER="codex"
fi
# ========================================
# Conditional Dependency Check (with fallback)
# ========================================
if ! check_provider_dependency "$BITLESSON_PROVIDER" 2>/dev/null; then
# Fall back to codex provider when the configured provider binary is missing
BITLESSON_MODEL="$DEFAULT_CODEX_MODEL"
BITLESSON_PROVIDER="codex"
check_provider_dependency "$BITLESSON_PROVIDER"
fi
# ========================================
# Detect Project Root (for -C)
# ========================================
BITLESSON_DIR="$(cd "$(dirname "$BITLESSON_FILE")" && pwd -P)"
if git -C "$BITLESSON_DIR" rev-parse --show-toplevel &>/dev/null; then
CODEX_PROJECT_ROOT="$(git -C "$BITLESSON_DIR" rev-parse --show-toplevel)"
else
CODEX_PROJECT_ROOT="$BITLESSON_DIR"
fi
# ========================================
# Build Selector Prompt
# ========================================
PROMPT="$(cat <<EOF
# BitLesson Selector
You select which lessons from the configured BitLesson file (normally \`.humanize/bitlesson.md\`) must be applied for a given sub-task.
## Input
Sub-task description:
$TASK
Related file paths (comma-separated):
$PATHS
BitLesson file content:
<<<BEGIN_BITLESSON_MD
$BITLESSON_CONTENT
<<<END_BITLESSON_MD
## Decision Rules
1. Match only lessons that are directly relevant to the sub-task scope and failure mode.
2. Prefer precision over recall: do not include weakly related lessons.
3. If nothing is relevant, return \`NONE\`.
4. Use only the information in this prompt. Do not use tools, shell commands, browser access, MCP servers, or repository inspection.
## Output Format (Stable)
Return exactly two lines (no code blocks, no extra whitespace, no additional sections):
LESSON_IDS: <comma-separated lesson IDs or NONE>
RATIONALE: <one concise sentence>
EOF
)"
# ========================================
# Run Selector (Codex or Claude)
# ========================================
SELECTOR_TIMEOUT=120
run_selector() {
local provider="$1"
local model="$2"
if [[ "$provider" == "codex" ]]; then
local codex_exec_args=()
# Probe whether the installed Codex CLI supports --disable flag
if codex --help 2>&1 | grep -q -- '--disable'; then
codex_exec_args+=("--disable" "hooks")
fi
# Probe for --skip-git-repo-check and --ephemeral support
if codex exec --help 2>&1 | grep -q -- '--skip-git-repo-check'; then
codex_exec_args+=("--skip-git-repo-check")
fi
if codex exec --help 2>&1 | grep -q -- '--ephemeral'; then
codex_exec_args+=("--ephemeral")
fi
codex_exec_args+=(
"-s" "read-only"
"-m" "$model"
"-c" "model_reasoning_effort=low"
"-C" "$CODEX_PROJECT_ROOT"
)
printf '%s' "$PROMPT" | run_with_timeout "$SELECTOR_TIMEOUT" codex exec "${codex_exec_args[@]}" -
return $?
fi
if [[ "$provider" == "claude" ]]; then
printf '%s' "$PROMPT" | run_with_timeout "$SELECTOR_TIMEOUT" claude --print --model "$model" -
return $?
fi
echo "Error: Unsupported BitLesson provider '$provider'" >&2
return 1
}
CODEX_EXIT_CODE=0
RAW_OUTPUT="$(run_selector "$BITLESSON_PROVIDER" "$BITLESSON_MODEL" 2>&1)" || CODEX_EXIT_CODE=$?
if [[ $CODEX_EXIT_CODE -eq 124 ]]; then
echo "Error: BitLesson selector timed out after ${SELECTOR_TIMEOUT} seconds" >&2
exit 124
fi
if [[ $CODEX_EXIT_CODE -ne 0 ]]; then
echo "Error: BitLesson selector failed (exit code $CODEX_EXIT_CODE)" >&2
printf '%s\n' "$RAW_OUTPUT" >&2
exit "$CODEX_EXIT_CODE"
fi
# ========================================
# Enforce Stable Output Format
# ========================================
LESSON_IDS_VALUE="$(
printf '%s\n' "$RAW_OUTPUT" \
| sed -n 's/^[[:space:]]*LESSON_IDS:[[:space:]]*//p' \
| head -n 1 \
| tr -d '\r' \
| sed 's/[[:space:]]*$//'
)"
RATIONALE_VALUE="$(
printf '%s\n' "$RAW_OUTPUT" \
| sed -n 's/^[[:space:]]*RATIONALE:[[:space:]]*//p' \
| head -n 1 \
| tr -d '\r' \
| sed 's/[[:space:]]*$//'
)"
if [[ -z "$LESSON_IDS_VALUE" || -z "$RATIONALE_VALUE" ]]; then
echo "Error: Unexpected selector output format (expected LESSON_IDS and RATIONALE lines)" >&2
echo "" >&2
echo "Raw output:" >&2
printf '%s\n' "$RAW_OUTPUT" >&2
exit 1
fi
printf 'LESSON_IDS: %s\n' "$LESSON_IDS_VALUE"
printf 'RATIONALE: %s\n' "$RATIONALE_VALUE"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment