ask-claude v2.6.1, ask-hermes v4.2.0, ask-dev v1.1.0, create-plan v1.1.0

- ask-claude v2.4.0 -> v2.6.1: Added mandatory disagreement scan (Step 3.5) with web-reference demand + internal consistency check. Updated callouts for the paste-vs-path rule (now HARD RULE, not just example).
- ask-hermes v4.1.1 -> v4.2.0: Added mandatory disagreement scan mirroring ask-claude.
- ask-dev v1.0.0 -> v1.1.0: Added mandatory disagreement scan mirroring ask-claude.
- create-plan v1.1.0 (new): Multi-agent plan-build dispatcher. Trigger phrases, 10-Q brief script (min as needed, max 10), curator dispatch, capture/handoff format, all 6 failure modes. Companion references: curator-framing-prompt.md, deep-research-dispatch-template.md, ask-claude-validation-template.md, structured-brief-10q.md.

5 rounds of Claude validation on the design plan; final SHIP from ask-hermes peer review.
This commit is contained in:
Hermes Agent
2026-07-06 12:51:02 -05:00
parent c6d6db699c
commit 1533a6e8c3
12 changed files with 1775 additions and 8 deletions

View File

@@ -0,0 +1,38 @@
# Adversarial Consulting Pattern
Two-turn technique for higher-quality analysis from Claude Opus. Proven effective for architecture decisions, prompt engineering, and design trade-offs.
## Pattern
**Turn 1:** Ask for advice on the problem. Frame it neutrally — "I need your advice on X."
**Turn 2:** Ask Claude to play devil's advocate against its own Turn 1 advice. Require web searches to ground the pushback. Frame: "Push back on your own advice. Do web searches first. Be genuinely adversarial — if your previous answer was wrong, say so."
## Why It Works
- Claude's first answer is often confident but incomplete — it picks a position and argues for it
- The adversarial prompt forces it to find counter-evidence via web search, surfacing trade-offs it glossed over
- The second turn often partially reverses or qualifies the first, producing a more nuanced final position
- Web search requirement prevents it from just inventing counter-arguments — they must be grounded
## When To Use
- Architecture decisions with real trade-offs
- Prompt engineering (where to place rules, how to structure instructions)
- Security/design reviews
- Any decision where the first answer felt too clean
## When NOT To Use
- Simple factual questions (one turn is enough)
- Time-sensitive queries where the extra turn isn't worth it
- When Claude's first answer already acknowledged uncertainty and trade-offs
## Example Session
Session from 2026-07-02: "Where to add global conciseness instructions to reduce token use?"
Turn 1: Claude recommended SOUL.md edit, argued token math favored it.
Turn 2 (adversarial): Claude partially reversed on token math (user has local Ollama, no per-token pricing), conceded the 14-profile symlink risk, acknowledged compression threshold concern, and revised to: SOUL.md edit + SOUL_OVERRIDE.md mechanism + measurement.
The adversarial turn produced a materially better recommendation than the first pass.

View File

@@ -0,0 +1,151 @@
# Ask-Claude Payload Pattern
Session-specific detail for the `ask-claude` skill: how to send questions to Claude
Opus 4.8 on 10.0.0.28 reliably, capture the session_id, handle shell metacharacters,
and avoid the filename-collision gotcha that bites when `read_file` returns a
different schema than expected.
## Pattern: scp + ask.sh
The `ask.sh` wrapper on 10.0.0.28 handles mktemp snapshot, claude invocation
(`--output-format json --model claude-opus-4-8 --max-turns 30`, `timeout 280`, `|| true`),
fetches the usage API, and runs `merge.py` to produce a single JSON envelope.
**Why scp, not heredoc:** shell metacharacters (`"`, `$`, `(`, `)`, backticks) in
the question content will break heredoc-based writes. For ANY non-trivial question
write the question to a local temp file, scp it, and pass the remote path to
`ask.sh --qfile`.
```bash
# 1. Write question locally
write_file("/tmp/ask-claude-q.txt", content=question)
# 2. Copy to remote
terminal("scp /tmp/ask-claude-q.txt n8n@10.0.0.28:/tmp/ask-claude-q.txt")
# 3. Run via ask.sh
terminal("ssh n8n@10.0.0.28 '~/claude/hermes_support/ask.sh --qfile /tmp/ask-claude-q.txt'")
```
## JSON envelope fields
Always parse these from the `--output-format json` response:
| Field | When | Use |
|---|---|---|
| `session_id` | Always (including errors) | Capture for `--resume` follow-ups |
| `result` | Success | The answer text |
| `is_error` | Always | `true` if anything failed |
| `subtype` | Always | `success` / `error_max_turns` / `error_budget` |
| `total_cost_usd` | Always | Track spend |
| `num_turns` | Always | How many agentic loops |
| `usage.input_tokens` | Always | Context usage |
| `usage.cache_creation_input_tokens` | Always | Context usage |
| `usage.cache_read_input_tokens` | Always | Context usage |
| `output_tokens` | Always | Context usage |
| `modelUsage.{model}.contextWindow` | Always | Context window size — iterate keys, don't hardcode |
| `stop_reason` | Always | Why Claude stopped |
**Critical: capture `session_id` from EVERY response, including errors.** A turn can
error yet still advance the session. If you only store it on success, `--resume` breaks.
**Critical: detect `error_max_turns` via `subtype`, not `is_error`.** `error_max_turns`
has `is_error: false` but no `result` field. Empty-answer detection requires checking
`subtype == 'error_max_turns'`.
## Asking Claude to validate a file
Claude (Opus on 10.0.0.28) has **no filesystem access to the operator's machine**.
When asking Claude to validate a plan, code, or doc:
1. **Read the file locally** with `read_file` or `terminal cat > /tmp/file.txt`
2. **Inline the content in the question** as a fenced block
3. **Tell Claude explicitly** the file is pasted inline (not a path to read)
**Common failure mode:** pasting a path like `/home/n8n/workspace/...` and asking
Claude to validate it. Claude will reply "I can't read that file" and refuse to
validate. Always inline.
## Filename-collision gotcha (execute_code + read_file)
`hermes_tools.read_file` inside `execute_code` returns a different schema than the
top-level `read_file` tool. Inside a script:
```python
from hermes_tools import read_file
r = read_file("/path/to/file")
# Schema: {"status": ..., "message": ..., "path": ..., "dedup": ..., "content_returned": ...}
# NO "content" key. Use the top-level read_file tool, OR use terminal cat.
```
**Workaround patterns:**
```python
# Pattern 1: terminal cat to a temp file, then open()
import subprocess
subprocess.run(["cp", "/path/to/file", "/tmp/working.txt"])
with open("/tmp/working.txt") as f:
content = f.read()
# Pattern 2: shell-out to the file directly
with open("/path/to/file") as f:
content = f.read() # works in execute_code without hermes_tools
```
This gotcha caused patch errors in a multi-file edit session: a patch string was
constructed from `r["content"]` which didn't exist inside `execute_code`. Switched
to `subprocess.run` + `with open()` to read reliably.
## Pre-dispatch model and config
- **Always pass `--model claude-opus-4-8` explicitly.** Profile defaults drift silently.
- **Always set `--max-turns`.** Default 30 is good for analysis. Lower for trivial
questions; higher (50+) for deep architectural reviews.
- **Always wrap with `timeout 280`.** Prevents runaway hangs. SSH itself has 300s.
- **Always add `|| true` after claude invocation.** `set -e` would kill the script
on non-zero exit, but the error JSON is still parseable.
- **Always use `mktemp` for temp files on the remote.** `/tmp/ask-claude-q.txt` is
a fixed path that concurrent Hermes sessions clobber.
## Multi-turn session lifecycle
- First `ask-claude` call in a Hermes session → fresh session (no `--resume`).
- Every subsequent call in the same Hermes session → `--resume <session_id>`.
- Sessions auto-expire after ~5 hours of inactivity. No cleanup needed.
- If the operator starts a new Hermes session (`.hermes/sessions/` rotates),
the Claude session is also gone — `--resume` will fail.
- For maximum continuity, capture `session_id` in the operator-visible relay
text so the operator can resume manually if the Hermes session restarts.
## Usage and context alerts
Apply on every turn:
| Check | Threshold | Action |
|---|---|---|
| Context % (from JSON envelope) | ≥ 80% | Warn: "wrap up or start fresh" |
| Session 5h utilization (OAuth API) | ≥ 80% | Warn + show reset time, offer Sonnet |
| Weekly 7d utilization (OAuth API) | ≥ 90% | Critical warning + reset time |
| Unavailable (error_budget / rate-limit) | N/A | Report exact reset time |
**The OAuth usage API aggressively rate-limits.** Call at most every ~5 minutes.
Cache the last good value. Swallow all errors (429s, timeouts). Never gate a turn
on this call.
## Common error patterns
- `error_max_turns` — question too complex, increase `--max-turns` or simplify.
`is_error: false`, but no `result` field — check `subtype` explicitly.
- `error_budget` — hit spending cap, check Pro limits.
- Empty response — timeout (increase from 280s), OOM, or crash.
- Non-JSON response — SSH dropped mid-call, Claude crashed before writing output.
- `ask.sh` returns `{"is_error": true, "error": "no Claude output"}` but direct
`claude -p` works — wrapper has a known failure mode. Fall back to direct:
`ssh n8n@10.0.0.28 'cd ~/claude/hermes_support && timeout 280 /home/n8n/.local/bin/claude -p "$(cat /tmp/q.txt)" --output-format json --model claude-opus-4-8 --max-turns 30 || true'`
## When the operator pushes back
After applying Claude's recommendations, ALWAYS emit the disagreement scan (see
SKILL.md §3.5). Skipping this is a failure mode — both silently-accepting and
silently-dropping are bugs. The scan is mandatory before declaring a Claude turn
resolved.

View File

@@ -0,0 +1,156 @@
# Peer Response Protocol — Disagreement Scan, Web-Reference Mandate, Cross-Doc Desync
This reference documents the three cross-cutting patterns that emerged from the
v2.6.0 ask-claude update. They apply to ANY peer/consultant dispatch
(ask-claude, ask-hermes, ask-dev, ask-claude-as-curator, future peers) and to
ANY document-edit workflow where multiple sections describe the same thing.
## 1. Disagreement Scan (MANDATORY before applying)
Source: ask-claude v2.6.0 Step 3.5, ask-hermes v4.2.0, ask-dev v1.1.0 (all
updated in the same session).
**Rule:** For every peer response, before applying or moving on, walk through
the peer's findings and classify each one:
- **Agree + will apply** → no action
- **Agree + will skip** → state explicitly WHY you are skipping. Do not
silently drop. The "why" matters — operator can re-prioritize if the
rationale is wrong.
- **Disagree** → push back via `--resume` (ask-hermes/ask-dev) or a follow-up
turn (ask-claude). Either send the pushback OR state why you decided not to.
- **Disagreed silently dropped: should be EMPTY.** If non-empty, that's a
bug — surface it.
**Output format (emit every time):**
```
[Peer's findings as-is]
## My disagreement scan
- **Agreed and applied:** [list]
- **Agreed but skipped:** [item] — [reason]
- **Disagreed and pushed back:** [item] — [what I said]
- **Web references / live tests requested:** [items where I demanded a URL or run]
- **Disagreed silently dropped:** (should be empty — if not, justify)
```
The "disagreed silently dropped" line is the tripwire. Empty is the only
acceptable state. Non-empty means the agent is rationalizing acceptance
without doing the work.
## 2. Web-Reference Mandate (for unverified concrete claims)
Source: ask-claude v2.6.0, ask-hermes v4.2.0 (already had canonical form), ask-dev v1.1.0.
**Rule:** For any peer claim that is a concrete factual statement
(tool version, API behavior, library status, system state assertion,
"best practice" recommendation) AND where the peer did NOT cite a source URL
inline OR run a live command to verify, send a follow-up demanding the
verification.
**Pattern:**
> "Show me the command output that supports X. I want a URL or a live test,
> not reasoning."
Claude has web search (mcp_searxng_searxng_web_search). Hermes peers have
filesystem + terminal + web search. **No concrete factual claim is acceptable
without a source.**
**Applies to:**
- Tool versions, port numbers, env var names, config keys
- "X is broken" / "Y is down" system state assertions
- Library APIs, package availability, install commands
- Architecture pattern recommendations
- "Best practice" assertions
- Anything the plan or system will depend on
## 3. Cross-Document Desync (the recurring edit pattern)
Source: observed across 5 rounds of plan validation in a single session
(plan_skill_plan.md v1 → v5). The pattern fires every time.
**The problem:** When a value (count, name, path, number) changes in a
document with multiple sections describing the same thing (prose + diagram +
checklist + cross-references), the edit almost always lands in the prose
section and gets missed in the diagram and checklist.
**Symptom:** Sections describe the same construct with different values. The
section that gets READ CAREFULLY (prose) is correct; the section that gets
SCANNED (diagram, checklist) is stale.
**Meta-pattern from the workshop (5 rounds of validation, 4 had desync):**
the first round almost always misses 2-3 cross-references. The second round
catches 1-2 more. The third+ rounds usually surface real design issues
that the desync had been hiding. **Treat the first round of "all clean"
findings as suspicious** — re-grep for the changed value across the whole
document before declaring done.
**Mitigation (MANDATORY before finalizing any doc edit):**
1. Identify the value being changed (count, name, path, etc.)
2. `grep -nE "<old_value>" <file>` to find every occurrence
3. Update ALL occurrences, not just the obvious one
4. Re-grep with the new value to confirm zero stragglers
5. For cross-section references (e.g., "see §6 for the 9 pitfalls" when
§6 now has 11), grep the literal cross-reference too — they are
often hardcoded numbers that don't update with the section they point
at
**This applies to:**
- Plan documents (sections, diagrams, checklists, cross-references)
- Skill files (description, examples, pitfall counts, version strings)
- Config files (any field referenced in multiple sections)
- Any markdown with both ASCII diagrams AND prose describing the diagram
**The lesson generalizes:** if a value is mentioned in 3+ places, expect
to miss at least one on each edit. Treat the grep as a pre-commit hook.
**Pre-finalize workflow (run this every time, no exceptions):**
```bash
# 1. Identify the value you just changed
OLD_VALUE="<the value before your edit>"
NEW_VALUE="<the value after your edit>"
# 2. Find any stragglers of the old value
grep -nE "$OLD_VALUE" <file> || echo "OK: no stragglers of $OLD_VALUE"
# 3. Confirm the new value is in the expected places
grep -nE "$NEW_VALUE" <file>
# 4. Find any cross-section references that hardcode the count/number
grep -nE "§[0-9].*\b$OLD_VALUE\b" <file> || echo "OK: no §X cross-refs to $OLD_VALUE"
```
Run this even when "the edit is in one obvious place." Multi-place edits
hide.
## 4. Pre-Build Verification Gate
Source: plan_skill_plan.md §7, surfaced when Claude flagged session-id
line-1 capture as a first-run failure risk that "five rounds of counting-fixes
never touched."
**The problem:** Plans can be internally consistent on design while
containing hidden assumptions about the runtime environment (positional
output parsing, banner formats, version-specific CLI flags, etc.). These
don't show up in design review.
**Mitigation:** Before declaring any plan "buildable," list the
runtime-assumption items and empirically verify each one against the
actual deployed environment. Common categories:
- Positional parsing assumptions (line 1 of output, JSON field order)
- CLI flag assumptions (`--max-turns 600` works, `--yolo` works, etc.)
- Path assumptions (config files at expected locations, skills registered)
- Version assumptions (skill X is at version Y, has feature Z)
**Output: a verified-items checklist in the plan's §7.** Each item is
either confirmed (with the actual command output) or marked as
"out of scope" (with the reason).
## When to apply this protocol
- After EVERY ask-claude, ask-hermes, ask-dev, or any peer response —
emit the disagreement scan output.
- After EVERY multi-section doc edit — grep for the old value, then re-grep.
- Before declaring any plan "buildable" — verify the runtime-assumption
checklist empirically.

View File

@@ -0,0 +1,111 @@
# Plan Validation Prompt Pattern
The most effective prompt shape for using `ask-claude` to validate a plan. Proven against Opus 4.8 on real plan files (workshopped Jul 6 2026 against `plan_skill_plan.md`).
## Why This Pattern
Generic "review this plan" prompts fail three ways:
1. Claude proposes new features instead of finding flaws.
2. Claude's checks are vibes ("this looks incomplete") instead of evidence-grounded.
3. Claude's review isn't constrained to checkable-from-text-only properties, so it hallucinates verifications.
The pattern below solves all three.
## The Template
```
Validate this plan. Read it in full first.
CRITICAL CONSTRAINT: Do NOT propose new features, new architecture, or new complexity.
Your job is to find FLAWS in what's already proposed — not to add more. If you find
a problem, say what's wrong and suggest the SIMPLEST fix.
CONTEXT (why this plan exists):
- <one paragraph: the goal, what triggered the plan, what skills/tools it reuses>
VALIDATE:
1. <dimension 1 — must be checkable from plan text alone>
2. <dimension 2>
3. ...
Report format:
- Release-blockers (must fix before building)
- Medium (should fix)
- Low (nice to have)
- Pass-criteria met / not met
Then: give 2-3 concrete suggestions for how to make this plan better ACHIEVE the
operator's goal. Be specific.
Do not rewrite the plan. Just report findings and suggestions.
==== ARTIFACT BEGINS ====
<paste full artifact here>
==== ARTIFACT ENDS ====
```
## Why It Works
| Ingredient | Purpose |
|---|---|
| `CRITICAL CONSTRAINT: Do NOT propose new features` | Kills Claude's feature-creep reflex (his default mode is thoroughness → overengineering). |
| `say what's wrong and suggest the SIMPLEST fix` | Forces fixes to be small. Big fixes = new complexity = rejected. |
| Numbered VALIDATE list with checkable dimensions | Forces structured findings. If a dimension is uncheckable from the artifact text alone, drop it. |
| Pass-criteria met / not met | Binary verdict the dispatcher can act on. |
| `2-3 concrete suggestions to ACHIEVE the goal` | Lets Claude contribute value (refinements) without breaking the no-new-features rule. |
| Pasted artifact with markers | Avoids the "file not found" wasted turn (see SKILL.md Pitfalls). |
## Dimensions That Work (Checkable from Text)
- **Completeness** — does the plan cover all phases / all sub-tasks of the topic?
- **Internal consistency** — do the steps in §3 actually produce the outputs claimed in §2?
- **TDD discipline** — is there a failing test before every code-producing task?
- **Bite-size** — are all tasks 2-5 minutes of focused work?
- **Bite-size inverse** — which task is suspiciously large and should be split?
- **Output contract** — are the file paths, names, and structures consistent across all sections?
- **Trigger / dispatch chain** — does the plan's "use skill X" actually do what's claimed? (e.g., "uses `ask-hermes`" — does it say with what prompt, with what resume rule?)
- **Session management** — same-topic = resume, new-topic = fresh. Does the plan enforce this?
## Dimensions That DO NOT Work (Uncheckable from Text)
These belong to the *dispatcher* (which has web + filesystem), NOT to Claude:
- "Are versions current as of 2026?" → Claude has no live web access in print mode.
- "Do all file paths exist in the project?" → Claude has no filesystem access to the operator's project.
- "Does this conflict with installed packages?" → Claude has no access to the operator's env.
If you ask Claude these, it will hallucinate. Either drop them from the prompt or pass the evidence inline (e.g., "Here is the official v0.27.0 release page contents: [paste]").
## When To Use
- Plan for a new skill, integration, infrastructure change, profile setup
- Plan for a multi-file feature build
- Plan for a research deliverable that needs structural review
- ANY plan you're about to ask the user to approve
## When NOT To Use
- Single-step, trivial changes (one file, one config edit) — overkill
- Research-only outputs (use the `deep-research` validate-fix cycle instead — see `deep-research` skill)
- Plans that are themselves research findings (Claude should be reading the source URLs, not just the synthesis)
## Example: Real Validation Run
Session: 2026-07-06, validating `plan_skill_plan.md`.
**What worked:**
- 3 release-blockers caught: (1) Phase 1 interactive Q&A contradicts "curator runs autonomously", (2) Claude template asked Claude to check things it structurally couldn't, (3) output filename contract contradictory.
- 6 medium findings: deep-research sync vs async, who writes pre-plan.md, session-id capture fragility, trigger-phrase collision, --no-research breaks checklist, no Claude-down fallback.
- 4 low findings: rename `_pre-plan.md`, weak self-review, missing validation persistence, false "reproducible" claim.
- 3 actionable suggestions, including the highest-leverage one: "front-load the brief into the dispatcher" — solved B1 cleanly by changing where the Q&A lives.
**What didn't:**
- None. Cost $0.32, caught real defects. Beats running the plan and discovering them at runtime.
## Variations
**For research-heavy plans** (where the primary risk is factual error, not structure): use the `deep-research` skill's validate-fix cycle instead — dispatch `ask-hermes` to web-verify each claim, then feed the report back to `deep-research --resume`.
**For plans you wrote yourself** (high self-review blindness): prepend `Be especially skeptical of the actor assignments and the open questions — those are where author bias lives.`