Skip to content

mass-update: deterministic update - #8

Open
OriNachum wants to merge 1 commit into
mainfrom
mass-update/agentculture-lecodeur-skills
Open

mass-update: deterministic update#8
OriNachum wants to merge 1 commit into
mainfrom
mass-update/agentculture-lecodeur-skills

Conversation

@OriNachum

Copy link
Copy Markdown
Contributor

Automated update via mass-update skill.

@github-actions

Copy link
Copy Markdown

⚠️ Version not bumpedpyproject.toml still has 0.2.0 (same as main). Bump before merging to avoid a failed PyPI publish.

@sonarqubecloud

Copy link
Copy Markdown

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add devague workflow skills and an ask-colleague CLI wrapper

✨ Enhancement 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Add devague method skills covering scope→think→plan→workforce→deviate→delivery summary.
• Introduce portable bash entrypoints that resolve devague/colleague CLIs and forward commands.
• Add ask-colleague prompts and wrapper to run explore/review/write with an independent model.
Diagram

graph TD
A["Claude agent"] --> B["Skill scripts"] --> C["devague CLI"]
A --> D["ask-colleague.sh"] --> E["colleague CLI"] --> F["Alt model backend"]
D --> G["Prompt templates"]
A --> H["Skill docs"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Split ask-colleague.sh into per-verb scripts/modules
  • ➕ Better maintainability and smaller review surface per change
  • ➕ Reduces coupling between unrelated verbs/flags
  • ➖ More files/entrypoints to distribute
  • ➖ Requires factoring shared parsing/utilities
2. Replace bash wrappers with a small Python CLI package
  • ➕ Cleaner JSON parsing/templating and stronger structure for subcommands
  • ➕ Easier unit testing than large bash scripts
  • ➖ Adds a heavier runtime expectation vs pure bash portability
  • ➖ Distribution/versioning overhead for the mesh use case

Recommendation: The PR’s approach (portable bash wrappers with minimal assumptions) aligns with the stated goal of running across diverse environments and keeping devague deterministic/non-orchestrating. If ask-colleague continues growing, the main improvement to consider later is decomposing the 866-line script by verb or migrating it to a small Python CLI for long-term maintainability.

Files changed (15) +3629 / -0

Enhancement (4) +1352 / -0
ask-colleague.shAdd full ask-colleague wrapper implementing multiple verbs and safety rules +866/-0

Add full ask-colleague wrapper implementing multiple verbs and safety rules

• Adds an 866-line bash CLI that resolves the colleague executable (PATH-first, uv fallback) and supports explore/review/write plus feedback/clean and run monitoring controls. Encodes exit-code policy, worktree isolation for read-only probes, and cleanup guidance for stale colleague/* artifacts/branches.

.claude/skills/ask-colleague/scripts/ask-colleague.sh

assign-to-workforce.shAdd wrapper to render implementation split plan from 'devague plan waves --json' +283/-0

Add wrapper to render implementation split plan from 'devague plan waves --json'

• Adds a portable bash entrypoint that resolves devague and provides 'split-plan' (render a human-facing split plan) and 'waves' (forward devague waves). 'split-plan' captures JSON output, formats it via an embedded Python script, and appends an End state section via 'devague plan deliverables' with graceful fallback for older devague versions.

.claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh

spec-to-plan.shAdd spec-to-plan bash wrapper that forwards to 'devague plan' +102/-0

Add spec-to-plan bash wrapper that forwards to 'devague plan'

• Adds a portable bash script that resolves devague (PATH-first with uv fallback in a devague checkout) and forwards all arguments as 'devague plan ...'. Includes usage/help and notes that future moves require no wrapper changes.

.claude/skills/spec-to-plan/scripts/spec-to-plan.sh

think.shAdd think bash wrapper that forwards devague moves verbatim +101/-0

Add think bash wrapper that forwards devague moves verbatim

• Adds a portable bash entrypoint that resolves devague and forwards any command/move (including status and future moves) directly to the CLI. Includes usage text and notes frames persist under .devague/ in the current directory.

.claude/skills/think/scripts/think.sh

Documentation (8) +2202 / -0
SKILL.mdAdd ask-colleague skill documentation and operating model +214/-0

Add ask-colleague skill documentation and operating model

• Introduces the ask-colleague skill, explaining the “second independent mind” rationale and when to use explore/review/write/feedback/clean. Documents read-only isolation via throwaway worktrees and the expectation that colleague output is advisory, not authority.

.claude/skills/ask-colleague/SKILL.md

SKILL.mdDocument assign-to-workforce: fan out plan waves to parallel agents +325/-0

Document assign-to-workforce: fan out plan waves to parallel agents

• Adds method documentation for taking devague dependency waves and distributing tasks to parallel agents in isolated worktrees, with TDD-gated merges by a main agent and explicit human gates. Clarifies that devague remains non-orchestrating and the operator performs fan-out.

.claude/skills/assign-to-workforce/SKILL.md

SKILL.mdAdd challenge skill documentation for blind-spot discovery between spec and plan +290/-0

Add challenge skill documentation for blind-spot discovery between spec and plan

• Documents a structured pressure-test pass over an exported/converged spec after /think and before plan seeding. Describes routing findings back through existing deterministic moves as proposed content for human adjudication, without adding a new gate.

.claude/skills/challenge/SKILL.md

SKILL.mdAdd deviate skill documentation for mid-run plan departures +176/-0

Add deviate skill documentation for mid-run plan departures

• Documents how to stop an in-flight workforce run when reality diverges from the confirmed plan, obtain explicit human approval, and record an append-only deviation via 'devague deviate' before resuming. Positions deviate within the overall method flow.

.claude/skills/deviate/SKILL.md

SKILL.mdAdd scope skill documentation for pre-framing surface exploration +167/-0

Add scope skill documentation for pre-framing surface exploration

• Documents an optional opening leg to explore what an idea touches (code/docs/CI/sibling repos) before framing. Emphasizes provenance-backed findings and how they seed boundary/non-goal/assumption claims on the devague frame.

.claude/skills/scope/SKILL.md

SKILL.mdAdd spec-to-plan skill documentation for spec→plan convergence +303/-0

Add spec-to-plan skill documentation for spec→plan convergence

• Documents the forward leg of the devague method: seeding a plan from a converged frame, creating tasks with acceptance criteria and dependencies, tracking risks, converging, exporting, and emitting deterministic waves. Includes a move reference and guidance on status usage.

.claude/skills/spec-to-plan/SKILL.md

SKILL.mdAdd summarize-delivery method-only documentation for post-run accountability +440/-0

Add summarize-delivery method-only documentation for post-run accountability

• Introduces a method-only skill for producing an auditable delivery artifact after workforce execution: planned vs actual, drift/deviations, evidence-backed delivery claims, and remaining work. Explicitly avoids adding a new devague CLI verb or orchestration behavior.

.claude/skills/summarize-delivery/SKILL.md

SKILL.mdAdd think skill documentation for idea→spec working-backwards flow +287/-0

Add think skill documentation for idea→spec working-backwards flow

• Documents the working-backwards flow to turn a vague idea into a converged/exported spec using deterministic devague moves. Clarifies the role of status, convergence, export, and how /scope can precede framing for codebase-touching ideas.

.claude/skills/think/SKILL.md

Other (3) +75 / -0
explore.mdAdd explore prompt template for colleague runs +29/-0

Add explore prompt template for colleague runs

• Adds a read-only exploration prompt emphasizing concrete citations (paths/lines), efficient searching, and finishing early within a step budget. Defines a structured findings report format.

.claude/skills/ask-colleague/prompts/explore.md

review.mdAdd review prompt template for second-opinion diff reviews +31/-0

Add review prompt template for second-opinion diff reviews

• Adds a read-only review prompt focused on correctness risks, maintainability concerns, and ranked actionable suggestions. Explicitly discourages running builds/installs and notes that the diff is already provided.

.claude/skills/ask-colleague/prompts/review.md

write.mdAdd write prompt template for delegated implementation +15/-0

Add write prompt template for delegated implementation

• Adds a prompt for implementing a scoped task with guardrails: smallest change, follow repo patterns, keep lint-clean, and summarize changes on completion.

.claude/skills/ask-colleague/prompts/write.md

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📜 Skill insights (1)

Context used
✅ Compliance rules (platform): 28 rules

Grey Divider


Action required

1. Skill dirs missing scripts/ 📜 Skill insight ⌂ Architecture
Description
This PR adds new/updated skills that do not include a scripts/ directory with an executable
entry-point, which violates the required skill directory structure. Without an entry-point script,
these skills cannot be invoked consistently and do not meet the repository’s skill packaging
contract.
Code

.claude/skills/summarize-delivery/SKILL.md[R65-69]

+## Method-only — no script, no CLI verb
+
+This is a **method-only** skill (v1), modelled on `/scope` at its birth: a
+`SKILL.md` with an output template and no entry-point script, no new CLI verb.
+The deterministic devague CLI surface is **unchanged** — Devague never spawns
Evidence
PR Compliance ID 731663 requires every skill under .claude/skills/<name>/ to contain SKILL.md
and a scripts/ directory with an executable entry-point. The added summarize-delivery skill
explicitly states it has “no entry-point script”, and the other newly added skills shown are also
introduced as skills but do not include corresponding scripts/ entry-points in this change set.

.claude/skills/summarize-delivery/SKILL.md[65-80]
.claude/skills/challenge/SKILL.md[1-28]
.claude/skills/deviate/SKILL.md[1-26]
.claude/skills/scope/SKILL.md[1-30]
Skill: doc-test-alignment

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Several skills added/modified in this PR do not include a `scripts/` directory with an executable entry-point script, but the compliance rule requires every skill directory to have `SKILL.md` *and* `scripts/` with an entry-point.

## Issue Context
`.claude/skills/summarize-delivery/SKILL.md` explicitly documents itself as having “no entry-point script”, which directly conflicts with the requirement.

## Fix Focus Areas
- .claude/skills/summarize-delivery/SKILL.md[65-80]
- .claude/skills/challenge/SKILL.md[1-25]
- .claude/skills/deviate/SKILL.md[1-30]
- .claude/skills/scope/SKILL.md[1-30]

(Implement by adding `scripts/` directories and at least one executable entry-point script per skill, using the portable bash shebang + `set -euo pipefail`.)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Max-steps parse crash 🐞 Bug ☼ Reliability
Description
ask-colleague.sh accepts an arbitrary string for --max-steps and later unconditionally converts it
with Python int() while rendering results, so a non-numeric value crashes result rendering
(ValueError) and can hide an otherwise valid colleague run output.
Code

.claude/skills/ask-colleague/scripts/ask-colleague.sh[R430-477]

+    ASK_COLLEAGUE_REAL_ARTIFACT_DIR="${1:-}" ASK_COLLEAGUE_GRADABLE="${2:-}" ASK_COLLEAGUE_DRIVE_RC="${3:-}" ASK_COLLEAGUE_JSON="${JSON_OUT:-0}" ASK_COLLEAGUE_MAX_STEPS="${MAX_STEPS:-20}" python3 -c '
+import sys, json, os
+raw = sys.stdin.read().strip()
+json_mode = os.environ.get("ASK_COLLEAGUE_JSON") == "1"
+def _fail(code, message, remediation, detail=None):
+    # #226: in --json mode emit a structured {code, message, remediation} object
+    # on stderr (matching colleague CliError shape) so a machine consumer parses
+    # a failure the same way it parses success; in text mode keep the standard
+    # error:/hint: contract. stdout stays clean (no result) on every path.
+    if json_mode:
+        obj = {"code": code, "message": message, "remediation": remediation}
+        if detail is not None:
+            obj["detail"] = detail
+        sys.stderr.write(json.dumps(obj) + "\n")
+    else:
+        sys.stderr.write("error: " + message + "\n")
+        if detail is not None:
+            sys.stderr.write(detail + "\n")
+        if remediation:
+            sys.stderr.write("hint: " + remediation + "\n")
+    sys.exit(code)
+if not raw:
+    _fail(2, "colleague produced no result on stdout (see diagnostics above)",
+          "re-run; if it persists, check the backend with colleague doctor --probe")
+try:
+    d = json.loads(raw)
+except Exception:
+    _fail(2, "could not parse colleague --json output",
+          "the backend may have emitted non-JSON; see the raw output and diagnostics above",
+          detail=raw[:2000])
+ok = d.get("status") == "ok"
+inc = d.get("incompletion") if isinstance(d.get("incompletion"), dict) else None
+tid = d.get("task_id") or ""
+# Resolve the artifact path to the preserved copy when the drive ran in a
+# throwaway worktree (read-only verbs); the raw JSON points into the now-deleted
+# worktree, so both the digest and the --json output report the real location.
+ap = d.get("artifacts_path")
+real_dir = os.environ.get("ASK_COLLEAGUE_REAL_ARTIFACT_DIR") or ""
+if ap and real_dir:
+    ap = os.path.join(real_dir, os.path.basename(ap))
+# A drive that stopped without calling finish (colleague#142) or exhausted its
+# step budget did NOT deliver an authoritative result — its summary is the model
+# trailing off mid-task. Warn so the caller treats it as a partial, not a verdict.
+# The warning is a DIAGNOSTIC -> always stderr (never stdout), so both the digest
+# and --json keep a clean, machine-readable stdout (no single quotes in this body).
+# Enriched partial warnings: include reached step count and a concrete larger
+# --max-steps to retry with, so the hint is actionable (#194).
+max_steps = int(os.environ.get("ASK_COLLEAGUE_MAX_STEPS", "20"))
Evidence
The script assigns MAX_STEPS directly from the CLI argument without validation and then exports it
into the embedded Python, which calls int(...) without a try/except, so non-numeric input will
raise and abort rendering.

.claude/skills/ask-colleague/scripts/ask-colleague.sh[203-223]
.claude/skills/ask-colleague/scripts/ask-colleague.sh[430-478]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`--max-steps` is stored as a raw string and later parsed with `int(...)` inside `print_result`’s embedded Python. If a user passes a non-integer value, result rendering crashes.

### Issue Context
This is a CLI wrapper: malformed CLI input should produce a controlled, user-input error (exit 1 + clear message), not a Python traceback or aborted rendering.

### Fix Focus Areas
- .claude/skills/ask-colleague/scripts/ask-colleague.sh[203-244]
- .claude/skills/ask-colleague/scripts/ask-colleague.sh[430-478]

### Proposed fix
- When parsing `--max-steps`, validate it matches `^[0-9]+$` and is > 0; otherwise print `error: --max-steps must be a positive integer` and `exit 1`.
- (Optional hardening) Wrap the embedded Python `int(...)` conversion in `try/except` and fall back to 20 if somehow invalid, to prevent rendering failures from any unexpected input source.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Invalid diff cap crash 🐞 Bug ☼ Reliability
Description
front_load_review_diff() uses COLLEAGUE_MAX_OUTPUT_CHARS directly in bash numeric comparison and
substring slicing; if it is set to a non-integer, the review path can terminate with an
arithmetic/substitution error under set -e.
Code

.claude/skills/ask-colleague/scripts/ask-colleague.sh[R820-832]

+front_load_review_diff() {
+    local cap="${COLLEAGUE_MAX_OUTPUT_CHARS:-100000}"
+    printf '%s\n' "--- DIFF UNDER REVIEW (filtered + capped; read specific files for more) ---"
+    git -C "$REPO" diff "$BASE"...HEAD --stat
+    printf '\n'
+    local diff_body
+    diff_body="$(git -C "$REPO" diff "$BASE"...HEAD -- . ':(exclude)*.lock' ':(exclude)**/*.lock' ':(exclude)package-lock.json' ':(exclude)**/package-lock.json' ':(exclude)*.min.js' ':(exclude)**/*.min.js' 2>/dev/null || true)"
+    if [[ "${#diff_body}" -gt "$cap" ]]; then
+        printf '%s\n' "${diff_body:0:$cap}"
+        printf '%s\n' "[... diff body truncated at ${cap} chars; read specific files for the rest ...]"
+    else
+        printf '%s\n' "$diff_body"
+    fi
Evidence
cap is sourced from an environment variable and then used as a numeric operand and substring
length without validation, which is unsafe under set -euo pipefail.

.claude/skills/ask-colleague/scripts/ask-colleague.sh[816-833]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`COLLEAGUE_MAX_OUTPUT_CHARS` is treated as an integer but is not validated. A non-numeric value can break `[[ ... -gt ... ]]` and `${diff_body:0:$cap}` causing the `review` verb to fail.

### Issue Context
This value is environment/config-driven; failures here are confusing and prevent `ask-colleague review` from running.

### Fix Focus Areas
- .claude/skills/ask-colleague/scripts/ask-colleague.sh[816-833]

### Proposed fix
- Validate `cap` with a numeric regex before using it:
 - If invalid (or <= 0), either:
   - print a warning to stderr and fall back to `100000`, or
   - print an error to stderr and exit 2 (config/env error), depending on desired contract.
- Ensure the validated `cap` is used in both the `-gt` comparison and substring slice.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment on lines +65 to +69
## Method-only — no script, no CLI verb

This is a **method-only** skill (v1), modelled on `/scope` at its birth: a
`SKILL.md` with an output template and no entry-point script, no new CLI verb.
The deterministic devague CLI surface is **unchanged** — Devague never spawns

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Skill dirs missing scripts/ 📜 Skill insight ⌂ Architecture

This PR adds new/updated skills that do not include a scripts/ directory with an executable
entry-point, which violates the required skill directory structure. Without an entry-point script,
these skills cannot be invoked consistently and do not meet the repository’s skill packaging
contract.
Agent Prompt
## Issue description
Several skills added/modified in this PR do not include a `scripts/` directory with an executable entry-point script, but the compliance rule requires every skill directory to have `SKILL.md` *and* `scripts/` with an entry-point.

## Issue Context
`.claude/skills/summarize-delivery/SKILL.md` explicitly documents itself as having “no entry-point script”, which directly conflicts with the requirement.

## Fix Focus Areas
- .claude/skills/summarize-delivery/SKILL.md[65-80]
- .claude/skills/challenge/SKILL.md[1-25]
- .claude/skills/deviate/SKILL.md[1-30]
- .claude/skills/scope/SKILL.md[1-30]

(Implement by adding `scripts/` directories and at least one executable entry-point script per skill, using the portable bash shebang + `set -euo pipefail`.)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +430 to +477
ASK_COLLEAGUE_REAL_ARTIFACT_DIR="${1:-}" ASK_COLLEAGUE_GRADABLE="${2:-}" ASK_COLLEAGUE_DRIVE_RC="${3:-}" ASK_COLLEAGUE_JSON="${JSON_OUT:-0}" ASK_COLLEAGUE_MAX_STEPS="${MAX_STEPS:-20}" python3 -c '
import sys, json, os
raw = sys.stdin.read().strip()
json_mode = os.environ.get("ASK_COLLEAGUE_JSON") == "1"
def _fail(code, message, remediation, detail=None):
# #226: in --json mode emit a structured {code, message, remediation} object
# on stderr (matching colleague CliError shape) so a machine consumer parses
# a failure the same way it parses success; in text mode keep the standard
# error:/hint: contract. stdout stays clean (no result) on every path.
if json_mode:
obj = {"code": code, "message": message, "remediation": remediation}
if detail is not None:
obj["detail"] = detail
sys.stderr.write(json.dumps(obj) + "\n")
else:
sys.stderr.write("error: " + message + "\n")
if detail is not None:
sys.stderr.write(detail + "\n")
if remediation:
sys.stderr.write("hint: " + remediation + "\n")
sys.exit(code)
if not raw:
_fail(2, "colleague produced no result on stdout (see diagnostics above)",
"re-run; if it persists, check the backend with colleague doctor --probe")
try:
d = json.loads(raw)
except Exception:
_fail(2, "could not parse colleague --json output",
"the backend may have emitted non-JSON; see the raw output and diagnostics above",
detail=raw[:2000])
ok = d.get("status") == "ok"
inc = d.get("incompletion") if isinstance(d.get("incompletion"), dict) else None
tid = d.get("task_id") or ""
# Resolve the artifact path to the preserved copy when the drive ran in a
# throwaway worktree (read-only verbs); the raw JSON points into the now-deleted
# worktree, so both the digest and the --json output report the real location.
ap = d.get("artifacts_path")
real_dir = os.environ.get("ASK_COLLEAGUE_REAL_ARTIFACT_DIR") or ""
if ap and real_dir:
ap = os.path.join(real_dir, os.path.basename(ap))
# A drive that stopped without calling finish (colleague#142) or exhausted its
# step budget did NOT deliver an authoritative result — its summary is the model
# trailing off mid-task. Warn so the caller treats it as a partial, not a verdict.
# The warning is a DIAGNOSTIC -> always stderr (never stdout), so both the digest
# and --json keep a clean, machine-readable stdout (no single quotes in this body).
# Enriched partial warnings: include reached step count and a concrete larger
# --max-steps to retry with, so the hint is actionable (#194).
max_steps = int(os.environ.get("ASK_COLLEAGUE_MAX_STEPS", "20"))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

2. Max-steps parse crash 🐞 Bug ☼ Reliability

ask-colleague.sh accepts an arbitrary string for --max-steps and later unconditionally converts it
with Python int() while rendering results, so a non-numeric value crashes result rendering
(ValueError) and can hide an otherwise valid colleague run output.
Agent Prompt
### Issue description
`--max-steps` is stored as a raw string and later parsed with `int(...)` inside `print_result`’s embedded Python. If a user passes a non-integer value, result rendering crashes.

### Issue Context
This is a CLI wrapper: malformed CLI input should produce a controlled, user-input error (exit 1 + clear message), not a Python traceback or aborted rendering.

### Fix Focus Areas
- .claude/skills/ask-colleague/scripts/ask-colleague.sh[203-244]
- .claude/skills/ask-colleague/scripts/ask-colleague.sh[430-478]

### Proposed fix
- When parsing `--max-steps`, validate it matches `^[0-9]+$` and is > 0; otherwise print `error: --max-steps must be a positive integer` and `exit 1`.
- (Optional hardening) Wrap the embedded Python `int(...)` conversion in `try/except` and fall back to 20 if somehow invalid, to prevent rendering failures from any unexpected input source.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +820 to +832
front_load_review_diff() {
local cap="${COLLEAGUE_MAX_OUTPUT_CHARS:-100000}"
printf '%s\n' "--- DIFF UNDER REVIEW (filtered + capped; read specific files for more) ---"
git -C "$REPO" diff "$BASE"...HEAD --stat
printf '\n'
local diff_body
diff_body="$(git -C "$REPO" diff "$BASE"...HEAD -- . ':(exclude)*.lock' ':(exclude)**/*.lock' ':(exclude)package-lock.json' ':(exclude)**/package-lock.json' ':(exclude)*.min.js' ':(exclude)**/*.min.js' 2>/dev/null || true)"
if [[ "${#diff_body}" -gt "$cap" ]]; then
printf '%s\n' "${diff_body:0:$cap}"
printf '%s\n' "[... diff body truncated at ${cap} chars; read specific files for the rest ...]"
else
printf '%s\n' "$diff_body"
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

3. Invalid diff cap crash 🐞 Bug ☼ Reliability

front_load_review_diff() uses COLLEAGUE_MAX_OUTPUT_CHARS directly in bash numeric comparison and
substring slicing; if it is set to a non-integer, the review path can terminate with an
arithmetic/substitution error under set -e.
Agent Prompt
### Issue description
`COLLEAGUE_MAX_OUTPUT_CHARS` is treated as an integer but is not validated. A non-numeric value can break `[[ ... -gt ... ]]` and `${diff_body:0:$cap}` causing the `review` verb to fail.

### Issue Context
This value is environment/config-driven; failures here are confusing and prevent `ask-colleague review` from running.

### Fix Focus Areas
- .claude/skills/ask-colleague/scripts/ask-colleague.sh[816-833]

### Proposed fix
- Validate `cap` with a numeric regex before using it:
  - If invalid (or <= 0), either:
    - print a warning to stderr and fall back to `100000`, or
    - print an error to stderr and exit 2 (config/env error), depending on desired contract.
- Ensure the validated `cap` is used in both the `-gt` comparison and substring slice.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant