diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 1f579bd..1738836 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "intent-layer", - "version": "1.2.0", + "version": "2.0.0", "description": "Hierarchical AGENTS.md infrastructure for AI-navigable codebases. Create CLAUDE.md/AGENTS.md files that help AI agents navigate your codebase like senior engineers.", "author": { "name": "Intent Layer Contributors" diff --git a/CLAUDE.md b/CLAUDE.md index 92a5ce9..798eeb4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -40,13 +40,12 @@ intent-layer-plugin/ ├── .claude-plugin/ │ └── plugin.json # Plugin manifest (name, version, author) ├── skills/ # Slash-command skills (/intent-layer, etc.) -│ ├── intent-layer/ # Main setup skill + sub-skills (git-history, pr-review, pr-review-mining) -│ ├── intent-layer-maintenance/ -│ ├── intent-layer-onboarding/ -│ ├── intent-layer-query/ -│ ├── intent-layer-compound/ # End-of-session learning capture -│ ├── intent-layer-health/ # Quick health check -│ └── review-mistakes/ # Interactive mistake triage +│ ├── intent-layer/ # Smart router + sub-skills (git-history, pr-review, pr-review-mining) +│ │ └── workflows/ # Reference docs for setup, maintain, onboard flows +│ ├── intent-layer-maintain/ # Ongoing maintenance (state = complete) +│ ├── intent-layer-review/ # Batch triage of pending learnings +│ ├── intent-layer-query/ # Query Intent Layer for answers +│ └── intent-layer-health/ # Quick health check ├── agents/ # Specialized subagents │ ├── explorer.md # Analyzes directories, proposes nodes │ ├── validator.md # Deep validation against codebase @@ -67,7 +66,7 @@ intent-layer-plugin/ | Component | Purpose | Invocation | |-----------|---------|------------| -| **Skills** | Interactive workflows for setup/maintenance | `/intent-layer`, `/intent-layer-maintenance` | +| **Skills** | Interactive workflows for setup/maintenance | `/intent-layer`, `/intent-layer:maintain`, `/intent-layer:review` | | **Agents** | Specialized analysis tasks | Auto-invoked by Claude when relevant | | **Hooks** | Learning loop: auto-capture, pitfall injection, staleness check | 5 hooks: SessionStart, PreToolUse, PostToolUse, PostToolUseFailure, Stop | @@ -97,7 +96,7 @@ intent-layer-plugin/ | `capture_mistake.sh` | Record mistakes for learning loop (manual) | | `review_mistakes.sh` | Interactive triage of pending mistake reports | | `post-edit-check.sh` | Hook script for edit tracking | -| `stop-learning-check.sh` | Stop hook: two-tier learning classifier (heuristic + Haiku) | +| `stop-learning-check.sh` | Stop hook: three-tier learning classifier (heuristic + Haiku classify + Haiku extract) | | `inject-learnings.sh` | SessionStart hook: inject recent learnings | | `pre-edit-check.sh` | PreToolUse hook: inject covering AGENTS.md sections | | `capture-tool-failure.sh` | PostToolUseFailure hook: create skeleton reports | @@ -127,14 +126,11 @@ Internal scripts used by hooks and other scripts: ### Skill Relationships -- `intent-layer` → Initial setup (state = none/partial) -- `intent-layer-maintenance` → Ongoing updates (state = complete) -- `intent-layer-onboarding` → Orientation for new developers -- `intent-layer-query` → Answer questions using Intent Layer -- `intent-layer:clean` → Remove Intent Layer from a repo -- `intent-layer-compound` → End-of-session learning capture and triage -- `intent-layer-health` → Quick health check (validation + staleness + coverage) -- `review-mistakes` → Interactive triage of pending mistake reports +- `/intent-layer` → Smart router: detects state, counts pending, routes to appropriate action +- `/intent-layer:maintain` → Ongoing updates (state = complete) +- `/intent-layer:review` → Batch triage of pending learnings (auto-captured by stop hook) +- `/intent-layer:query` → Answer questions using Intent Layer +- `/intent-layer:health` → Quick health check (validation + staleness + coverage) All skills share scripts via `${CLAUDE_PLUGIN_ROOT}/scripts/`. diff --git a/README.md b/README.md index 26a6077..0d4c557 100644 --- a/README.md +++ b/README.md @@ -58,11 +58,11 @@ Interactive workflows invoked via slash commands: | Skill | Purpose | Command | |-------|---------|---------| -| `intent-layer` | Set up new Intent Layer infrastructure | `/intent-layer` | -| `intent-layer-maintenance` | Maintain existing Intent Layers | `/intent-layer-maintenance` | -| `intent-layer-onboarding` | Orient new developers using Intent Layer | `/intent-layer-onboarding` | -| `intent-layer-query` | Query Intent Layer for answers | `/intent-layer-query` | -| `review-mistakes` | Interactive review of pending mistake reports | `/review-mistakes` | +| `intent-layer` | Smart router: detects state, routes to setup/maintain/review | `/intent-layer` | +| `intent-layer:maintain` | Maintain existing Intent Layers | `/intent-layer:maintain` | +| `intent-layer:review` | Batch triage of pending learnings | `/intent-layer:review` | +| `intent-layer:query` | Query Intent Layer for answers | `/intent-layer:query` | +| `intent-layer:health` | Quick health check (validation + staleness + coverage) | `/intent-layer:health` | ### Agents @@ -98,7 +98,7 @@ Agent makes mistake → PostToolUseFailure auto-creates skeleton Stop hook evaluates: enrich or discard? ↓ Next session: Agent offers interactive review - or user runs /review-mistakes + or user runs /intent-layer:review ↓ User decides: Accept / Reject / Discard ↓ (on accept) @@ -110,7 +110,7 @@ Agent makes mistake → PostToolUseFailure auto-creates skeleton PreToolUse injects relevant pitfalls before edits ``` -**Interactive review**: When pending reports exist, the agent offers to walk you through them conversationally. You can also explicitly run `/review-mistakes` to start a review session. +**Interactive review**: When pending reports exist, the agent offers to walk you through them conversationally. You can also explicitly run `/intent-layer:review` to start a review session. **Supporting scripts:** @@ -145,7 +145,7 @@ Agent makes mistake → PostToolUseFailure auto-creates skeleton ./scripts/capture_pain_points.sh pain_points.md # Run maintenance workflow -# In Claude Code: /intent-layer-maintenance /path/to/project +# In Claude Code: /intent-layer:maintain /path/to/project ``` ### Onboarding @@ -154,8 +154,8 @@ Agent makes mistake → PostToolUseFailure auto-creates skeleton # Generate orientation overview ./scripts/generate_orientation.sh /path/to/project -# Or use the skill interactively -# In Claude Code: /intent-layer-onboarding /path/to/project +# Or use the router which includes onboarding as an option +# In Claude Code: /intent-layer /path/to/project ``` ## Plugin Structure @@ -165,17 +165,21 @@ intent-layer-plugin/ ├── .claude-plugin/ │ └── plugin.json # Plugin manifest ├── skills/ # Slash-command skills -│ ├── intent-layer/ -│ ├── intent-layer-maintenance/ -│ ├── intent-layer-onboarding/ -│ └── intent-layer-query/ +│ ├── intent-layer/ # Smart router + sub-skills +│ │ └── workflows/ # Reference docs for flows +│ ├── intent-layer-maintain/ +│ ├── intent-layer-review/ +│ ├── intent-layer-query/ +│ └── intent-layer-health/ ├── agents/ # Specialized subagents │ ├── explorer.md │ ├── validator.md -│ └── auditor.md +│ ├── auditor.md +│ └── change-tracker.md ├── hooks/ -│ └── hooks.json # PostToolUse hook config +│ └── hooks.json # 5 hook slots ├── scripts/ # Shared bash scripts +├── lib/ # Internal library scripts └── references/ # Templates and guides ``` @@ -203,7 +207,7 @@ All scripts support: - Projects that change so rapidly the docs would be stale immediately - Codebases you won't use AI agents on -### intent-layer-maintenance +### intent-layer:maintain **Good for:** - Quarterly reviews of existing Intent Layers @@ -212,7 +216,7 @@ All scripts support: - When agents consistently get confused about something **Not good for:** -- Initial setup (use `intent-layer` first) +- Initial setup (use `/intent-layer` first — it routes automatically) - Minor cosmetic changes that don't affect behavior ## CI Integration diff --git a/docs/brainstorms/2026-02-15-ux-refactor-brainstorm.md b/docs/brainstorms/2026-02-15-ux-refactor-brainstorm.md new file mode 100644 index 0000000..640dc6a --- /dev/null +++ b/docs/brainstorms/2026-02-15-ux-refactor-brainstorm.md @@ -0,0 +1,113 @@ +# Intent Layer UX Refactor — Brainstorm + +Date: 2026-02-15 + +## What we're building + +A full UX overhaul of the intent-layer plugin, restructuring from a flat list of 7 skills into a three-tier architecture (commands → skills → agents), redesigning the learning review pipeline for batch triage, and improving visual output quality across hooks and dashboards. + +## Why this approach + +The plugin grew organically and now has 7 slash commands with unclear boundaries. Users don't know which to run when. The learning capture pipeline requires 10+ interactions per session for a handful of learnings. Hook outputs dump full AGENTS.md sections before every edit with no deduplication. Dashboard scripts output plain ASCII with no visual hierarchy. + +The compound-engineering plugin demonstrates a working three-tier pattern: workflow commands chain skills and spawn agents. We're adopting this pattern while also fixing the review pipeline and output quality. + +## Key decisions + +### 1. Three-tier reorganization + +Restructure the plugin into three tiers: + +**Commands** (what users run): +- `/intent-layer` — smart router that detects state and presents the right action +- `/intent-layer:review` — batch learning triage (replaces `/intent-layer-compound` + `/review-mistakes`) +- Workflow sub-commands: `/intent-layer:maintain`, `/intent-layer:health`, `/intent-layer:query` + +**Skills** (reusable knowledge, not interactive): +- `node-authoring/` — how to write good AGENTS.md content +- `hierarchy-design/` — T-shaped context, LCA placement, compression +- `learning-loop/` — how the capture → triage → integrate cycle works + +**Agents** (already exist, unchanged): +- `explorer.md`, `validator.md`, `auditor.md`, `change-tracker.md` + +Old standalone skills (`intent-layer-onboarding`, `intent-layer-health`, `intent-layer-query`) become sub-flows of the router or workflows. No migration aliases — clean break. + +### 2. Review pipeline redesign + +**Phase 1: Capture (automatic, non-blocking)** +- Stop hook **never blocks session exit** +- Auto-classifies confidence: high / medium / low +- Appends confidence score and suggested section to each skeleton report +- Captures go silently to `.intent-layer/mistakes/pending/` + +**Phase 2: Triage (batch, one interaction)** +- `/intent-layer:review` shows ranked table of all pending learnings +- User selects which to accept via `AskUserQuestion` with `multiSelect: true` +- Remaining are discarded or deferred in one action +- Accepted items integrate automatically — no further prompts + +**Phase 3: Auto-accept (optional fast path)** +- `--auto-accept-high` flag integrates high-confidence items without prompting +- Only medium/low items shown for review + +### 3. Smart router + +`/intent-layer` detects state and routes: + +| State | Condition | Action | +|-------|-----------|--------| +| none | No CLAUDE.md or AGENTS.md | Offer setup workflow | +| partial | CLAUDE.md exists, no children | Continue setup | +| complete + pending | Learnings waiting | Offer review first | +| complete + stale | Nodes >30 days old | Suggest maintenance | +| complete + healthy | Everything OK | Show menu: maintain, query, export | + +Priority order: pending learnings → stale nodes → healthy menu. + +### 4. Hook output deduplication + +PreToolUse changes: +- Track injected nodes in session-scoped temp file +- First edit to a file: full injection (Pitfalls, Checks, Patterns, Context) +- Same node injected <5 min ago: one-liner summary instead of full content +- High-risk areas (mistake history): always full injection with warning banner + +PostToolUse changes: +- Only fire "review if behavior changed" when the edited file is actually referenced in the covering AGENTS.md (check Code Map, Entry Points sections) + +### 5. Colon-namespaced naming + +| Command | Purpose | +|---------|---------| +| `/intent-layer` | Smart router (main entry point) | +| `/intent-layer:review` | Batch learning triage | +| `/intent-layer:maintain` | Post-change maintenance pass | +| `/intent-layer:health` | Quick validation (staleness + coverage) | +| `/intent-layer:query` | Answer questions using Intent Layer | + +Five commands total, all under one namespace. Onboarding becomes a sub-flow of the router (not a standalone command). + +### 6. Dashboard color styling + +Add ANSI color support with `NO_COLOR` env var opt-out: +- Green for healthy/passing/high rates +- Yellow for warnings/stale/medium confidence +- Red for failures/critical/low rates +- Bold for headers and key metrics +- Dim for secondary info + +Add `setup_colors()` helper to `lib/common.sh`. Apply to `show_status.sh`, `show_hierarchy.sh`, `show_telemetry.sh`, and `audit_intent_layer.sh`. + +## Open questions + +1. Should the smart router also auto-run on SessionStart (via hook) instead of requiring `/intent-layer`? +2. Should `/intent-layer:review` be auto-suggested at session end (non-blocking hint) when there are pending learnings? +3. What confidence threshold separates high from medium? Current stop hook uses a two-tier classifier (heuristic + Haiku) — should the confidence score come from the Haiku response directly? + +## Scope exclusions + +- MCP server changes (already built, works fine) +- Template system changes (already built) +- Agent restructuring (agents already follow the right pattern) +- Backward-compatible aliases for old skill names (clean break) diff --git a/lib/common.sh b/lib/common.sh index a66569b..7fd991a 100755 --- a/lib/common.sh +++ b/lib/common.sh @@ -79,6 +79,18 @@ file_newer_than() { [[ "$file_date" > "$cutoff_date" || "$file_date" == "$cutoff_date" ]] } +# Set up ANSI color variables for CLI dashboard scripts. +# Checks both TTY detection and NO_COLOR convention (https://no-color.org). +# IMPORTANT: Hook scripts must NEVER call this — color codes corrupt JSON output. +setup_colors() { + if [[ -t 1 ]] && [[ -z "${NO_COLOR:-}" ]]; then + RED=$'\033[31m'; GREEN=$'\033[32m'; YELLOW=$'\033[33m' + BOLD=$'\033[1m'; DIM=$'\033[2m'; RESET=$'\033[0m' + else + RED=''; GREEN=''; YELLOW=''; BOLD=''; DIM=''; RESET='' + fi +} + # Output JSON for hook response (additionalContext pattern) output_context() { local hook_event="$1" diff --git a/references/agent-feedback-protocol.md b/references/agent-feedback-protocol.md index 30d5326..db26f4d 100644 --- a/references/agent-feedback-protocol.md +++ b/references/agent-feedback-protocol.md @@ -130,7 +130,7 @@ Before marking task complete, check if you encountered Intent Layer gaps. Include Intent Layer feedback in PR description if findings emerged. ### Quarterly Maintenance -Use accumulated feedback as input to `intent-layer-maintenance` skill. +Use accumulated feedback as input to `intent-layer:maintain` skill. ## Example Workflow diff --git a/references/parallel-orchestration.md b/references/parallel-orchestration.md index 9f7d79e..980e934 100644 --- a/references/parallel-orchestration.md +++ b/references/parallel-orchestration.md @@ -461,7 +461,7 @@ Formula: `batch_size = min(available_agents, resource_limit, task_count)` 4. Present to user ``` -### /intent-layer-maintenance +### /intent-layer:maintain ``` 1. detect_staleness.sh → List flagged nodes diff --git a/scripts/audit_intent_layer.sh b/scripts/audit_intent_layer.sh index 458eacf..fe458d4 100755 --- a/scripts/audit_intent_layer.sh +++ b/scripts/audit_intent_layer.sh @@ -43,6 +43,15 @@ EOF # Script directory for calling sibling scripts SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# Source common.sh for setup_colors +if [[ -f "$SCRIPT_DIR/../lib/common.sh" ]]; then + # shellcheck source=../lib/common.sh + source "$SCRIPT_DIR/../lib/common.sh" + setup_colors +else + RED=''; GREEN=''; YELLOW=''; BOLD=''; DIM=''; RESET='' +fi + # Defaults TARGET_PATH="." JSON_OUTPUT=false @@ -595,16 +604,22 @@ EOF fi # Text output -cat << EOF -Intent Layer Audit Report -========================= - -EOF +echo "${BOLD}Intent Layer Audit Report${RESET}" +echo "${BOLD}=========================${RESET}" +echo "" -echo "VALIDATION ($NODE_COUNT nodes checked)" -echo " ✓ PASS: $VAL_PASS nodes" -echo " ⚠ WARN: $VAL_WARN nodes" -echo " ✗ FAIL: $VAL_FAIL nodes" +echo "${BOLD}VALIDATION${RESET} ($NODE_COUNT nodes checked)" +echo " ${GREEN}✓${RESET} PASS: $VAL_PASS nodes" +if [ "$VAL_WARN" -gt 0 ]; then + echo " ${YELLOW}⚠${RESET} WARN: ${YELLOW}$VAL_WARN${RESET} nodes" +else + echo " ${GREEN}⚠${RESET} WARN: $VAL_WARN nodes" +fi +if [ "$VAL_FAIL" -gt 0 ]; then + echo " ${RED}✗${RESET} FAIL: ${RED}$VAL_FAIL${RESET} nodes" +else + echo " ${GREEN}✗${RESET} FAIL: $VAL_FAIL nodes" +fi if [ -n "$VAL_ISSUES" ]; then IFS=';' read -ra issue_arr <<< "$VAL_ISSUES" @@ -613,17 +628,25 @@ if [ -n "$VAL_ISSUES" ]; then IFS='|' read -r level path desc <<< "$entry" [ -z "$level" ] && continue case $level in - FAIL) echo " ✗ $path - $desc" ;; - WARN) echo " ⚠ $path - $desc" ;; + FAIL) echo " ${RED}✗${RESET} $path - $desc" ;; + WARN) echo " ${YELLOW}⚠${RESET} $path - $desc" ;; esac done fi echo "" -echo "STALENESS" -echo " Fresh (<30 days): $STALE_FRESH nodes" -echo " Aging (30-90 days): $STALE_AGING nodes" -echo " Stale (>90 days): $STALE_STALE node(s)" +echo "${BOLD}STALENESS${RESET}" +echo " ${GREEN}Fresh${RESET} (<30 days): $STALE_FRESH nodes" +if [ "$STALE_AGING" -gt 0 ]; then + echo " ${YELLOW}Aging${RESET} (30-90 days): ${YELLOW}$STALE_AGING${RESET} nodes" +else + echo " Aging (30-90 days): $STALE_AGING nodes" +fi +if [ "$STALE_STALE" -gt 0 ]; then + echo " ${RED}Stale${RESET} (>90 days): ${RED}$STALE_STALE${RESET} node(s)" +else + echo " Stale (>90 days): $STALE_STALE node(s)" +fi if [ -n "$STALE_NODES" ]; then IFS=';' read -ra stale_arr <<< "$STALE_NODES" @@ -631,13 +654,21 @@ if [ -n "$STALE_NODES" ]; then [ -z "$entry" ] && continue IFS='|' read -r path days <<< "$entry" [ -z "$path" ] && continue - echo " - $path ($days days)" + echo " ${DIM}-${RESET} $path ${DIM}($days days)${RESET}" done fi echo "" -echo "COVERAGE" -echo " Documented: $COV_PCT% ($COV_COVERED/$COV_TOTAL directories)" +echo "${BOLD}COVERAGE${RESET}" +# Color the coverage percentage +if [ "$COV_PCT" -ge 80 ]; then + COV_COLOR="$GREEN" +elif [ "$COV_PCT" -ge 50 ]; then + COV_COLOR="$YELLOW" +else + COV_COLOR="$RED" +fi +echo " Documented: ${COV_COLOR}${COV_PCT}%${RESET} ($COV_COVERED/$COV_TOTAL directories)" if [ -n "$COV_GAPS" ]; then echo " Gaps:" @@ -647,17 +678,31 @@ if [ -n "$COV_GAPS" ]; then IFS='|' read -r tokens path <<< "$entry" [ -z "$tokens" ] && continue tokens_fmt=$(format_tokens "$tokens") - echo " - $path (${tokens_fmt} tokens)" + echo " ${YELLOW}-${RESET} $path ${DIM}(${tokens_fmt} tokens)${RESET}" done fi echo "" if [ "$QUICK_MODE" = false ] && [ "$CONS_TOTAL" -gt 0 ]; then - echo "CONSISTENCY" - echo " Section alignment: $CONS_PCT% ($CONS_ALIGNED/$CONS_TOTAL sibling nodes)" + echo "${BOLD}CONSISTENCY${RESET}" + if [ "$CONS_PCT" -ge 80 ]; then + CONS_COLOR="$GREEN" + elif [ "$CONS_PCT" -ge 50 ]; then + CONS_COLOR="$YELLOW" + else + CONS_COLOR="$RED" + fi + echo " Section alignment: ${CONS_COLOR}${CONS_PCT}%${RESET} ($CONS_ALIGNED/$CONS_TOTAL sibling nodes)" echo "" fi -echo "OVERALL: $OVERALL_STATUS ($ISSUE_COUNT issue(s))" +# Color the overall status +case "$OVERALL_STATUS" in + HEALTHY) STATUS_COLOR="$GREEN" ;; + NEEDS_ATTENTION) STATUS_COLOR="$YELLOW" ;; + CRITICAL) STATUS_COLOR="$RED" ;; + *) STATUS_COLOR="" ;; +esac +echo "${BOLD}OVERALL:${RESET} ${STATUS_COLOR}${OVERALL_STATUS}${RESET} ($ISSUE_COUNT issue(s))" exit $EXIT_CODE diff --git a/scripts/capture-tool-failure.sh b/scripts/capture-tool-failure.sh index 4727cd4..a853e22 100755 --- a/scripts/capture-tool-failure.sh +++ b/scripts/capture-tool-failure.sh @@ -94,6 +94,7 @@ cat > "$REPORT_FILE" << EOF **Timestamp**: $TIMESTAMP **Directory**: $TARGET_DIR **Operation**: $OPERATION +**Confidence**: low **Status**: skeleton (awaiting enrichment) ### What Went Wrong diff --git a/scripts/capture_mistake.sh b/scripts/capture_mistake.sh index a775b45..7bd0c7d 100755 --- a/scripts/capture_mistake.sh +++ b/scripts/capture_mistake.sh @@ -22,6 +22,7 @@ OPTIONS: --from-git Auto-fill from recent git activity --non-interactive Fail if prompts needed (for scripting) --agent-id ID Identifier for the reporting agent + --confidence LEVEL Confidence level: high, medium, low LEARNING TYPES: pitfall Something that went wrong / gotcha to avoid @@ -62,6 +63,7 @@ ROOT_CAUSE="" FROM_GIT=false NON_INTERACTIVE=false AGENT_ID="" +CONFIDENCE="" # Parse arguments while [[ $# -gt 0 ]]; do @@ -101,6 +103,10 @@ while [[ $# -gt 0 ]]; do AGENT_ID="$2" shift 2 ;; + --confidence) + CONFIDENCE="$2" + shift 2 + ;; -*) echo "Error: Unknown option: $1" >&2 echo " Run with --help for usage information" >&2 @@ -214,6 +220,12 @@ case "$LEARNING_TYPE" in ;; esac +# Validate confidence (default to medium for unrecognized values) +case "$CONFIDENCE" in + high|medium|low|"") ;; + *) CONFIDENCE="medium" ;; +esac + # Directory if [ -z "$TARGET_DIR" ]; then prompt TARGET_DIR "Directory where this applies" "." @@ -359,6 +371,8 @@ esac # Write report AGENT_LINE="" [[ -n "$AGENT_ID" ]] && AGENT_LINE=$'\n'"**Agent**: $AGENT_ID" +CONFIDENCE_LINE="" +[[ -n "$CONFIDENCE" ]] && CONFIDENCE_LINE=$'\n'"**Confidence**: $CONFIDENCE" cat > "$REPORT_FILE" << EOF ## Learning Report @@ -367,7 +381,7 @@ cat > "$REPORT_FILE" << EOF **Type**: $LEARNING_TYPE **Timestamp**: $TIMESTAMP **Directory**: $TARGET_DIR -**Operation**: $OPERATION${AGENT_LINE} +**Operation**: $OPERATION${AGENT_LINE}${CONFIDENCE_LINE} ### $SECTION_TITLE $WHAT_HAPPENED diff --git a/scripts/detect_state.sh b/scripts/detect_state.sh index 6b1456a..ff7bd68 100755 --- a/scripts/detect_state.sh +++ b/scripts/detect_state.sh @@ -188,5 +188,5 @@ elif [ "$HAS_INTENT_SECTION" = false ]; then echo "action: Add Intent Layer section to $ROOT_FILE" else echo "state: complete" - echo "action: Run intent-layer-maintenance skill for audits" + echo "action: Run intent-layer:maintain skill for audits" fi diff --git a/scripts/inject-learnings.sh b/scripts/inject-learnings.sh index 20edfa2..04c4fc9 100755 --- a/scripts/inject-learnings.sh +++ b/scripts/inject-learnings.sh @@ -17,6 +17,10 @@ PROJECT_ROOT="${CLAUDE_PROJECT_DIR:-.}" CONTEXT_PARTS=() STATE="unknown" +# --- Cleanup stale dedup files from PreToolUse hook --- +# Remove dedup files older than 24h to avoid accumulation in $TMPDIR. +find "${TMPDIR:-/tmp}" -maxdepth 1 -name "intent-layer-dedup-*" -type f -mmin +1440 -delete 2>/dev/null || true + # --- Check 1: Does Intent Layer exist? --- DETECT_STATE="$PLUGIN_ROOT/scripts/detect_state.sh" if [[ -x "$DETECT_STATE" ]]; then @@ -36,6 +40,20 @@ Without this, I'm navigating blind. Setup takes ~5 minutes for most projects.") fi fi +# --- Check 1b: Migration notice for v2.0 command renames --- +if [[ "$STATE" == "complete" || "$STATE" == "partial" ]]; then + CONTEXT_PARTS+=("## Intent Layer v2.0: Command names changed + +| Old | New | +|-----|-----| +| \`/intent-layer-maintenance\` | \`/intent-layer:maintain\` | +| \`/review-mistakes\` | \`/intent-layer:review\` | +| \`/intent-layer-compound\` | _(removed, auto-captured by stop hook)_ | +| \`/intent-layer-onboarding\` | \`/intent-layer\` _(router handles it)_ | +| \`/intent-layer-query\` | \`/intent-layer:query\` | +| \`/intent-layer-health\` | \`/intent-layer:health\` |") +fi + # --- Check 2: Recent learnings from accepted mistakes --- AGGREGATE_SCRIPT="$PLUGIN_ROOT/lib/aggregate_learnings.sh" if [[ -x "$AGGREGATE_SCRIPT" ]]; then diff --git a/scripts/learn.sh b/scripts/learn.sh index a4d5d0e..cd4cdc9 100755 --- a/scripts/learn.sh +++ b/scripts/learn.sh @@ -251,5 +251,5 @@ SECTION_WORDS=$(awk -v section="$TARGET_SECTION" ' if [[ "$SECTION_WORDS" -gt 300 ]]; then echo "Warning: ## $TARGET_SECTION in $COVERING_NODE has ~${SECTION_WORDS} words (budget: ~300)" >&2 - echo "Consider consolidating entries with /intent-layer-maintenance" >&2 + echo "Consider consolidating entries with /intent-layer:maintain" >&2 fi diff --git a/scripts/post-edit-check.sh b/scripts/post-edit-check.sh index b896558..e3df03f 100755 --- a/scripts/post-edit-check.sh +++ b/scripts/post-edit-check.sh @@ -108,9 +108,12 @@ fi NODE_DIR=$(dirname "$COVERING_NODE") RELATIVE_PATH="${FILE_PATH#$NODE_DIR/}" -# Output reminder (this is what Claude sees) -echo "ℹ️ Intent Layer: $RELATIVE_PATH is covered by $COVERING_NODE" -echo " Review if behavior changed: Contracts, Entry Points, Pitfalls" +# Only emit reminder if the file's basename appears in the covering node +# Case-insensitive match reduces noise for files not mentioned in AGENTS.md +if grep -qi "$FILE_NAME" "$COVERING_NODE" 2>/dev/null; then + echo "ℹ️ Intent Layer: $RELATIVE_PATH is covered by $COVERING_NODE" + echo " Review if behavior changed: Contracts, Entry Points, Pitfalls" +fi # --- New Directory Detection --- # Check if this file was written to a new directory that may need AGENTS.md @@ -163,7 +166,7 @@ if [[ ! -f "$FILE_DIR/AGENTS.md" ]] && \ parent_has_coverage "$FILE_DIR"; then echo "" echo "📁 New directory \`$DIR_NAME\` created - may need AGENTS.md coverage as it grows." - echo " Run \`/intent-layer-maintenance\` when ready to extend the hierarchy." + echo " Run \`/intent-layer:maintain\` when ready to extend the hierarchy." fi # --- Outcome Telemetry --- diff --git a/scripts/pre-edit-check.sh b/scripts/pre-edit-check.sh index a6c184e..86c99ea 100755 --- a/scripts/pre-edit-check.sh +++ b/scripts/pre-edit-check.sh @@ -50,6 +50,26 @@ fi NODE_PATH=$("$FIND_NODE" "$FILE_PATH" 2>/dev/null || true) +# --- Session deduplication --- +# Skip injection if the same node was injected <5 min ago in this session. +# Session key: CLAUDE_SESSION_ID (primary) or CLAUDE_PROJECT_DIR (fallback). +DEDUP_KEY="${CLAUDE_SESSION_ID:-${CLAUDE_PROJECT_DIR:-default}}" +# Sanitize key for filesystem use (replace non-alnum with dashes) +# Note: uses sed instead of tr — macOS tr mangles character classes under non-C locales +DEDUP_KEY=$(printf '%s' "$DEDUP_KEY" | sed 's/[^A-Za-z0-9_-]/-/g') +DEDUP_FILE="${TMPDIR:-/tmp}/intent-layer-dedup-${DEDUP_KEY}" +DEDUP_TTL=300 # 5 minutes in seconds + +if [[ -n "$NODE_PATH" && -f "$DEDUP_FILE" ]]; then + NOW=$(date +%s) + # Check if this node was injected recently + LAST_INJECT=$(awk -F'\t' -v node="$NODE_PATH" '$1 == node { print $2 }' "$DEDUP_FILE" 2>/dev/null | tail -1) + if [[ -n "$LAST_INJECT" ]] && [[ $((NOW - LAST_INJECT)) -lt $DEDUP_TTL ]]; then + # Node injected recently — skip silently + exit 0 + fi +fi + # If no covering node found, warn about uncovered directory if [[ -z "$NODE_PATH" ]]; then # Only warn for source files, not configs/docs @@ -62,7 +82,7 @@ if [[ -z "$NODE_PATH" ]]; then This directory isn't documented in the Intent Layer. Consider: - Adding an AGENTS.md if this is a key module -- Running \`/intent-layer-maintenance\` to review coverage" +- Running \`/intent-layer:maintain\` to review coverage" output_context "PreToolUse" "$CONTEXT" ;; esac @@ -172,6 +192,11 @@ fi output_context "PreToolUse" "$CONTEXT" +# Record injection in dedup file +if [[ -n "$NODE_PATH" ]]; then + printf '%s\t%s\n' "$NODE_PATH" "$(date +%s)" >> "$DEDUP_FILE" 2>/dev/null || true +fi + # Injection audit log (feedback data trail) LOG_DIR="${CLAUDE_PROJECT_DIR:-.}/.intent-layer/hooks" if [[ -d "${CLAUDE_PROJECT_DIR:-.}/.intent-layer" ]]; then diff --git a/scripts/report_learning.sh b/scripts/report_learning.sh index f7c0700..b8faf2e 100755 --- a/scripts/report_learning.sh +++ b/scripts/report_learning.sh @@ -17,6 +17,7 @@ set -euo pipefail # # Optional: # --agent-id ID Identifier for the reporting agent +# --confidence LVL Confidence level: high, medium, low # -h, --help Show this help # # Examples: @@ -38,6 +39,7 @@ LEARNING_TYPE="" TITLE="" DETAIL="" AGENT_ID="" +CONFIDENCE="" while [[ $# -gt 0 ]]; do case $1 in @@ -48,6 +50,7 @@ while [[ $# -gt 0 ]]; do --title) TITLE="$2"; shift 2 ;; --detail) DETAIL="$2"; shift 2 ;; --agent-id) AGENT_ID="$2"; shift 2 ;; + --confidence) CONFIDENCE="$2"; shift 2 ;; *) echo "Error: Unknown option: $1" >&2; exit 1 ;; esac done @@ -105,6 +108,7 @@ CAPTURE_ARGS=( ) [[ -n "$AGENT_ID" ]] && CAPTURE_ARGS+=(--agent-id "$AGENT_ID") +[[ -n "$CONFIDENCE" ]] && CAPTURE_ARGS+=(--confidence "$CONFIDENCE") # Set project dir for capture script export CLAUDE_PROJECT_DIR="$PROJECT" diff --git a/scripts/show_hierarchy.sh b/scripts/show_hierarchy.sh index 7633bfb..3b16ef0 100755 --- a/scripts/show_hierarchy.sh +++ b/scripts/show_hierarchy.sh @@ -65,6 +65,16 @@ done TARGET_PATH="${TARGET_PATH:-.}" +# Source common.sh for setup_colors +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +if [[ -f "$SCRIPT_DIR/../lib/common.sh" ]]; then + # shellcheck source=../lib/common.sh + source "$SCRIPT_DIR/../lib/common.sh" + setup_colors +else + RED=''; GREEN=''; YELLOW=''; BOLD=''; DIM=''; RESET='' +fi + # Validate path exists if [ ! -d "$TARGET_PATH" ]; then echo "❌ Error: Directory not found: $TARGET_PATH" >&2 @@ -170,7 +180,7 @@ get_node_status() { } # Output header -echo "=== Intent Layer Hierarchy ===" +echo "${BOLD}=== Intent Layer Hierarchy ===${RESET}" echo "" # Process each node @@ -202,23 +212,27 @@ for node in "${ALL_NODES[@]}"; do status=$(get_node_status "$node" "$tokens" "$age") tokens_fmt=$(format_tokens $tokens) + # Color the status indicator + case "$status" in + "✓") colored_status="${GREEN}✓${RESET}" ;; + "⚠") colored_status="${YELLOW}⚠${RESET}" ;; + "✗") colored_status="${RED}✗${RESET}" ;; + *) colored_status="$status" ;; + esac + # Output node - echo "$prefix$rel_path" + echo "${BOLD}${prefix}${rel_path}${RESET}" if [ "$QUIET" = false ]; then # Add details on next line with indentation - if [ -n "$prefix" ]; then - detail_prefix=" " - else - detail_prefix=" " - fi - echo "${detail_prefix}${tokens_fmt} tokens $status (${age}d ago)" + detail_prefix=" " + echo "${detail_prefix}${DIM}${tokens_fmt} tokens${RESET} $colored_status ${DIM}(${age}d ago)${RESET}" echo "" fi done # Footer if [ "$QUIET" = false ]; then - echo "---" - echo "Legend: ✓ valid | ⚠ warning | ✗ error" + echo "${DIM}---${RESET}" + echo "${DIM}Legend:${RESET} ${GREEN}✓${RESET} valid | ${YELLOW}⚠${RESET} warning | ${RED}✗${RESET} error" fi diff --git a/scripts/show_status.sh b/scripts/show_status.sh index e4cd6c1..8b0ee91 100755 --- a/scripts/show_status.sh +++ b/scripts/show_status.sh @@ -65,6 +65,16 @@ done TARGET_PATH="${TARGET_PATH:-.}" +# Source common.sh for setup_colors +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +if [[ -f "$SCRIPT_DIR/../lib/common.sh" ]]; then + # shellcheck source=../lib/common.sh + source "$SCRIPT_DIR/../lib/common.sh" + setup_colors +else + RED=''; GREEN=''; YELLOW=''; BOLD=''; DIM=''; RESET='' +fi + # Validate path exists if [ ! -d "$TARGET_PATH" ]; then echo "❌ Error: Directory not found: $TARGET_PATH" >&2 @@ -108,15 +118,19 @@ fi # Determine state STATE="none" STATE_EMOJI="🔴" +STATE_COLOR="$RED" if [ -z "$ROOT_FILE" ]; then STATE="none" STATE_EMOJI="🔴" + STATE_COLOR="$RED" elif [ "$HAS_INTENT_SECTION" = false ]; then STATE="partial" STATE_EMOJI="🟡" + STATE_COLOR="$YELLOW" else STATE="complete" STATE_EMOJI="🟢" + STATE_COLOR="$GREEN" fi # Find all nodes @@ -282,40 +296,58 @@ EOF fi # Output dashboard -cat << 'EOF' -╔════════════════════════════════════════╗ -║ INTENT LAYER STATUS DASHBOARD ║ -╚════════════════════════════════════════╝ - -EOF +echo "${BOLD}╔════════════════════════════════════════╗${RESET}" +echo "${BOLD}║ INTENT LAYER STATUS DASHBOARD ║${RESET}" +echo "${BOLD}╚════════════════════════════════════════╝${RESET}" +echo "" -echo "## State: $STATE_EMOJI $(echo "$STATE" | tr '[:lower:]' '[:upper:]')" +echo "${BOLD}State:${RESET} $STATE_EMOJI ${STATE_COLOR}$(echo "$STATE" | tr '[:lower:]' '[:upper:]')${RESET}" echo "" -echo "## Summary" -echo "| Metric | Value |" -echo "|--------|-------|" -echo "| Root File | ${ROOT_FILE:-none} |" -echo "| Total Nodes | ${#NODES[@]} |" -echo "| Total Tokens | $TOTAL_TOKENS_FMT |" -echo "| Errors | $TOTAL_ERRORS |" -echo "| Warnings | $TOTAL_WARNINGS |" +echo "${BOLD}Summary${RESET}" +echo " Root File: ${ROOT_FILE:-none}" +echo " Total Nodes: ${#NODES[@]}" +echo " Total Tokens: $TOTAL_TOKENS_FMT" +if [ "$TOTAL_ERRORS" -gt 0 ]; then + echo " Errors: ${RED}${TOTAL_ERRORS}${RESET}" +else + echo " Errors: ${GREEN}${TOTAL_ERRORS}${RESET}" +fi +if [ "$TOTAL_WARNINGS" -gt 0 ]; then + echo " Warnings: ${YELLOW}${TOTAL_WARNINGS}${RESET}" +else + echo " Warnings: ${TOTAL_WARNINGS}" +fi echo "" if [ ${#NODES[@]} -gt 0 ]; then - echo "## Node Health" - echo "| Node | Tokens | Budget | Status | Age |" - echo "|------|--------|--------|--------|-----|" + echo "${BOLD}Node Health${RESET}" + printf " ${DIM}%-40s %-8s %-8s %-8s %s${RESET}\n" "Node" "Tokens" "Budget" "Status" "Age" for data in ${NODE_DATA[@]+"${NODE_DATA[@]}"}; do IFS='|' read -r path tokens budget status age <<< "$data" tokens_fmt=$(format_tokens $tokens) - echo "| $path | $tokens_fmt | ${budget}% | $status | ${age}d |" + # Color the status indicator + case "$status" in + "✓") colored_status="${GREEN}✓${RESET}" ;; + "⚠") colored_status="${YELLOW}⚠${RESET}" ;; + "✗") colored_status="${RED}✗${RESET}" ;; + *) colored_status="$status" ;; + esac + # Color the budget percentage + if [ "$budget" -gt 100 ]; then + colored_budget="${RED}${budget}%${RESET}" + elif [ "$budget" -gt 75 ]; then + colored_budget="${YELLOW}${budget}%${RESET}" + else + colored_budget="${GREEN}${budget}%${RESET}" + fi + printf " %-40s %-8s %-8b %-8b %s\n" "$path" "$tokens_fmt" "$colored_budget" "$colored_status" "${DIM}${age}d${RESET}" done echo "" fi -echo "## Recommended Actions" +echo "${BOLD}Recommended Actions${RESET}" for rec in ${RECOMMENDATIONS[@]+"${RECOMMENDATIONS[@]}"}; do - echo "- $rec" + echo " - $rec" done echo "" diff --git a/scripts/show_telemetry.sh b/scripts/show_telemetry.sh index 9c9f861..6156927 100755 --- a/scripts/show_telemetry.sh +++ b/scripts/show_telemetry.sh @@ -72,6 +72,16 @@ done TARGET_PATH="${TARGET_PATH:-.}" +# Source common.sh for setup_colors +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +if [[ -f "$SCRIPT_DIR/../lib/common.sh" ]]; then + # shellcheck source=../lib/common.sh + source "$SCRIPT_DIR/../lib/common.sh" + setup_colors +else + RED=''; GREEN=''; YELLOW=''; BOLD=''; DIM=''; RESET='' +fi + if [[ ! -d "$TARGET_PATH" ]]; then echo "Error: Directory not found: $TARGET_PATH" >&2 exit 1 @@ -239,44 +249,57 @@ END { # === Output === -echo "=== Intent Layer Telemetry ===" +# Helper: color a percentage value +color_pct() { + local val=$1 + if [[ "$val" -ge 80 ]]; then + echo "${GREEN}${val}%${RESET}" + elif [[ "$val" -ge 50 ]]; then + echo "${YELLOW}${val}%${RESET}" + else + echo "${RED}${val}%${RESET}" + fi +} + +echo "${BOLD}=== Intent Layer Telemetry ===${RESET}" echo "" -echo "Period: ${FIRST_DATE:-?} to ${LAST_DATE:-?}" +echo "${DIM}Period:${RESET} ${FIRST_DATE:-?} to ${LAST_DATE:-?}" echo "Total edits: $TOTAL_EDITS" -echo "Covered edits: $COVERED_EDITS (${COVERED_PCT}%)" +echo "Covered edits: $COVERED_EDITS ($(color_pct "$COVERED_PCT"))" echo "Uncovered edits: $UNCOVERED_EDITS (${UNCOVERED_PCT}%)" -echo "Success rate: ${SUCCESS_RATE}%" +echo "Success rate: $(color_pct "$SUCCESS_RATE")" # Per-node table if [[ -s "$TMPDIR_WORK/per_node.tsv" ]]; then echo "" - echo "## Per-Node Success Rates" + echo "${BOLD}## Per-Node Success Rates${RESET}" echo "" - printf "%-40s %-8s %-10s %s\n" "Node" "Edits" "Success" "Rate" + printf " ${DIM}%-40s %-8s %-10s %s${RESET}\n" "Node" "Edits" "Success" "Rate" while IFS=$'\t' read -r node edits success rate; do - printf "%-40s %-8s %-10s %s%%\n" "$node" "$edits" "$success" "$rate" + colored_rate=$(color_pct "$rate") + printf " %-40s %-8s %-10s %b\n" "$node" "$edits" "$success" "$colored_rate" done < "$TMPDIR_WORK/per_node.tsv" fi # Coverage gaps if [[ -s "$TMPDIR_WORK/gaps.tsv" ]]; then echo "" - echo "## Coverage Gaps (files edited without AGENTS.md context)" + echo "${BOLD}## Coverage Gaps${RESET} ${DIM}(files edited without AGENTS.md context)${RESET}" echo "" - printf "%-50s %s\n" "File" "Edits" + printf " ${DIM}%-50s %s${RESET}\n" "File" "Edits" while IFS=$'\t' read -r file count; do - printf "%-50s %s\n" "$file" "$count" + printf " ${YELLOW}%-50s${RESET} %s\n" "$file" "$count" done < "$TMPDIR_WORK/gaps.tsv" fi # Trend if [[ -s "$TMPDIR_WORK/trend.tsv" ]]; then echo "" - echo "## Trend" + echo "${BOLD}## Trend${RESET}" echo "" - printf "%-14s %-12s %s\n" "Date" "Covered%" "Success%" + printf " ${DIM}%-14s %-12s %s${RESET}\n" "Date" "Covered%" "Success%" while IFS=$'\t' read -r date covered_pct success_pct; do - printf "%-14s %-12s %s\n" "$date" "$covered_pct" "$success_pct" + printf " %-14s %-12s %s\n" "$date" "$covered_pct" "$success_pct" done < "$TMPDIR_WORK/trend.tsv" fi diff --git a/scripts/stop-learning-check.sh b/scripts/stop-learning-check.sh index 4417b08..966f9ea 100755 --- a/scripts/stop-learning-check.sh +++ b/scripts/stop-learning-check.sh @@ -7,7 +7,7 @@ # Tier 2: Haiku API call with structured output as binary classifier # Tier 3: Haiku extraction call → auto-write via learn.sh or queue via report_learning.sh # -# Blocks only when queued learnings need human review. Auto-captured learnings don't block. +# Never blocks — writes summary to stderr instead. All paths exit 0. # Everything fails open on error (API down, parse failure, missing tools). set -euo pipefail @@ -120,7 +120,7 @@ Examples of should_capture: true: Examples of should_capture: false: - Normal coding session, agent wrote tests and fixed a typo -- Agent edited AGENTS.md as part of routine /intent-layer-maintenance +- Agent edited AGENTS.md as part of routine /intent-layer:maintain - Simple Q&A session with no unexpected discoveries - User asked agent to push, commit, or do routine git operations @@ -192,7 +192,7 @@ Rules: - path must be relative to project root (e.g. \"src/api/\" or \"src/server/proxy.ts\") - title must be under 50 characters - detail should be 1-3 sentences, specific enough to act on -- confidence: \"high\" if the learning is clearly stated and actionable, \"low\" if ambiguous or you're inferring +- confidence: \"high\" if clearly stated and actionable, \"medium\" if plausible but needs verification, \"low\" if ambiguous or inferred - Return empty learnings array if nothing specific enough to extract - Max 5 learnings per session" \ --arg user_msg "$USER_MESSAGE" \ @@ -216,7 +216,7 @@ Rules: title: { type: "string" }, detail: { type: "string" }, path: { type: "string" }, - confidence: { type: "string", enum: ["high", "low"] } + confidence: { type: "string", enum: ["high", "medium", "low"] } }, required: ["type", "title", "detail", "path", "confidence"], additionalProperties: false @@ -240,9 +240,9 @@ EXTRACT_RESPONSE=$(curl -s --connect-timeout 5 --max-time 30 \ EXTRACT_EXIT=$? set -e -# Extraction failed — fall back to blocking with manual instruction +# Extraction failed — log to stderr and exit cleanly if [[ $EXTRACT_EXIT -ne 0 || -z "$EXTRACT_RESPONSE" ]]; then - output_block "Session contains learnings worth capturing. Run /intent-layer-compound to document them." + echo "Intent Layer: learnings detected but extraction failed. Run /intent-layer:review to capture manually." >&2 exit 0 fi @@ -250,9 +250,9 @@ fi LEARNINGS_JSON=$(echo "$EXTRACT_RESPONSE" | jq -r '.content[0].text' 2>/dev/null) LEARNING_COUNT=$(echo "$LEARNINGS_JSON" | jq -r '.learnings | length' 2>/dev/null) -# No learnings extracted or parse failure — fall back +# No learnings extracted or parse failure — log to stderr and exit cleanly if [[ -z "$LEARNING_COUNT" || "$LEARNING_COUNT" == "null" || "$LEARNING_COUNT" -eq 0 ]] 2>/dev/null; then - output_block "Session contains learnings worth capturing. Run /intent-layer-compound to document them." + echo "Intent Layer: learnings detected but none extracted. Run /intent-layer:review to capture manually." >&2 exit 0 fi @@ -273,6 +273,12 @@ for i in $(seq 0 $((LEARNING_COUNT - 1))); do continue fi + # Normalize unrecognized confidence to medium + case "$L_CONFIDENCE" in + high|medium|low) ;; + *) L_CONFIDENCE="medium" ;; + esac + if [[ "$L_CONFIDENCE" == "high" ]]; then # Direct-write via learn.sh (has dedup gate) set +e @@ -292,45 +298,43 @@ for i in $(seq 0 $((LEARNING_COUNT - 1))); do # Duplicate — already known, skip silently CAPTURE_SUMMARY+=" = [$L_TYPE] $L_TITLE (already documented)"$'\n' else - # learn.sh failed (no covering node, etc.) — queue instead + # learn.sh failed (no covering node, etc.) — queue with confidence set +e "$PLUGIN_ROOT/scripts/report_learning.sh" \ --project "$PROJECT_ROOT" \ --path "$L_PATH" \ --type "$L_TYPE" \ --title "$L_TITLE" \ - --detail "$L_DETAIL" 2>/dev/null + --detail "$L_DETAIL" \ + --confidence "$L_CONFIDENCE" 2>/dev/null set -e QUEUED=$((QUEUED + 1)) CAPTURE_SUMMARY+=" ? [$L_TYPE] $L_TITLE (queued — no covering node)"$'\n' fi else - # Low confidence — queue for human triage + # Medium/low confidence — queue for human triage set +e "$PLUGIN_ROOT/scripts/report_learning.sh" \ --project "$PROJECT_ROOT" \ --path "$L_PATH" \ --type "$L_TYPE" \ --title "$L_TITLE" \ - --detail "$L_DETAIL" 2>/dev/null + --detail "$L_DETAIL" \ + --confidence "$L_CONFIDENCE" 2>/dev/null set -e QUEUED=$((QUEUED + 1)) - CAPTURE_SUMMARY+=" ? [$L_TYPE] $L_TITLE (queued — needs review)"$'\n' + CAPTURE_SUMMARY+=" ? [$L_TYPE] $L_TITLE (queued — $L_CONFIDENCE confidence)"$'\n' fi done -# Decide whether to block -if [[ $QUEUED -gt 0 ]]; then - # Some learnings need human review - BLOCK_MSG="Auto-captured $AUTO_CAPTURED learning(s), queued $QUEUED for review. -${CAPTURE_SUMMARY} -Run /review-mistakes to triage queued items." - output_block "$BLOCK_MSG" -elif [[ $AUTO_CAPTURED -gt 0 ]]; then - # Everything was auto-captured — don't block, just log - echo "Intent Layer: auto-captured $AUTO_CAPTURED learning(s) to AGENTS.md" >&2 - exit 0 -else - # Nothing was written (all duplicates or skipped) — don't block - exit 0 +# Stderr summary — never block +if [[ $AUTO_CAPTURED -gt 0 || $QUEUED -gt 0 ]]; then + echo "Intent Layer: captured $((AUTO_CAPTURED + QUEUED)) learning(s) ($AUTO_CAPTURED auto-integrated, $QUEUED queued for review)" >&2 + if [[ -n "$CAPTURE_SUMMARY" ]]; then + echo "$CAPTURE_SUMMARY" >&2 + fi + if [[ $QUEUED -gt 0 ]]; then + echo "Run /intent-layer:review to triage." >&2 + fi fi +exit 0 diff --git a/skills/AGENTS.md b/skills/AGENTS.md index b489b29..93eff29 100644 --- a/skills/AGENTS.md +++ b/skills/AGENTS.md @@ -1,6 +1,6 @@ # skills/ -> 7 top-level skills + 3 sub-skills. Each is a SKILL.md with YAML frontmatter that becomes a `/slash-command`. +> 5 top-level skills + 3 sub-skills. Each is a SKILL.md with YAML frontmatter that becomes a `/slash-command`. ## Purpose @@ -8,15 +8,13 @@ Slash-command workflows that drive the Intent Layer lifecycle. Each skill is a d ### Skill map -| Skill | Trigger | What it does | +| Skill | Command | What it does | |-------|---------|-------------| -| `intent-layer` | `/intent-layer` | Initial setup (state = none/partial). Runs detect, measure, mine, create, validate. | -| `intent-layer-maintenance` | `/intent-layer-maintenance` | Quarterly audits, post-incident updates (state = complete) | -| `intent-layer-query` | `/intent-layer-query` | Answer codebase questions using existing nodes | -| `intent-layer-onboarding` | `/intent-layer-onboarding` | Orient new developers via hierarchy walkthrough | -| `intent-layer-compound` | `/intent-layer-compound` | End-of-session learning capture: conversation scan, structured prompts, direct integration | -| `intent-layer-health` | `/intent-layer-health` | Quick validation + staleness + coverage check | -| `review-mistakes` | `/review-mistakes` | Interactive triage of pending mistake reports | +| `intent-layer` | `/intent-layer` | Smart router: detects state, presents relevant action. Setup (none/partial), review, maintain. | +| `intent-layer-maintain` | `/intent-layer:maintain` | Quarterly audits, post-incident updates (state = complete) | +| `intent-layer-query` | `/intent-layer:query` | Answer codebase questions using existing nodes | +| `intent-layer-health` | `/intent-layer:health` | Quick validation + staleness + coverage check | +| `intent-layer-review` | `/intent-layer:review` | Batch triage of pending learning reports (multiSelect) | ### Sub-skills (nested under `intent-layer/`) @@ -26,6 +24,14 @@ Slash-command workflows that drive the Intent Layer lifecycle. Each skill is a d | `pr-review-mining` | Creating nodes for dirs with merged PRs | `mine_pr_reviews.sh` | | `pr-review` | Reviewing PRs touching Intent Layer nodes | `review_pr.sh` | +### Workflow references (under `intent-layer/workflows/`) + +| File | Contents | +|------|----------| +| `setup.md` | Setup flow quick reference (extracted from main SKILL.md) | +| `maintain.md` | Maintenance flow quick reference (extracted from maintain skill) | +| `onboard.md` | Onboarding flow quick reference (extracted from former onboarding skill) | + ## Entry Points | Task | Start Here | @@ -33,14 +39,14 @@ Slash-command workflows that drive the Intent Layer lifecycle. Each skill is a d | Create a new skill | Copy any existing skill dir, edit `SKILL.md` frontmatter | | Understand a skill's behavior | Read its `SKILL.md` top to bottom (they're the full spec) | | Add a sub-skill to `intent-layer` | Create dir under `intent-layer/`, add `SKILL.md` | -| Find which skill handles a state | Check the state routing: none/partial -> `intent-layer`, complete -> `intent-layer-maintenance` | +| Find which skill handles a state | Check the state routing: none/partial -> `intent-layer`, complete -> `intent-layer:maintain` | ## Contracts - Every skill dir must contain exactly one `SKILL.md` with YAML frontmatter (`name`, `description`). Source: `.claude-plugin/plugin.json` auto-discovers skills. - Skills reference scripts via `${CLAUDE_PLUGIN_ROOT}/scripts/` -- never hardcode paths. - Sub-skills live as subdirectories of a parent skill and get invoked by the parent's SKILL.md logic, not directly by users. -- `intent-layer-compound` writes via `learn.sh` (direct, dedup-gated). Never via `report_learning.sh` (that's for multi-agent swarms). +- Skill names use colon-namespaced format: `intent-layer:maintain`, `intent-layer:review`, etc. The root `intent-layer` skill has no suffix. ## Patterns @@ -49,14 +55,18 @@ Slash-command workflows that drive the Intent Layer lifecycle. Each skill is a d ``` detect_state.sh output -> skill selection none/partial -> /intent-layer (setup) - complete -> /intent-layer-maintenance (audit) + complete -> /intent-layer:maintain (audit) ``` All skills check state first and redirect if wrong. -### Prompts directory +### Learning review pipeline -`intent-layer-compound/prompts/scan.md` is a reusable prompt template. Other skills inline their prompts directly in SKILL.md. No standard yet for when to extract prompts. +``` +Stop hook (auto-capture) → .intent-layer/mistakes/pending/ → /intent-layer:review (batch triage) +``` + +High-confidence learnings auto-integrate via `learn.sh`. Everything else queues for `/intent-layer:review`. ## Pitfalls @@ -67,7 +77,3 @@ Users can't run `/git-history` or `/pr-review` directly. They're only triggered ### SKILL.md is both docs and executable spec The SKILL.md content is injected into Claude's context when a skill runs. Everything in it is instructions to Claude, not documentation for humans. Writing "this skill does X" in SKILL.md means Claude reads it as instructions to do X. Be precise. - -### intent-layer-compound uses conversation analysis - -Layer 1 (AI scan) searches the current conversation for correction signals ("actually...", "no, you should..."). This only works when run in the same session. Running it in a fresh session finds nothing. diff --git a/skills/intent-layer-compound/SKILL.md b/skills/intent-layer-compound/SKILL.md deleted file mode 100644 index 791fdb1..0000000 --- a/skills/intent-layer-compound/SKILL.md +++ /dev/null @@ -1,227 +0,0 @@ ---- -name: intent-layer-compound -description: > - End-of-cycle learning capture and triage. Run after completing a feature, - fixing a bug, or finishing any significant work. Reviews pending learnings, - analyzes conversation for undocumented insights, and integrates into the - Intent Layer with appropriate scope (global workflow vs local code). -argument-hint: "[/path/to/project]" ---- - -# Compound Learning Skill - -> **TL;DR**: Capture and triage learnings at the end of a work session. Runs conversation analysis, surfaces candidates, and integrates with proper scope routing. - ---- - -## When to Use - -Run `/intent-layer-compound` after: -- Completing a feature or bug fix -- Finishing any significant work session -- Discovering non-obvious behaviors or gotchas -- When you want to capture learnings before ending the session - ---- - -## Three-Layer Workflow - -### Layer 1: AI Conversation Scan - -Before prompting for manual capture, analyze the conversation for learning signals. - -**Scan for these patterns:** - -| Pattern | Example Phrases | Learning Type | -|---------|-----------------|---------------| -| User corrections | "actually...", "no, you should...", "that's wrong" | pitfall | -| Discoveries | "interesting...", "I didn't know...", "turns out..." | insight | -| Better approaches | "a better way is...", "instead, try..." | pattern | -| Unexpected behaviors | "but it returned...", "weird, it..." | pitfall | -| Missing checks | "should have verified...", "forgot to check..." | check | - -**For each candidate found:** -1. Extract the relevant conversation snippet -2. Identify the learning type -3. Determine affected directory (if identifiable from context) -4. Present to user for confirmation - -**Example output:** -``` -Found 3 potential learnings in this conversation: - -1. [pitfall] User corrected assumption about API response format - Context: "Actually, the API returns a list when there are multiple results..." - Affected: src/api/ - -2. [insight] Discovery about caching behavior - Context: "Turns out the cache invalidates on every deploy..." - Affected: (workflow-level) - -3. [check] Missing verification identified - Context: "Should have verified the schema before migration..." - Affected: src/db/ -``` - -### Layer 2: Structured Prompts - -After AI-surfaced candidates are reviewed, prompt for additional learnings: - -**Prompt sequence:** -1. "Were there any corrections you made to my assumptions?" -2. "Did we discover any unexpected behaviors?" -3. "Are there any better approaches we figured out?" -4. "Any checks that would have helped if done earlier?" - -For each "yes" response: -- Use the scan prompt from `prompts/scan.md` to extract details -- Capture via the existing `capture_mistake.sh` with pre-filled fields -- Assign appropriate learning type - -### Layer 3: Direct Integration - -After candidates are confirmed, integrate each one directly using `learn.sh`: - -For each confirmed candidate: -```bash -${CLAUDE_PLUGIN_ROOT}/scripts/learn.sh \ - --project [PROJECT_PATH] \ - --path [AFFECTED_PATH] \ - --type [pitfall|check|pattern|insight] \ - --title "[TITLE]" \ - --detail "[DETAIL]" -``` - -`learn.sh` handles deduplication automatically — if the learning already exists (≥60% word overlap), it exits with code 2 and reports "duplicate skipped". - -**Report outcomes to the user:** -- Exit 0: "✓ Integrated into [AGENTS.md path]" -- Exit 2: "⊘ Duplicate skipped (already documented)" -- Exit 1: "✗ Error: [message]" - -**Show summary** of what was integrated and where when all candidates are processed. - ---- - -## Resources - -### Scripts Used - -| Script | Purpose | -|--------|---------| -| `learn.sh` | Direct-write learning to AGENTS.md (dedup-gated) | -| `capture_mistake.sh` | Create learning report for pending queue (swarm use) | - -### Prompts - -| Prompt | Purpose | -|--------|---------| -| `prompts/scan.md` | Conversation analysis for learning signals | - ---- - -## Quick Start - -``` -/intent-layer-compound -``` - -Or with explicit project path: -``` -/intent-layer-compound /path/to/project -``` - ---- - -## Example Session - -``` -$ /intent-layer-compound - -=== Intent Layer Compound Learning === - -[Layer 1: Conversation Scan] -Analyzing conversation for potential learnings... - -Found 2 potential learnings: - -1. [pitfall] API response format varies - "Actually, the API can return either a dict or a list..." - Path: src/api/ - - Is this worth documenting? [y/n/edit]: y - -2. [insight] Deploy triggers cache invalidation - "Turns out the cache clears on every deploy..." - Path: (workflow-level) - - Is this worth documenting? [y/n/edit]: y - -[Layer 2: Additional Prompts] -Any other corrections you made to my assumptions? [y/n]: n -Any unexpected behaviors discovered? [y/n]: n -Any better approaches figured out? [y/n]: n - -[Layer 3: Direct Integration] -Integrating 2 confirmed learnings... - -1. ✓ pitfall added to ## Pitfalls in src/api/AGENTS.md -2. ✓ insight added to ## Context in CLAUDE.md - -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Summary -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - Integrated: 2 - Duplicates: 0 - Errors: 0 - -Compound learning complete! -``` - ---- - -## Scope Routing - -The compound skill routes learnings to the appropriate location: - -``` -Learning captured - │ - └─── Is it workflow-level? (insight, cross-cutting) - │ - ┌────────┴────────┐ - │ │ - Yes No - │ │ - ▼ ▼ - Root CLAUDE.md Covering AGENTS.md - (global scope) (local scope) -``` - -### Global Scope (Root CLAUDE.md) - -Use for: -- Workflow insights (build process, deployment, testing) -- Cross-cutting patterns that apply everywhere -- Project-wide conventions and decisions -- Learnings that don't belong to any specific directory - -### Local Scope (Covering AGENTS.md) - -Use for: -- Code-specific pitfalls -- API behavior quirks -- Module-specific patterns -- Checks for particular operations - ---- - -## Integration with Hooks - -The compound skill works with the existing learning loop hooks: - -- **PostToolUseFailure**: Auto-captures failures → pending/ -- **Stop hook**: Prompts for learnings if configured -- **/intent-layer-compound**: End-of-session synthesis - -Run `/intent-layer-compound` to process any auto-captured learnings alongside manual capture. diff --git a/skills/intent-layer-compound/prompts/scan.md b/skills/intent-layer-compound/prompts/scan.md deleted file mode 100644 index deae116..0000000 --- a/skills/intent-layer-compound/prompts/scan.md +++ /dev/null @@ -1,152 +0,0 @@ -# Conversation Analysis Prompt - -Analyze the conversation for potential learnings that should be documented in the Intent Layer. - -## What to Look For - -### 1. User Corrections -Where the user corrected an assumption or approach. - -**Signal phrases:** -- "actually..." -- "no, you should..." -- "that's wrong" -- "not quite..." -- "it's the other way around" -- "you need to do X first" - -**Learning type:** Usually `pitfall` (wrong assumption) or `check` (missing verification) - -### 2. Discoveries -Unexpected behaviors, edge cases, or gotchas found during the work. - -**Signal phrases:** -- "interesting..." -- "I didn't know..." -- "turns out..." -- "surprisingly..." -- "that's weird..." -- "but it actually..." - -**Learning type:** Usually `pitfall` (gotcha) or `insight` (useful discovery) - -### 3. Better Approaches -Improved patterns or methods discovered. - -**Signal phrases:** -- "a better way is..." -- "instead, try..." -- "the proper way..." -- "you should use X instead of Y" -- "the pattern we use is..." - -**Learning type:** Usually `pattern` (preferred approach) - -### 4. Missing Checks -Verification or validation that would have helped earlier. - -**Signal phrases:** -- "should have checked..." -- "forgot to verify..." -- "need to make sure..." -- "always check X before Y" -- "this would have caught it" - -**Learning type:** `check` (pre-action verification) - -## Output Format - -For each potential learning, extract structured fields that can be passed directly to `learn.sh`: - -```markdown -## Candidate [N] - -**Type**: pitfall | check | pattern | insight -**Title**: [One-line title for ### header — concise, specific] -**Detail**: [Body content for the entry — the actual learning] -**Path**: [Directory path, e.g., src/api/ — or project root for workflow-level] -**Confidence**: high | medium | low -**Quote**: "[The relevant conversation snippet]" -``` - -The **Title**, **Detail**, **Path**, and **Type** fields map directly to `learn.sh` arguments: -```bash -learn.sh --project --path --type --title "" --detail "<Detail>" -``` - -## Confidence Levels - -- **High**: User explicitly stated a correction or learning -- **Medium**: Clear signal phrase with actionable content -- **Low**: Implicit learning, may need clarification - -## Examples - -### Example 1: User Correction (High Confidence) - -Conversation: -> User: "Actually, the API can return either a dict or a list depending on the query type. You need to check the type before calling .get()." - -Extracted: -```markdown -## Candidate 1 - -**Type**: pitfall -**Title**: API response format varies by query type -**Detail**: API can return either a dict or a list depending on query type. Check isinstance() before calling .get(). -**Path**: src/api/ -**Confidence**: high -**Quote**: "Actually, the API can return either a dict or a list depending on the query type." -``` - -### Example 2: Discovery (Medium Confidence) - -Conversation: -> User: "Turns out the cache invalidates automatically on every deploy. That's why the first request after deploy is slow." - -Extracted: -```markdown -## Candidate 2 - -**Type**: insight -**Title**: Cache invalidates on every deploy -**Detail**: Cache invalidates automatically on deploy, causing slow first requests post-deploy. -**Path**: . -**Confidence**: medium -**Quote**: "Turns out the cache invalidates automatically on every deploy." -``` - -### Example 3: Missing Check (High Confidence) - -Conversation: -> User: "We should have verified the schema exists before running the migration. Always check with `hasattr(db, 'schema_version')` first." - -Extracted: -```markdown -## Candidate 3 - -**Type**: check -**Title**: Verify schema version before migration -**Detail**: Always check hasattr(db, 'schema_version') exists before running migration to avoid data loss. -**Path**: src/db/ -**Confidence**: high -**Quote**: "We should have verified the schema exists before running the migration." -``` - -## What NOT to Extract - -Skip these as they're not learnings: - -- General acknowledgments ("Got it", "Okay") -- Standard programming knowledge -- Things already documented in AGENTS.md -- Temporary workarounds being removed -- User preferences that aren't universal - -## Processing Order - -1. Scan entire conversation chronologically -2. Extract all candidates -3. Deduplicate (same learning mentioned multiple times) -4. Rank by confidence (high first) -5. Present to user for confirmation diff --git a/skills/intent-layer-health/SKILL.md b/skills/intent-layer-health/SKILL.md index 0447f1a..b51128a 100644 --- a/skills/intent-layer-health/SKILL.md +++ b/skills/intent-layer-health/SKILL.md @@ -1,5 +1,5 @@ --- -name: intent-layer-health +name: intent-layer:health description: Quick health check for Intent Layer - validates nodes, checks staleness, reports coverage gaps argument-hint: "[/path/to/project] [--full]" --- @@ -83,7 +83,7 @@ ${CLAUDE_PLUGIN_ROOT}/scripts/audit_intent_layer.sh [path] - **80%+**: Good coverage - **60-80%**: Consider adding nodes for uncovered areas -- **<60%**: Significant gaps - run `/intent-layer-maintenance` +- **<60%**: Significant gaps - run `/intent-layer:maintain` --- @@ -102,7 +102,7 @@ Present results to user in this format: - Coverage: 85% (3 directories uncovered) ### Recommended Actions -1. Run `/intent-layer-maintenance` to address stale nodes +1. Run `/intent-layer:maintain` to address stale nodes 2. Consider adding AGENTS.md to: src/utils/, src/migrations/ Ready to proceed with current work? The warnings are informational. @@ -122,7 +122,7 @@ Intent Layer is healthy. Good to proceed with current work. ```markdown ### Recommended Actions -1. [If stale nodes] Run `/intent-layer-maintenance` to update stale nodes +1. [If stale nodes] Run `/intent-layer:maintain` to update stale nodes 2. [If low coverage] Consider adding AGENTS.md to: [list uncovered directories] 3. [If validation warnings] Review warnings: [list] @@ -135,7 +135,7 @@ These are informational - you can proceed with current work. ### Immediate Actions Required 1. [If validation failures] Fix these nodes before proceeding: - [node path]: [issue description] -2. [If >50% stale] Most nodes are outdated - run `/intent-layer-maintenance` +2. [If >50% stale] Most nodes are outdated - run `/intent-layer:maintain` Recommend addressing these issues before starting new work. ``` @@ -168,7 +168,7 @@ Exit codes enable CI pass/fail: | Skill | Use When | |-------|----------| -| `/intent-layer-maintenance` | Status is NEEDS_ATTENTION or CRITICAL | +| `/intent-layer:maintain` | Status is NEEDS_ATTENTION or CRITICAL | | `/intent-layer` | No Intent Layer exists (state = none/partial) | | `/intent-layer-query` | Need to query Intent Layer for information | diff --git a/skills/intent-layer-maintenance/SKILL.md b/skills/intent-layer-maintain/SKILL.md similarity index 99% rename from skills/intent-layer-maintenance/SKILL.md rename to skills/intent-layer-maintain/SKILL.md index 06877ec..1b794a9 100644 --- a/skills/intent-layer-maintenance/SKILL.md +++ b/skills/intent-layer-maintain/SKILL.md @@ -1,5 +1,5 @@ --- -name: intent-layer-maintenance +name: intent-layer:maintain description: > Use when maintaining an existing Intent Layer, during quarterly reviews, after significant code changes, when something confused you, or when diff --git a/skills/intent-layer-onboarding/SKILL.md b/skills/intent-layer-onboarding/SKILL.md deleted file mode 100644 index 79a3826..0000000 --- a/skills/intent-layer-onboarding/SKILL.md +++ /dev/null @@ -1,563 +0,0 @@ ---- -name: intent-layer-onboarding -description: > - Get oriented in an unfamiliar codebase using its Intent Layer. - Use when joining a new project, exploring a codebase for the first time, - or helping someone understand "where do I start?" questions. -argument-hint: "[/path/to/project] [--role <role>] [--task <first-task>]" ---- - -# Intent Layer Onboarding - -Use an existing Intent Layer to quickly orient yourself (or a new team member) in a codebase. - -## Prerequisites - -- Project must have Intent Layer state = `complete` -- Run `intent-layer` skill first if state is `none` or `partial` - -## Quick Start - -```bash -# Check Intent Layer exists -${CLAUDE_PLUGIN_ROOT}/scripts/detect_state.sh /path/to/project - -# Generate orientation overview -scripts/generate_orientation.sh /path/to/project - -# View hierarchy -${CLAUDE_PLUGIN_ROOT}/scripts/show_hierarchy.sh /path/to/project -``` - ---- - -## The 15-Minute Orientation - -Get productive in a new codebase in 15 minutes using this workflow. - -### Step 1: Read the Root (2 min) - -Read the root CLAUDE.md or AGENTS.md completely. Focus on: - -- **TL;DR** - One sentence project purpose -- **Subsystem Boundaries** - Major areas and owners -- **Contracts** - Global rules that apply everywhere -- **Pitfalls** - Surprises that bite newcomers - -```bash -# Find and display root node -cat /path/to/project/CLAUDE.md || cat /path/to/project/AGENTS.md -``` - -### Step 2: Map the Hierarchy (2 min) - -Visualize the full Intent Layer structure: - -```bash -${CLAUDE_PLUGIN_ROOT}/scripts/show_hierarchy.sh /path/to/project -``` - -Note: -- How many child nodes exist -- Which areas have the most documentation (complexity signals) -- Depth of hierarchy (shallow = simple, deep = complex) - -### Step 3: Identify Your Entry Point (3 min) - -Based on your role or first task, find where to start: - -| If your role is... | Start with... | -|-------------------|---------------| -| Frontend engineer | UI/components AGENTS.md | -| Backend engineer | API/services AGENTS.md | -| DevOps/Platform | Infrastructure AGENTS.md | -| Full-stack | Root node + busiest subsystem | - -| If your first task is... | Find... | -|-------------------------|---------| -| Bug fix in area X | AGENTS.md closest to X | -| New feature | Entry Points in relevant subsystem | -| Understanding flow | Root → follow data path | - -### Step 4: Deep-Read Your Area (5 min) - -For your identified entry point: - -1. Read the specific AGENTS.md completely -2. Note the **Entry Points** - these are your starting files -3. Note the **Contracts** - rules you must follow -4. Note the **Pitfalls** - traps to avoid - -### Step 5: Verify Understanding (3 min) - -Test your mental model: - -1. Can you explain the project in one sentence? -2. Do you know where your first change goes? -3. Do you know what rules apply to that area? -4. Do you know what NOT to do? - -If any answer is "no", re-read the relevant node. - ---- - -## Role-Based Onboarding - -### For AI Agents - -When an AI agent needs to understand a new codebase: - -**Minimum context load:** -1. Root node (always) -2. Node for target area (if known) -3. Ancestors of target (for inherited constraints) - -**Query pattern:** -``` -"I need to [task] in [area]. What should I know?" -``` - -**Response pattern:** -```markdown -## Context for [task] - -### Relevant Node -`path/to/AGENTS.md` - -### Key Constraints -- [From local node] -- [Inherited from ancestors] - -### Entry Point -Start at: `path/to/file.ts` - -### Watch Out For -- [Pitfall 1] -- [Pitfall 2] -``` - -### For New Engineers - -When a human is joining the team: - -**Day 1 Goals:** -1. Understand project purpose (root TL;DR) -2. Know major subsystems (root Subsystem Boundaries) -3. Know global rules (root Contracts) -4. Know what surprises exist (root Pitfalls) - -**Week 1 Goals:** -1. Deep-read your team's AGENTS.md files -2. Understand your area's specific contracts -3. Successfully complete one small task -4. Know where to ask questions - -**Onboarding Checklist:** -```markdown -## Onboarding Checklist: [Name] - -### Day 1 -- [ ] Read root CLAUDE.md/AGENTS.md -- [ ] Run show_hierarchy.sh to see structure -- [ ] Identify which subsystem I'll work in -- [ ] Read my subsystem's AGENTS.md - -### Week 1 -- [ ] Complete first small task -- [ ] Verify I followed all contracts -- [ ] Note any confusion for Intent Layer feedback -- [ ] Ask about anything not documented -``` - -### For Code Reviewers - -When reviewing code in an unfamiliar area: - -1. Find AGENTS.md for the changed files -2. Check Contracts section - are they followed? -3. Check Pitfalls section - are they avoided? -4. Check Anti-patterns section - none introduced? - ---- - -## Task-Based Onboarding - -### "I need to fix a bug in X" - -**Workflow:** -1. Find AGENTS.md nearest to X -2. Read Pitfalls (often explains the bug) -3. Read Contracts (constraints on the fix) -4. Find Entry Point for debugging - -**Output:** -```markdown -## Bug Fix Context: [area] - -**Relevant Node:** `path/to/AGENTS.md` - -**Common Pitfalls (check these first):** -- [Pitfall that might explain bug] - -**Fix Constraints:** -- [Rules the fix must follow] - -**Start Debugging At:** -- `path/to/entry/file.ts` -``` - -### "I need to add a feature to Y" - -**Workflow:** -1. Find AGENTS.md for Y -2. Check if feature is in scope (vs out of scope) -3. Read Entry Points for "add new..." -4. Read Contracts for implementation rules -5. Check parent nodes for inherited constraints - -**Output:** -```markdown -## Feature Context: [feature] in [area] - -**In Scope:** Yes/No (from AGENTS.md) - -**Entry Point:** -- Start at: `path/to/file.ts` -- Pattern to follow: [from Entry Points] - -**Constraints:** -- [Local rules] -- [Inherited rules] - -**Related Areas:** -- [Siblings that might be affected] -``` - -### "I need to understand how Z works" - -**Workflow:** -1. Find AGENTS.md that owns Z -2. Read TL;DR for high-level understanding -3. Read Architecture Decisions for rationale -4. Follow Entry Points to key files -5. Read ancestors for broader context - -**Output:** -```markdown -## Understanding: [Z] - -**Owner:** `path/to/AGENTS.md` - -**TL;DR:** -> [From node] - -**Why It's Designed This Way:** -- [From Architecture Decisions] - -**Key Files to Read:** -1. `file1.ts` - [purpose] -2. `file2.ts` - [purpose] - -**Broader Context:** -- [From parent nodes] -``` - ---- - -## Generating Orientation Documents - -For teams that want a static onboarding doc: - -### Quick Overview - -```bash -scripts/generate_orientation.sh /path/to/project --format overview -``` - -Produces: -- Project summary -- Subsystem map -- Global rules -- Common tasks entry points - -### Full Onboarding Guide - -```bash -scripts/generate_orientation.sh /path/to/project --format full -``` - -Produces: -- Everything in overview -- Per-subsystem deep dives -- Role-based entry points -- First-week checklist - -### Team-Specific - -```bash -scripts/generate_orientation.sh /path/to/project --role backend -``` - -Produces: -- Filtered view for backend engineers -- Relevant subsystems only -- Backend-specific entry points - ---- - -## Interactive Onboarding Session - -For a guided, interactive orientation: - -### Step 1: Gather Context - -Ask the newcomer: -1. What's your role? (frontend/backend/fullstack/devops/other) -2. What's your first task? (if known) -3. What's your experience level? (junior/mid/senior) - -### Step 2: Generate Personalized Path - -Based on answers, create a reading list: - -**Junior + No specific task:** -```markdown -## Your Onboarding Path - -1. **Start Here:** CLAUDE.md (root) - 10 min read -2. **Then:** [area matching role]/AGENTS.md - 5 min read -3. **Exercise:** Find where [simple task] would be done -4. **Verify:** Explain the project back to me -``` - -**Senior + Specific task:** -```markdown -## Your Onboarding Path - -1. **Quick Scan:** CLAUDE.md TL;DR + Subsystems - 2 min -2. **Deep Read:** [task area]/AGENTS.md - 5 min -3. **Context:** Walk ancestors for inherited rules - 3 min -4. **Start:** [Entry point for task] -``` - -### Step 3: Verify Understanding - -After they complete the path, ask: -1. "What does this project do in one sentence?" -2. "Where would you make your first change?" -3. "What rules must you follow there?" -4. "What mistakes should you avoid?" - -If answers are weak, point them to specific sections. - -### Step 4: Capture Gaps - -If they found the Intent Layer confusing or incomplete: - -```markdown -### Intent Layer Feedback - -| Type | Location | Finding | -|------|----------|---------| -| Unclear | `src/api/AGENTS.md` | Entry Points don't explain X | -| Missing | `CLAUDE.md` | No mention of Y subsystem | -``` - -Feed this back via `intent-layer-maintenance` skill. - ---- - -## Common Questions - -### "Where do I start?" - -1. Run `show_hierarchy.sh` to see structure -2. Read root node for project overview -3. Identify your area from Subsystem Boundaries -4. Read that area's AGENTS.md -5. Follow its Entry Points - -### "What can I safely change?" - -1. Find AGENTS.md for the area -2. Check **Contracts** - these are invariants -3. Check **Anti-patterns** - don't introduce these -4. Anything not constrained is fair game - -### "Who owns this code?" - -1. Find nearest AGENTS.md (walk up if needed) -2. Check TL;DR for ownership statement -3. Check Subsystem Boundaries in parent for team info - -### "Why is it done this way?" - -1. Find AGENTS.md for the area -2. Check **Architecture Decisions** section -3. Follow any ADR links -4. If not documented, flag as feedback - ---- - -## Parallel Onboarding (Teams & Multiple Roles) - -For onboarding multiple people or generating comprehensive multi-role documentation, use parallel subagents. - -### When to Use Parallel Onboarding - -| Scenario | Approach | -|----------|----------| -| Single person, known role | Sequential (standard 15-min workflow) | -| Single person, exploring roles | Parallel role summaries | -| Multiple new team members | Parallel per-person paths | -| Comprehensive onboarding docs | Parallel section generation | - -### Parallel Role Summaries - -Generate role-specific orientations simultaneously: - -``` -Task 1 (Explore): "Generate frontend engineer orientation from Intent Layer. - Focus on: UI components, state management, styling patterns. - Return: relevant nodes, key contracts, entry points, pitfalls" - -Task 2 (Explore): "Generate backend engineer orientation from Intent Layer. - Focus on: API layer, database, services, integrations. - Return: relevant nodes, key contracts, entry points, pitfalls" - -Task 3 (Explore): "Generate DevOps/platform orientation from Intent Layer. - Focus on: infrastructure, CI/CD, deployment, monitoring. - Return: relevant nodes, key contracts, entry points, pitfalls" -``` - -**Output**: Three role-specific onboarding guides generated in parallel. - -### Parallel Comprehensive Documentation - -Generate full onboarding documentation in parallel sections: - -``` -Task 1 (Explore): "Extract project overview from Intent Layer root. - Return: TL;DR, architecture overview, subsystem map" - -Task 2 (Explore): "Extract all global contracts and pitfalls from Intent Layer. - Return: merged constraints list, common mistakes to avoid" - -Task 3 (Explore): "Extract all entry points across Intent Layer nodes. - Return: task → starting point mapping for common tasks" - -Task 4 (Explore): "Identify complexity hotspots from Intent Layer. - Return: areas with most contracts/pitfalls (need careful reading)" -``` - -**Synthesis**: Combine into comprehensive onboarding document. - -### Parallel Task-Context Generation - -When newcomer has multiple potential first tasks: - -``` -Task 1 (Explore): "Generate context for 'fix login bug' task. - Find: relevant node, constraints, pitfalls, entry point" - -Task 2 (Explore): "Generate context for 'add new API endpoint' task. - Find: relevant node, constraints, pitfalls, entry point" - -Task 3 (Explore): "Generate context for 'update dashboard component' task. - Find: relevant node, constraints, pitfalls, entry point" -``` - -**Output**: Three task-context summaries, let newcomer pick their starting point. - -### Parallel Codebase Exploration - -For AI agents needing to understand unfamiliar codebase quickly: - -``` -Task 1 (Explore): "Read CLAUDE.md root node. Extract: purpose, subsystems, - global constraints, and identify which child nodes exist" - -Task 2 (Explore): "For each child AGENTS.md, extract: ownership scope, - key contracts, main pitfalls. Return summary table" - -Task 3 (Explore): "Map data flow through system using Intent Layer. - How does data move between subsystems?" -``` - -**Synthesis**: Complete mental model of codebase in ~5 minutes vs ~15 minutes sequential. - -### Example: Parallel Team Onboarding - -**Scenario**: 3 new engineers joining (1 frontend, 1 backend, 1 fullstack) - -**Parallel execution**: -``` -Task 1: "Create onboarding path for frontend engineer. - - Identify UI-related AGENTS.md nodes - - Extract frontend-specific contracts and pitfalls - - List frontend entry points for common tasks - - Generate Day 1 and Week 1 checklist" - -Task 2: "Create onboarding path for backend engineer. - - Identify API/service AGENTS.md nodes - - Extract backend-specific contracts and pitfalls - - List backend entry points for common tasks - - Generate Day 1 and Week 1 checklist" - -Task 3: "Create onboarding path for fullstack engineer. - - Identify cross-cutting AGENTS.md nodes - - Extract integration contracts and pitfalls - - List full-stack entry points - - Generate Day 1 and Week 1 checklist" -``` - -**Output**: Three personalized onboarding documents in parallel. - -### Parallel Onboarding Benefits - -| Scenario | Sequential | Parallel | -|----------|------------|----------| -| 3-role documentation | ~30 min | ~10 min | -| 5-person team onboarding | ~75 min | ~15 min | -| Comprehensive docs (4 sections) | ~40 min | ~12 min | - ---- - -## Scripts Reference - -| Script | Purpose | -|--------|---------| -| `generate_orientation.sh` | Create onboarding documents | -| `show_hierarchy.sh` | Visualize Intent Layer structure | -| `show_status.sh` | Check Intent Layer health | -| `query_intent.sh` | Search for specific concepts | -| `walk_ancestors.sh` | Gather context from hierarchy | - -Scripts from intent-layer: `${CLAUDE_PLUGIN_ROOT}/scripts/` -Scripts from intent-layer-query: `${CLAUDE_PLUGIN_ROOT}/scripts/` - ---- - -## Anti-Patterns - -| Don't Do This | Do This Instead | -|--------------|-----------------| -| Skip root, jump to code | Always read root first | -| Read all nodes exhaustively | Read root + your area | -| Ignore Pitfalls section | Pitfalls prevent 80% of mistakes | -| Assume contracts are optional | Contracts are hard requirements | -| Start coding without reading Entry Points | Entry Points show the correct starting place | - ---- - -## Success Metrics - -After onboarding, the newcomer should be able to: - -1. **Explain** - Describe project purpose in one sentence -2. **Navigate** - Find the right AGENTS.md for any task -3. **Comply** - Know constraints that apply to their area -4. **Avoid** - Know common pitfalls in their area -5. **Start** - Know exactly which file to open first - -If any of these fail, the Intent Layer may need improvement via maintenance skill. diff --git a/skills/intent-layer-query/SKILL.md b/skills/intent-layer-query/SKILL.md index 111fd9c..f8ebd8a 100644 --- a/skills/intent-layer-query/SKILL.md +++ b/skills/intent-layer-query/SKILL.md @@ -1,5 +1,5 @@ --- -name: intent-layer-query +name: intent-layer:query description: > Query the Intent Layer to answer questions about the codebase. Use when asking "what owns X?", "where should I put Y?", "what constraints apply to Z?", @@ -321,7 +321,7 @@ Fall back to code analysis, but flag uncertainty: ### 3. Trigger Maintenance -If multiple gaps found, suggest running `intent-layer-maintenance` skill. +If multiple gaps found, suggest running `intent-layer:maintain` skill. --- diff --git a/skills/intent-layer-review/SKILL.md b/skills/intent-layer-review/SKILL.md new file mode 100644 index 0000000..02c323e --- /dev/null +++ b/skills/intent-layer-review/SKILL.md @@ -0,0 +1,113 @@ +--- +name: intent-layer:review +description: Batch review pending learnings from the Intent Layer learning loop. Rank by confidence, multiSelect for batch acceptance. +argument-hint: "[/path/to/project]" +--- + +# Intent Layer: Review Pending Learnings + +Batch review and triage of pending learning reports. Presents all pending items ranked by confidence for multi-select acceptance. + +## Step 1: Scan Pending Reports + +```bash +find "${CLAUDE_PROJECT_DIR:-.}/.intent-layer/mistakes/pending" -name "*.md" -type f 2>/dev/null | sort +``` + +If no reports found, tell the user: + +> Nothing to review. Intent Layer learning queue is empty. + +Then stop. + +## Step 2: Parse Each Report + +For every `.md` file in `pending/`, read it and extract: + +- **Title**: from `**Operation**:` line +- **Type**: from `**Type**:` line (pitfall, check, pattern, insight) +- **Confidence**: from `**Confidence**:` line (high, medium, low). Default to "medium" if missing. +- **Covering node**: from `**Covering node**:` or `**Existing node**:` line +- **Timestamp**: from `**Timestamp**:` line +- **Directory**: from `**Directory**:` line + +Also read the "What Went Wrong" / "Check Needed" / "Better Approach" / "Key Insight" section body for a one-line summary. + +## Step 3: Sort and Rank + +Sort items by: +1. Confidence: high > medium > low +2. Within same confidence: newest first (by timestamp) + +Assign rank numbers starting from 1. + +## Step 4: Present for Review + +Build a summary table in your message showing: + +``` +| # | Conf | Type | Title | Directory | +|---|--------|---------|---------------------------|-------------| +| 1 | high | pitfall | API response can be list | src/api/ | +| 2 | medium | pattern | Retry needs backoff | src/api/ | +| 3 | low | check | Type narrowing on union | src/ | +``` + +Then use `AskUserQuestion` with `multiSelect: true` to let the user select which items to integrate: + +- Each option label: `#N: [title]` (short enough for the chip UI) +- Each option description: `[type] — [one-line summary] (confidence: [level])` +- Include an option: "Discard all" with description "Delete all pending reports without integrating" + +**If there are more than 4 items**: present only the top 4 by confidence in the AskUserQuestion options. After processing those, loop back to Step 1 for remaining items. + +## Step 5: Integrate Selected Items + +For each selected item, run `learn.sh`: + +```bash +${CLAUDE_PLUGIN_ROOT}/scripts/learn.sh \ + --project "${CLAUDE_PROJECT_DIR:-.}" \ + --path "<directory from report>" \ + --type "<type from report>" \ + --title "<title from report>" \ + --detail "<detail/body from report>" +``` + +**Handle results:** +- Exit 0 → integrated. Delete the report file from `pending/`. +- Exit 2 → duplicate (already documented). Delete the report file. Note as "already known" in summary. +- Other exit → integration failed. Leave report in `pending/`. Note the failure in summary. + +## Step 6: Handle Unselected Items + +Leave unselected items in `pending/`. They'll appear in the next review. + +If "Discard all" was selected, delete all pending reports: +```bash +rm -f "${CLAUDE_PROJECT_DIR:-.}/.intent-layer/mistakes/pending/"*.md +``` + +## Step 7: Summary + +Show a brief summary: + +``` +Review complete: + Integrated: N + Already known: N + Failed: N + Deferred: N (still in pending/) + Discarded: N +``` + +If any items failed integration, suggest running `/intent-layer:review` again after fixing the underlying issue (usually a missing covering AGENTS.md node). + +--- + +## Notes + +- This skill replaces the old `review-mistakes` skill and `intent-layer-compound` end-of-session capture +- The stop hook auto-captures learnings with confidence scores — this skill is where humans triage them +- High-confidence learnings from the stop hook may already be auto-integrated via `learn.sh`. Those won't appear here. +- Reports include skeleton reports from tool failures and full reports from manual capture diff --git a/skills/intent-layer/SKILL.md b/skills/intent-layer/SKILL.md index 2c0ea8f..f9a2a11 100644 --- a/skills/intent-layer/SKILL.md +++ b/skills/intent-layer/SKILL.md @@ -1,510 +1,148 @@ --- name: intent-layer description: > - Set up hierarchical Intent Layer (AGENTS.md files) for codebases. - Use when initializing a new project, adding context infrastructure to an existing repo, - user asks to set up AGENTS.md, add intent layer, make agents understand the codebase, - or scaffolding AI-friendly project documentation. + Smart router for Intent Layer commands. Detects project state and routes to the + right action: setup, review pending learnings, maintenance, query, health check, + onboarding, or export. argument-hint: "[/path/to/project]" --- # Intent Layer -> **TL;DR**: Create CLAUDE.md/AGENTS.md files that help AI agents navigate your codebase like senior engineers. Run `detect_state.sh` first to see what's needed. +> **TL;DR**: Detects your project's Intent Layer state and routes you to the right action. -Hierarchical AGENTS.md infrastructure so agents navigate codebases like senior engineers. - ---- - -## Sub-Skills - -This skill includes specialized sub-skills that are **automatically invoked** when appropriate: - -| Sub-Skill | Location | Auto-Invoke When | -|-----------|----------|------------------| -| `git-history` | `git-history/SKILL.md` | Creating nodes for existing code (extracts pitfalls from commits) | -| `pr-review-mining` | `pr-review-mining/SKILL.md` | Creating nodes for existing code (extracts pitfalls from PR discussions) | -| `pr-review` | `pr-review/SKILL.md` | Reviewing PRs that touch Intent Layer nodes | - -### git-history (Auto-Invoked During Setup) - -When creating nodes for directories with git history, **automatically run git-history analysis** to pre-populate: -- **Pitfalls** from bug fix commits -- **Anti-patterns** from revert commits -- **Architecture Decisions** from refactor commits -- **Contracts** from breaking change commits - -``` -Trigger: Creating AGENTS.md for directory with >50 commits -Action: Run git-history analysis before writing node -``` - -### pr-review-mining (Auto-Invoked During Setup) - -When creating nodes for directories with merged PRs, **automatically run PR mining** to pre-populate: -- **Pitfalls** from PR Risks sections and review warnings -- **Contracts** from Breaking Changes sections -- **Architecture Decisions** from Why sections and Alternatives Considered -- **Anti-patterns** from rejected approaches in reviews - -``` -Trigger: Creating AGENTS.md for directory with merged PRs -Action: Run pr-review-mining alongside git-history, merge findings -``` - -### pr-review (Auto-Invoked for PRs) - -When reviewing PRs that modify code covered by Intent Layer: -- Verify contracts are respected -- Check pitfalls are avoided -- Flag potential Intent Layer updates needed - -``` -Trigger: PR touches files under an AGENTS.md -Action: Run pr-review with --ai-generated if applicable -``` - -### learning-loop (Auto-Invoked on Error Discovery) - -When you discover a non-obvious gotcha during any work (not just Intent Layer setup): -- Find the nearest AGENTS.md to where the issue occurred -- Append to its Pitfalls section -- Keep the Intent Layer alive with real lessons - -``` -Trigger: Fix error caused by non-obvious behavior (API format, config quirk, etc.) -Action: Append pitfall to nearest AGENTS.md -Format: - ### Short descriptive title - **Problem**: What assumption failed - **Symptom**: Error message or unexpected behavior - **Solution**: Correct approach with code reference -``` - -**Example**: After fixing `'list' object has no attribute 'get'` because Claude CLI output format varies: -```markdown -### Claude CLI JSON output format varies - -**Problem**: `claude --output-format json` can return dict or list -**Symptom**: `'list' object has no attribute 'get'` -**Solution**: Check `isinstance(data, list)` before `.get()`. See `lib/claude_runner.py:parse_claude_output()` -``` - ---- - -## Quick Start - -### Step 0: Check State - -```bash -scripts/detect_state.sh /path/to/project -``` - -| State | Action | -|-------|--------| -| `none` | Create root file (continue below) | -| `partial` | Add Intent Layer section to existing root | -| `complete` | Use `intent-layer-maintenance` skill instead | - -### Step 1: Measure +## Step 1: Detect State ```bash -# Auto-discover all candidate directories -scripts/estimate_all_candidates.sh /path/to/project - -# Or analyze structure first -scripts/analyze_structure.sh /path/to/project +${CLAUDE_PLUGIN_ROOT}/scripts/detect_state.sh "${1:-.}" ``` -### Step 2: Create Root Node - -Choose CLAUDE.md (Anthropic) or AGENTS.md (cross-tool). Pick template by size: -- **Small** (<50k tokens): `references/templates.md` → Small Project -- **Medium** (50-150k): `references/templates.md` → Medium Project -- **Large** (>150k/monorepo): `references/templates.md` → Large Project +Capture the output. It returns one of: `none`, `partial`, `complete`. -### Step 3: Create Child Nodes (if needed) +If the command fails, tell the user: -| Signal | Action | -|--------|--------| -| Directory >20k tokens | Create `AGENTS.md` | -| Responsibility shift | Create `AGENTS.md` | -| Cross-cutting concern | Document at nearest common ancestor | +> State detection failed. Run `detect_state.sh --help` for troubleshooting. -Use child template from `references/templates.md`. +Then stop. -### Step 4: Validate +## Step 2: Count Pending Learnings ```bash -scripts/validate_node.sh CLAUDE.md -scripts/validate_node.sh path/to/AGENTS.md +find "${CLAUDE_PROJECT_DIR:-.}/.intent-layer/mistakes/pending" -name "*.md" -type f 2>/dev/null | wc -l ``` -Checks: token count <4k, required sections, no absolute paths, no TODOs. +Store the count as `PENDING_COUNT`. -### Step 5: Cross-Tool Compatibility +## Step 3: Route -```bash -ln -s CLAUDE.md AGENTS.md # If CLAUDE.md is primary -``` +Use this matrix to decide what to do: ---- +| State | Pending | Action | +|-------|---------|--------| +| `none` | any | → **Setup** | +| `partial` | any | → **Continue Setup** | +| `complete` | >0 | → **Review** | +| `complete` | 0 | → **Menu** | -## Interactive Wizard +### Route: Setup (state = none) -Step-by-step guided setup with prompts at each decision point. +Tell the user: -### Step 1: Detect State +> No Intent Layer found. Want to set one up? -Run `scripts/detect_state.sh`, then based on result: +Use `AskUserQuestion` with options: +- "Yes, set up now" — proceed with setup workflow below +- "Not now" — stop -| State | Action | -|-------|--------| -| `none` | Ask user: "Create CLAUDE.md or AGENTS.md as root?" | -| `partial` | Ask user: "What's the one-line TL;DR for this project?" | -| `complete` | Redirect to `intent-layer-maintenance` skill | +If they choose setup, follow the **Setup Workflow** (see `workflows/setup.md` for quick reference). -### Step 2: Measure & Decide +The full setup flow is: +1. `estimate_all_candidates.sh` to measure directories +2. Mine history: `mine_git_history.sh` + `mine_pr_reviews.sh` per candidate +3. Create root node using template from `references/templates.md` +4. Create child AGENTS.md for directories >20k tokens or with responsibility shifts +5. `validate_node.sh` on each created node +6. Optional symlink for cross-tool compatibility -Run `scripts/estimate_all_candidates.sh`, then: -- Present candidates table to user -- Ask: "Which directories should get their own AGENTS.md?" +For large codebases (>200k tokens), use parallel subagents — one per subsystem for exploration + mining. -### Step 3: Mine History (Auto-Invoked) — HIGHEST VALUE STEP +### Route: Continue Setup (state = partial) -**Before creating each node**, automatically analyze both git history AND PR discussions using the mining scripts. Git-mined pitfalls are consistently the most valuable content in any node. Pitfalls discovered from real bugs (commit fixes, reverts, migrations) are far more useful than pitfalls guessed from reading code. +Tell the user: -```bash -# Git commit analysis (extracts pitfalls, anti-patterns, decisions, contracts) -${CLAUDE_PLUGIN_ROOT}/scripts/mine_git_history.sh [directory] - -# GitHub PR analysis (requires gh CLI) -${CLAUDE_PLUGIN_ROOT}/scripts/mine_pr_reviews.sh --limit 50 - -# Check for stale nodes (during maintenance) -${CLAUDE_PLUGIN_ROOT}/scripts/detect_staleness.sh --code-changes [directory] -``` - -**mine_git_history.sh** extracts from commits: -1. Bug fixes → Pre-populate Pitfalls -2. Reverts → Pre-populate Anti-patterns -3. Refactors → Pre-populate Architecture Decisions -4. Breaking changes → Pre-populate Contracts +> Intent Layer partially set up. CLAUDE.md exists but needs an Intent Layer section or child nodes. -**mine_pr_reviews.sh** extracts from PRs: -1. Risks sections → Pre-populate Pitfalls -2. Review warnings → Pre-populate Pitfalls -3. Breaking Changes → Pre-populate Contracts -4. Why/Alternatives → Pre-populate Architecture Decisions +Use `AskUserQuestion` with options: +- "Continue setup" — run setup workflow from where it left off +- "Not now" — stop -Present merged findings to user: "History suggests these pitfalls: [list]. Include them?" +### Route: Review (state = complete, pending > 0) -### Step 4: Create Nodes +Tell the user: -For root node: -- Ask user about project purpose -- Select template by size (Small/Medium/Large from `references/templates.md`) -- **Include git-history findings** in appropriate sections +> Intent Layer active. **{PENDING_COUNT} learning(s) pending review.** -For each child node: -- Ask user about directory's responsibility -- Use child template from `references/templates.md` -- **Include git-history findings** for that directory +Use `AskUserQuestion` with options: +- "Review now" — invoke `/intent-layer:review` skill +- "Skip, show menu" — fall through to Menu -### Step 4b: Add Pre-flight Checks +### Route: Menu (state = complete, pending = 0) -For directories with history of mistakes or complex operations: +Tell the user: -**Ask**: "What operations in this directory have caused problems before?" +> Intent Layer healthy. What would you like to do? -For each risky operation identified: -1. Ask: "What would you check before doing [operation]?" -2. Convert answer to verifiable check format -3. Add to Pre-flight Checks section - -**Mine from history**: -```bash -# Find reverts and fixes that suggest missing checks -${CLAUDE_PLUGIN_ROOT}/scripts/mine_git_history.sh [directory] | grep -i "fix\|revert" -``` - -Present findings: "These commits suggest potential checks: [list]. Add any?" - -### Step 5: Validate - -Run `scripts/validate_node.sh` on all created nodes: -- Show validation results -- Offer to fix warnings/errors - -### Step 6: Symlink - -Ask user: "Create symlink for cross-tool compatibility? (AGENTS.md → CLAUDE.md)" - -If yes: `ln -s CLAUDE.md AGENTS.md` +Use `AskUserQuestion` with options: +- "Run maintenance check" — invoke `/intent-layer:maintain` +- "Query the Intent Layer" — invoke `/intent-layer:query` +- "Run health check" — invoke `/intent-layer:health` +- "Generate onboarding doc" — follow onboarding workflow (see `workflows/onboard.md`) --- -## Parallel Setup (Large Codebases) - -For codebases >200k tokens, use parallel subagents to dramatically speed up exploration. - -### When to Use Parallel Mode - -| Codebase Size | Approach | -|---------------|----------| -| <100k tokens | Sequential (standard workflow) | -| 100-500k tokens | Parallel exploration, sequential synthesis | -| >500k tokens | Full parallel mode (explore + validate) | - -### Step 1: Identify Subsystems - -Run structure analysis first: -```bash -scripts/analyze_structure.sh /path/to/project -``` - -Identify 3-6 major subsystems from the output (e.g., `src/api/`, `src/core/`, `src/db/`). - -### Step 2: Parallel Exploration + History Mining - -Spawn subagents for **code exploration, git history, AND PR mining** in parallel: - -``` -# Code exploration (one per subsystem) -Task 1: "Analyze src/api/ for Intent Layer setup. Find: code map (find-it-fast - + key relationships), public API (exports used by others + core types), - external dependencies, data flow, entry points, contracts, patterns, - pitfalls. Return structured findings per section." - -Task 2: "Analyze src/core/ for Intent Layer setup. Find: code map (find-it-fast - + key relationships), public API (exports used by others + core types), - external dependencies, data flow, entry points, contracts, patterns, - pitfalls. Return structured findings per section." - -Task 3: "Analyze src/db/ for Intent Layer setup. Find: code map (find-it-fast - + key relationships), public API (exports used by others + core types), - external dependencies, data flow, entry points, contracts, patterns, - pitfalls. Return structured findings per section." - -# Git history analysis (parallel with exploration) -Task 4: "Run git-history analysis on src/api/. Find bug fixes, reverts, - refactors, and breaking changes. Return as Intent Layer findings." - -Task 5: "Run git-history analysis on src/core/. Find bug fixes, reverts, - refactors, and breaking changes. Return as Intent Layer findings." - -Task 6: "Run git-history analysis on src/db/. Find bug fixes, reverts, - refactors, and breaking changes. Return as Intent Layer findings." - -# PR review mining (parallel with above) -Task 7: "Run pr-review-mining on src/api/. Extract from PR descriptions - and review comments: pitfalls, contracts, architecture decisions. - Return as Intent Layer findings with PR numbers." - -Task 8: "Run pr-review-mining on src/core/. Extract from PR descriptions - and review comments: pitfalls, contracts, architecture decisions. - Return as Intent Layer findings with PR numbers." - -Task 9: "Run pr-review-mining on src/db/. Extract from PR descriptions - and review comments: pitfalls, contracts, architecture decisions. - Return as Intent Layer findings with PR numbers." -``` - -**Critical**: Launch all agents in parallel (single message with multiple Task calls). - -### Step 3: Synthesize Results - -Once all agents complete: -1. **Merge code exploration + git history + PR mining** findings per subsystem -2. Identify cross-cutting concerns (appear in multiple findings) -3. Place cross-cutting items in root node -4. Create child AGENTS.md for each subsystem with all sections: - - Purpose + Design Rationale (the "why") - - Code Map (find-it-fast + key relationships) - - Public API (key exports + core types) - - External Dependencies (services + failure modes) - - Data Flow (request path) - - Decisions (from git history + PR mining) - - Entry Points, Contracts, Patterns - - Pitfalls (from all sources) - - Boundaries, Pre-flight Checks -5. **Deduplicate** where multiple sources found the same insight -6. **Prefer PR-sourced rationale** for Decisions (richer "why" context) - -### Step 4: Parallel Validation - -Validate all nodes in parallel: -``` -Task 1: "Run validate_node.sh on CLAUDE.md, report results" -Task 2: "Run validate_node.sh on src/api/AGENTS.md, report results" -Task 3: "Run validate_node.sh on src/core/AGENTS.md, report results" -``` - -### Example Parallel Exploration Prompt - -For each subsystem, use this structured prompt: - -```markdown -Explore [DIRECTORY] for Intent Layer documentation. Return: - -## Design Rationale -[Why does this module exist? What problem does it solve? What's the core insight?] - -## Code Map -### Find It Fast -| Looking for... | Go to | -[What common searches map to which files? Focus on non-obvious locations.] - -### Key Relationships -[Import direction, layer rules, what depends on what] - -## Public API -### Key Exports -| Export | Used By | Change Impact | -[What do OTHER modules import from here?] - -### Core Types -[The 3-5 types needed to understand this area] - -## External Dependencies -| Service | Used For | Failure Mode | -[External services and what happens when down] - -## Data Flow -[How requests/data move through this area - simple diagram] - -## Decisions -| Decision | Why | Rejected | -[Architectural choices with rationale] - -## Entry Points -| Task | Start Here | -[Common tasks and where to start] - -## Contracts -[Non-type-enforced invariants] - -## Patterns -[How to do common tasks - sequence and non-obvious steps] - -## Pitfalls -[What looks wrong but isn't? What looks fine but breaks?] - -Keep findings specific to this directory. Note cross-cutting concerns separately. -``` +## Sub-Skills -### Parallel Mode Benefits +These are **automatically invoked** during setup when appropriate: -| Metric | Sequential | Parallel | -|--------|------------|----------| -| 500k token codebase | ~30 min | ~10 min | -| 1M+ token codebase | ~60 min | ~15 min | -| Subsystem coverage | Variable | Consistent | +| Sub-Skill | Location | Auto-Invoke When | +|-----------|----------|------------------| +| `git-history` | `git-history/SKILL.md` | Creating nodes for dirs with >50 commits | +| `pr-review-mining` | `pr-review-mining/SKILL.md` | Creating nodes for dirs with merged PRs | +| `pr-review` | `pr-review/SKILL.md` | Reviewing PRs touching Intent Layer nodes | ---- +### learning-loop (Auto-Invoked on Error Discovery) -## Spec-First Workflow (Greenfield) - -For projects WITHOUT existing code. Write Intent Nodes as specs, then scaffold. - -### Step 1: Define Scope -- What's the project vision? -- What are the major planned subsystems? -- Who are the stakeholders? - -### Step 2: Create Spec Root -Use "Spec Root Template" from `references/templates.md`: -- Vision statement (not TL;DR of existing code) -- Planned Subsystems (not discovered from code) -- Design Constraints (not extracted contracts) -- Implementation Targets (where to build first) - -### Step 3: Create Component Specs -For each planned subsystem, create AGENTS.md with: -- Responsibility Charter (what it will own) -- Interface Contracts (how others will call it) -- Acceptance Criteria (how we know it's done) - -### Step 4: AI Scaffolding -Ask Claude to scaffold against the specs: -- "Create directory structure matching the Planned Subsystems" -- "Generate interface stubs for the contracts defined" -- "Set up test fixtures based on acceptance criteria" - -### Step 5: Implementation Loop -Build incrementally: -1. Implement against spec -2. Update spec as requirements clarify -3. Spec nodes evolve into documentation nodes - -### Step 6: Transition to Maintenance -When implementation complete: -- Fill in discovered Pitfalls -- Add actual Entry Points -- Run `validate_node.sh` and transition to maintenance skill +When you discover a non-obvious gotcha during any work: +1. Find the nearest AGENTS.md +2. Append to its Pitfalls section +3. Format: `### Short title` + Problem/Symptom/Solution --- -## Concepts - -<details> -<summary><strong>Why Intent Layers?</strong> (click to expand)</summary> - -### The Problem -AI agents reading raw code lack the tribal knowledge that experienced engineers have: -- Where to start for common tasks -- What patterns are expected -- What invariants must never be violated -- What pitfalls to avoid - -### The Solution -Intent Nodes (CLAUDE.md/AGENTS.md files) provide compressed, high-signal context that tells agents *what matters* without reading thousands of lines of code. - -### How It Works -- **Ancestor-based loading**: Reading a child node auto-loads all ancestors (T-shaped knowledge) -- **Progressive disclosure**: Start minimal, agents drill down when needed -- **Compression**: 200k tokens of code → 2k token node (100:1 ratio) - -</details> +## Workflow References -<details> -<summary><strong>Core Rules</strong> (click to expand)</summary> +Detailed procedures for each major workflow: -### One Root Only -CLAUDE.md and AGENTS.md should NOT coexist at project root. Pick one and symlink the other for cross-tool compatibility. +| Workflow | Reference File | +|----------|---------------| +| Setup (initial creation) | `workflows/setup.md` | +| Maintenance (audits, updates) | `workflows/maintain.md` | +| Onboarding (orient newcomers) | `workflows/onboard.md` | -### Child Nodes Named AGENTS.md -Subdirectory nodes should be `AGENTS.md` (not CLAUDE.md) for cross-tool compatibility. - -### Token Budgets -- Each node: <4k tokens (prefer <3k) -- Target 100:1 compression -- If you can't compress, scope is too broad → split - -### What to Document -Keep: code map (non-obvious locations), public API (what others depend on), external dependencies, data flow, decisions with rationale, contracts, patterns (non-obvious steps), pitfalls -Delete: obvious mappings (routes.ts → routes), type-enforced invariants, internal exports, standard patterns, tech stack lists - -</details> - -<details> -<summary><strong>Effort Estimates</strong> (click to expand)</summary> - -| Codebase Size | Experienced | Newcomer | -|---------------|-------------|----------| -| <50k tokens | 1-2 hours | 3-5 hours | -| 50-150k tokens | 3-5 hours | 6-10 hours | -| >150k tokens | 5-10 hours | 10-20 hours | +--- -Budget additional time for SME interviews—tribal knowledge takes conversation to extract. +## Related Commands -</details> +| Command | Purpose | +|---------|---------| +| `/intent-layer:maintain` | Quarterly audits, post-incident updates | +| `/intent-layer:query` | Answer questions using Intent Layer | +| `/intent-layer:health` | Quick validation + staleness check | +| `/intent-layer:review` | Batch triage pending learnings | --- -## Resources - -### Scripts +## Scripts | Script | Purpose | |--------|---------| @@ -513,287 +151,20 @@ Budget additional time for SME interviews—tribal knowledge takes conversation | `estimate_tokens.sh` | Measure single directory | | `estimate_all_candidates.sh` | Measure all candidates at once | | `validate_node.sh` | Check node quality before committing | -| `capture_pain_points.sh` | Generate maintenance capture template | -| `detect_changes.sh` | Find affected nodes on merge/PR | -| `show_status.sh` | Health dashboard with metrics and recommendations | +| `show_status.sh` | Health dashboard with metrics | | `show_hierarchy.sh` | Visual tree display of all nodes | -| `review_pr.sh` | Review PR against Intent Layer | -| `capture_mistake.sh` | Generate mistake report for check extraction | - -### Sub-Skills - -| Sub-Skill | Location | Purpose | -|-----------|----------|---------| -| `git-history` | `git-history/SKILL.md` | Extract pitfalls/contracts from commit history | -| `pr-review-mining` | `pr-review-mining/SKILL.md` | Extract pitfalls/contracts from PR discussions | -| `pr-review` | `pr-review/SKILL.md` | Review PRs against Intent Layer contracts | - -### References - -| File | Purpose | -|------|---------| -| `templates.md` | Root (S/M/L) and child templates, three-tier boundaries | -| `node-examples.md` | Real-world examples | -| `capture-protocol.md` | SME interview questions | -| `compression-techniques.md` | How to achieve 100:1 compression, LCA placement | -| `agent-feedback-protocol.md` | Continuous improvement loop | - ---- - -## Capture Questions - -> **TL;DR**: Ask these when documenting existing code. Focus on what agents can't infer from code itself. - -### Scope & Navigation -1. What does this area own? What's explicitly out of scope? -2. Where do developers commonly search? What's in non-obvious locations? -3. What are the key relationships between modules? (import direction, layers) - -### Public Interface -4. What exports do OTHER modules actually depend on? -5. What 3-5 types must someone understand to work here? - -### External Dependencies -6. What external services does this area use? What happens when they're down? - -### Design Rationale (the "why") -7. What problem drove the creation of this module? What pain point does it solve? -8. What's the core insight or philosophy? What would you lose if you removed it? -9. What constraints shaped the design? (performance, compatibility, team size, etc.) - -### Understanding & Debugging -10. How does data flow through this area? (request → response path) -11. Why were specific technical choices made? What alternatives were rejected? - -### Consistency & Safety -12. What invariants must hold that aren't enforced by types? -13. What patterns must be followed for common tasks? -14. What operations require verification before proceeding? - -### Pitfalls (highest value) -15. What repeatedly confuses new engineers? -16. What looks wrong but is correct? What looks correct but will break? - -For full protocol: `references/capture-protocol.md` - ---- - -## When to Create Child Nodes +| `mine_git_history.sh` | Extract insights from git commits | +| `mine_pr_reviews.sh` | Extract insights from GitHub PRs | +| `generate_adapter.sh` | Export to Cursor / raw markdown | -> **TL;DR**: >20k tokens or responsibility shift → create. Simple utilities → don't. - -| Signal | Action | -|--------|--------| -| >20k tokens in directory | Create AGENTS.md | -| Responsibility shift (different owner/concern) | Create AGENTS.md | -| Hidden contracts/invariants | Document in nearest ancestor | -| Cross-cutting concern | Place at lowest common ancestor | - -**Do NOT create for**: -- Every directory -- Simple utilities or config-only directories -- Test folders (unless complex test infrastructure) -- Directories with <5 source files AND <2k tokens (too little to document meaningfully — a 54-line node for 4 markdown files is filler) - ---- - -## Pre-flight Checks - -> **TL;DR**: Testable verifications before risky operations. Add when mistakes reveal missing checks. - -### What They Are - -Pre-flight checks are **verifiable assertions** an agent runs before modifying code. They catch "I thought I understood" mistakes. - -### When to Add - -| Signal | Action | -|--------|--------| -| Mistake happened | Write check that would have caught it | -| PR reviewer flagged missing step | Convert to check | -| Complex multi-step operation | Add checks for each step | -| Critical/irreversible operation | Add comprehension + human gate | - -### When NOT to Add - -- Every operation (over-checking slows agents down) -- Things covered by Boundaries section (use Always/Never instead) -- Awareness-only items (use Pitfalls instead) - -### Format - -See `references/templates.md` → Writing Pre-flight Checks for the standard format. - -### Mining Checks from History - -```bash -# Find commits suggesting missing verifications -scripts/mine_git_history.sh --since "6 months ago" [directory] | grep -E "fix|broke|forgot" -``` - -Look for patterns like "forgot to update X" or "broke Y because didn't check Z". +All paths: `${CLAUDE_PLUGIN_ROOT}/scripts/` --- -## Capture Order (Leaf-First) - -> **TL;DR**: Start at leaves, work up to root. Clarity compounds upward. - -Always capture leaf-first, easy-to-hard: - -1. **Start with deepest directories** (most concrete) - - Leaf nodes compress raw code—patterns are visible - - Easier to identify contracts when you see the implementation - -2. **Work up to parent nodes** (summarize children) - - Parent nodes compress children's Intent Nodes, not raw code - - Wait until children are stable before writing parent - -3. **Finish with root** (summarize entire hierarchy) - - Root references child nodes, provides navigation - - Global invariants emerge from seeing all children - -**Why this order?** -- Clarity compounds upward—parent nodes reference stable children -- Avoids rewriting parents when children change -- Natural: understand details before summarizing - -**Anti-pattern**: Starting at root and working down leads to vague descriptions that need constant revision as you discover what's actually in the code. - ---- - -## Feedback Flywheel - -> **TL;DR**: Agents surface missing context during work → humans review → Intent Layer improves → future agents start better. - -### Continuous Improvement Loop - -``` -Agent works → Finds gap → Surfaces finding → Human reviews → Node updated → Future agents benefit -``` - -### During Normal Work - -When you encounter gaps while working, surface them using the format in `references/agent-feedback-protocol.md`: - -```markdown -### Intent Layer Feedback -| Type | Location | Finding | -|------|----------|---------| -| Missing pitfall | `src/api/AGENTS.md` | Rate limiter fails silently when Redis down | -``` - -### On Merge/PR - -Run change detection to identify which nodes need review: - -```bash -scripts/detect_changes.sh main HEAD -``` - -This outputs affected nodes in leaf-first order for systematic review. - -### Full Protocol - -See `references/agent-feedback-protocol.md` for: -- When to surface findings -- Structured feedback format -- Human review workflow (Accept/Reject/Defer) - -### Mistake → Check Pipeline - -When agents surface mistakes, evaluate for check conversion: - -``` -Mistake surfaced → "Would a check have caught this?" - │ - ┌─────────────┴─────────────┐ - │ │ - Yes No - │ │ - ▼ ▼ - Write Pre-flight Check Add to Pitfalls - │ (awareness only) - ▼ - Add to AGENTS.md Pre-flight section -``` - -**Check conversion template**: -```markdown -Mistake: [What happened] -Operation: [What agent was doing] -Check: Before [operation] → [verification that would have caught it] -``` - -Use `scripts/capture_mistake.sh` to generate structured mistake reports. - ---- - -## Maintenance Flywheel - -> **TL;DR**: Update nodes when behavior changes, not just when code changes. - -When files change (e.g., on merge): - -1. **Identify affected nodes** - Run `scripts/detect_changes.sh base head` -2. **Check behavior change** - Did contracts/invariants change, or just formatting? -3. **Update if needed** - Behavior change → update affected node -4. **Consider new nodes** - Patterns emerging → new node or LCA update? - -For full maintenance workflow, use: **`intent-layer-maintenance`** skill - ---- - -## What's Next? - -After completing initial setup (state = `complete`): - -### Immediate Actions -1. Create symlink for cross-tool compatibility -2. Test by asking an AI agent to perform a common task -3. Share with team (note in README or onboarding docs) - -### Ongoing Maintenance -| Trigger | Action | -|---------|--------| -| Quarterly | Run `intent-layer-maintenance` skill | -| Post-incident | Update Pitfalls + Contracts | -| After refactor | Update Entry Points + Subsystem Boundaries | -| After new feature | Update Architecture Decisions + Patterns | -| **PR Review** | **Auto-invoke `pr-review` sub-skill** | - -### PR Review Integration (Auto-Invoked) - -When reviewing PRs that touch files covered by Intent Layer nodes: - -```bash -# Automatically run pr-review -scripts/review_pr.sh main HEAD --ai-generated -``` - -The `pr-review` sub-skill will: -- Check PR against contracts in relevant AGENTS.md -- Flag if PR approaches documented pitfalls -- Suggest Intent Layer updates if contracts changed - -### Optional: CI Integration - -```yaml -- name: Check Intent Layer - run: ${CLAUDE_PLUGIN_ROOT}/scripts/detect_state.sh . - -- name: PR Review (if Intent Layer exists) - if: github.event_name == 'pull_request' - run: | - ${CLAUDE_PLUGIN_ROOT}/scripts/review_pr.sh origin/main HEAD --exit-code -``` +## Core Rules -### Related Skills -| Skill | Use When | -|-------|----------| -| `intent-layer-maintenance` | Quarterly audits, post-incident updates | -| `intent-layer-query` | Asking questions about the codebase | -| `intent-layer-onboarding` | Orienting newcomers | -| `git-history` (sub-skill) | Mining commit history for insights | -| `pr-review-mining` (sub-skill) | Mining PR discussions for insights | -| `pr-review` (sub-skill) | Reviewing PRs against Intent Layer | +- **One root only**: CLAUDE.md and AGENTS.md should not coexist at root. Pick one, symlink the other. +- **Child nodes named AGENTS.md**: For cross-tool compatibility. +- **Token budgets**: Each node <4k tokens (prefer <3k). Target 100:1 compression. +- **Capture order**: Leaf-first, then parents, then root. Clarity compounds upward. +- **When to create child nodes**: >20k tokens in directory OR responsibility shift. Don't create for every directory. diff --git a/skills/intent-layer/git-history/SKILL.md b/skills/intent-layer/git-history/SKILL.md index e9680ba..ac6e555 100644 --- a/skills/intent-layer/git-history/SKILL.md +++ b/skills/intent-layer/git-history/SKILL.md @@ -248,7 +248,7 @@ Use git-history during initial setup to pre-populate nodes: 3. Pre-fill Pitfalls and Architecture Decisions from history 4. Human reviews and refines -### With intent-layer-maintenance (audits) +### With intent-layer:maintain (audits) Use git-history to find undocumented changes: @@ -257,7 +257,7 @@ Use git-history to find undocumented changes: 3. Check if new pitfalls/contracts emerged since last audit 4. Propose updates based on commit analysis -### With intent-layer-query +### With intent-layer:query When query returns "uncertain" confidence: diff --git a/skills/intent-layer/pr-review-mining/SKILL.md b/skills/intent-layer/pr-review-mining/SKILL.md index ee9cebf..39e743e 100644 --- a/skills/intent-layer/pr-review-mining/SKILL.md +++ b/skills/intent-layer/pr-review-mining/SKILL.md @@ -208,7 +208,7 @@ Use both for complete coverage: - git-history catches changes without PR discussion - pr-review-mining provides deeper rationale -### With intent-layer-maintenance (audits) +### With intent-layer:maintain (audits) After significant merges: diff --git a/skills/intent-layer/workflows/maintain.md b/skills/intent-layer/workflows/maintain.md new file mode 100644 index 0000000..64e708f --- /dev/null +++ b/skills/intent-layer/workflows/maintain.md @@ -0,0 +1,43 @@ +# Maintenance Workflow + +Quick reference for `/intent-layer:maintain` audit flow. See `skills/intent-layer-maintain/SKILL.md` for full details. + +## Flow + +1. `detect_state.sh` → must be `complete`; otherwise redirect to `/intent-layer` +2. `estimate_all_candidates.sh` → measure token growth +3. Flag directories >20k tokens as child node candidates +4. Ask pain point questions (pitfalls, contract violations, architecture changes) +5. Map findings to AGENTS.md sections +6. Present update proposal to user +7. Apply approved updates + validate + +## Audit Types + +| Trigger | Focus | +|---------|-------| +| Quarterly review | Full: tokens + all question categories | +| Post-incident | Pitfalls + Contracts that were violated | +| After refactor | Entry Points + Subsystem Boundaries | +| After new feature | Architecture Decisions + Patterns | + +## Finding → Section Mapping + +| Finding Type | Target Section | +|--------------|----------------| +| Surprising behavior | Pitfalls | +| "Never do X" rule | Anti-patterns | +| Must-be-true constraint | Contracts | +| Technical decision rationale | Architecture Decisions | +| New common task | Entry Points | +| New subsystem | Subsystem Boundaries | + +## Key Scripts + +| Script | Purpose | +|--------|---------| +| `detect_state.sh` | Check state | +| `estimate_all_candidates.sh` | Measure all directories | +| `detect_changes.sh` | Find affected nodes on merge/PR | +| `detect_staleness.sh` | Find nodes needing updates | +| `validate_node.sh` | Validate after edits | diff --git a/skills/intent-layer/workflows/onboard.md b/skills/intent-layer/workflows/onboard.md new file mode 100644 index 0000000..b529efb --- /dev/null +++ b/skills/intent-layer/workflows/onboard.md @@ -0,0 +1,52 @@ +# Onboarding Workflow + +Quick reference for orienting newcomers using an existing Intent Layer. Previously the standalone `/intent-layer-onboarding` skill. + +## Prerequisites + +- Intent Layer state must be `complete` +- Run `show_hierarchy.sh` to visualize structure + +## The 15-Minute Orientation + +1. **Read root node** (2 min) — TL;DR, Subsystem Boundaries, Contracts, Pitfalls +2. **Map hierarchy** (2 min) — `show_hierarchy.sh`, note depth and complexity +3. **Identify entry point** (3 min) — match role/task to subsystem AGENTS.md +4. **Deep-read your area** (5 min) — Entry Points, Contracts, Pitfalls +5. **Verify understanding** (3 min) — can you explain, navigate, comply, avoid, start? + +## Role-Based Entry Points + +| Role | Start With | +|------|-----------| +| Frontend | UI/components AGENTS.md | +| Backend | API/services AGENTS.md | +| DevOps | Infrastructure AGENTS.md | +| Full-stack | Root + busiest subsystem | + +## Task-Based Entry Points + +| Task | Flow | +|------|------| +| Fix bug in X | Find nearest AGENTS.md → Pitfalls → Contracts → Entry Point | +| Add feature to Y | Find AGENTS.md → check scope → Entry Points → Contracts → parent constraints | +| Understand Z | Find AGENTS.md → TL;DR → Architecture Decisions → Entry Points → ancestors | + +## Key Scripts + +| Script | Purpose | +|--------|---------| +| `generate_orientation.sh` | Create onboarding documents | +| `show_hierarchy.sh` | Visualize Intent Layer structure | +| `show_status.sh` | Check Intent Layer health | +| `query_intent.sh` | Search for specific concepts | +| `walk_ancestors.sh` | Gather context from hierarchy | + +## Verification Checklist + +After onboarding, the newcomer should be able to: +1. Explain the project in one sentence +2. Find the right AGENTS.md for any task +3. Know constraints that apply to their area +4. Know common pitfalls in their area +5. Know which file to open first diff --git a/skills/intent-layer/workflows/setup.md b/skills/intent-layer/workflows/setup.md new file mode 100644 index 0000000..91dc647 --- /dev/null +++ b/skills/intent-layer/workflows/setup.md @@ -0,0 +1,30 @@ +# Setup Workflow + +Quick reference for `/intent-layer` setup flow. See main `SKILL.md` for full details. + +## Flow + +1. `detect_state.sh` → none/partial → proceed; complete → redirect to `/intent-layer:maintain` +2. `estimate_all_candidates.sh` → measure all directories +3. Mine history: `mine_git_history.sh` + `mine_pr_reviews.sh` per directory +4. Create root node (CLAUDE.md) using template from `references/templates.md` +5. Create child AGENTS.md nodes for directories >20k tokens or responsibility shifts +6. `validate_node.sh` on each created node +7. Optional: symlink CLAUDE.md ↔ AGENTS.md for cross-tool compatibility + +## Key Scripts + +| Script | Purpose | +|--------|---------| +| `detect_state.sh` | Check state (none/partial/complete) | +| `estimate_all_candidates.sh` | Measure all candidate directories | +| `mine_git_history.sh` | Extract pitfalls from commits | +| `mine_pr_reviews.sh` | Extract pitfalls from PRs | +| `validate_node.sh` | Validate node quality | + +## Decision Points + +- **Root format**: CLAUDE.md (Anthropic) or AGENTS.md (cross-tool) +- **Template size**: Small (<50k), Medium (50-150k), Large (>150k) +- **Child node threshold**: >20k tokens or responsibility shift +- **Capture order**: leaf-first, then parents, then root diff --git a/skills/review-mistakes/SKILL.md b/skills/review-mistakes/SKILL.md deleted file mode 100644 index bad774f..0000000 --- a/skills/review-mistakes/SKILL.md +++ /dev/null @@ -1,209 +0,0 @@ ---- -name: review-mistakes -description: > - Interactive review of pending mistake reports from the learning loop. - Walk through each report with the user, accepting/rejecting/discarding as appropriate. -argument-hint: "[/path/to/project]" ---- - -# Review Mistakes - -Interactively review pending mistake reports from the Intent Layer learning loop. - -## Overview - -When agents make mistakes during development, skeleton reports are auto-captured in `.intent-layer/mistakes/pending/`. This skill helps you and the user review these reports conversationally, deciding which should become pitfalls in the Intent Layer. - -## Prerequisites - -Check for pending reports: -```bash -ls -la ${CLAUDE_PROJECT_DIR:-.}/.intent-layer/mistakes/pending/ -``` - -## Workflow - -### Step 1: List Pending Reports - -```bash -find "${CLAUDE_PROJECT_DIR:-.}/.intent-layer/mistakes/pending" \ - \( -name "MISTAKE-*.md" -o -name "SKELETON-*.md" \) \ - -type f 2>/dev/null | sort -``` - -If no reports, inform the user there's nothing to review. - -### Step 2: For Each Report - -Read the report and present a summary: - -```markdown ---- -**Report**: SKELETON-2026-01-23-1234.md - -**Directory**: src/auth/ -**Operation**: Edit on login.ts -**What happened**: Tool Edit failed - old_string not found -**Covering node**: src/auth/AGENTS.md - -**Analysis**: [Your assessment - is this a real mistake or exploratory?] ---- -``` - -### Step 3: Ask User Decision - -Present options clearly: - -> **What would you like to do with this report?** -> -> 1. **Accept** - This is a real gotcha, add as pitfall to AGENTS.md -> 2. **Reject** - Not useful (I'll ask for a reason) -> 3. **Discard** - Exploratory failure, not a real mistake -> 4. **Enrich** - Add more context before deciding -> 5. **Skip** - Review later - -### Step 4: Execute Decision - -#### On Accept - -Run the integration script: - -```bash -${CLAUDE_PLUGIN_ROOT}/lib/integrate_pitfall.sh "${CLAUDE_PROJECT_DIR:-.}/.intent-layer/mistakes/pending/<filename>" -``` - -This will: -- Find the covering AGENTS.md -- Extract/generate a pitfall entry -- Append to the Pitfalls section -- Move report to `integrated/` - -#### On Reject - -Ask for rejection reason, then: - -```bash -# Create rejected directory if needed -mkdir -p "${CLAUDE_PROJECT_DIR:-.}/.intent-layer/mistakes/rejected" - -# Add rejection reason to file -echo -e "\n### Rejection\n**Reason**: <reason>\n**Date**: $(date -u +"%Y-%m-%dT%H:%M:%SZ")" >> "<file>" - -# Move to rejected -mv "<file>" "${CLAUDE_PROJECT_DIR:-.}/.intent-layer/mistakes/rejected/" -``` - -#### On Discard - -Simply delete the skeleton: - -```bash -rm "<file>" -``` - -Confirm to user: "Discarded - this was an exploratory failure, not a real mistake." - -#### On Enrich - -Open the file for editing or help the user add: -- Better description of what went wrong -- Root cause analysis -- Suggested pitfall text - -Then return to Step 3. - -#### On Skip - -Move to the next report. Track skipped files to mention at the end. - -### Step 5: Summary - -After reviewing all reports (or when user wants to stop): - -```markdown -## Review Summary - -- **Accepted**: 2 (pitfalls added to AGENTS.md) -- **Rejected**: 1 -- **Discarded**: 3 (exploratory failures) -- **Skipped**: 1 (still pending) - -Remaining pending: 1 report(s) -``` - ---- - -## Report Types - -### Skeleton Reports (SKELETON-*.md) - -Auto-created by PostToolUseFailure hook. Contains: -- Tool and file context -- Placeholder fields for root cause and suggested fix -- Often exploratory failures - review carefully - -**Common skeleton dispositions:** -- **Discard** if: Edit failed because string wasn't found (typo, wrong file) -- **Discard** if: Bash command failed during exploration -- **Accept** if: Failure revealed a non-obvious gotcha about the codebase -- **Enrich then Accept** if: Real mistake but needs better description - -### Full Reports (MISTAKE-*.md) - -Created manually via `capture_mistake.sh`. Contains: -- Detailed description from human/agent -- Root cause analysis -- Suggested fix - -**Common full report dispositions:** -- **Accept** if: Well-documented, clear pitfall -- **Reject** if: One-off issue, not worth documenting -- **Enrich then Accept** if: Good insight but needs clearer pitfall text - ---- - -## Example Conversation - -**Agent**: "I found 3 pending mistake reports. Would you like to review them now?" - -**User**: "yes" - -**Agent**: -> --- -> **Report**: SKELETON-2026-01-23-4521.md -> -> **Directory**: src/api/ -> **Operation**: Edit on routes.ts -> **What happened**: Edit failed - old_string not found -> **Covering node**: src/api/AGENTS.md -> -> **Analysis**: This looks like the Edit tool couldn't find the exact string to replace. This could be: -> - A typo in the old_string (exploratory) -> - The file had been modified and the string changed (possible gotcha) -> --- -> -> What would you like to do? (1) Accept (2) Reject (3) Discard (4) Enrich (5) Skip - -**User**: "3 - it was just a typo" - -**Agent**: "Discarded. Moving to next report..." - ---- - -## Scripts Reference - -| Script | Purpose | -|--------|---------| -| `lib/integrate_pitfall.sh` | Auto-add pitfall to covering AGENTS.md | -| `scripts/capture_mistake.sh` | Manual capture (if needed) | - -All paths: `${CLAUDE_PLUGIN_ROOT}/` - ---- - -## Tips - -- **Be conservative with Accept** - Only document genuine gotchas that would trip up future agents -- **Discard freely** - Most skeletons from exploratory failures should be discarded -- **Enrich before Accept** - A well-written pitfall is more useful than a vague one -- **Batch review** - Review all pending reports periodically rather than one at a time diff --git a/tests/test_colors.sh b/tests/test_colors.sh new file mode 100644 index 0000000..54c462b --- /dev/null +++ b/tests/test_colors.sh @@ -0,0 +1,190 @@ +#!/usr/bin/env bash +# Tests for ANSI color support in dashboard scripts +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PLUGIN_DIR="$(dirname "$SCRIPT_DIR")" +TEST_DIR="" +PASSED=0 +FAILED=0 + +pass() { echo "PASS: $1"; PASSED=$((PASSED + 1)); } +fail() { echo "FAIL: $1"; FAILED=$((FAILED + 1)); } + +# Portable ANSI escape detection (works on macOS and Linux) +has_ansi() { printf '%s' "$1" | grep -q $'\033\['; } + +cleanup() { + [[ -n "$TEST_DIR" && -d "$TEST_DIR" ]] && rm -rf "$TEST_DIR" +} +trap cleanup EXIT + +echo "=== Color Support Tests ===" +echo "" + +# ============================================================ +# Fixture: project with Intent Layer nodes +# ============================================================ +TEST_DIR=$(mktemp -d) +export CLAUDE_PLUGIN_ROOT="$PLUGIN_DIR" + +cat > "$TEST_DIR/CLAUDE.md" << 'EOF' +# Test Project + +## Intent Layer + +### Downlinks + +| Area | Node | +|------|------| +| src | src/AGENTS.md | + +## Pitfalls + +### Example pitfall +Check for null. +EOF + +mkdir -p "$TEST_DIR/src" +cat > "$TEST_DIR/src/AGENTS.md" << 'EOF' +# Source Module + +## Pitfalls + +### Watch out +Be careful. +EOF + +# ============================================================ +# Test 1: setup_colors sets variables when on TTY +# ============================================================ + +# We can't test real TTY, but we can test the NO_COLOR path +output=$(NO_COLOR=1 bash -c ' +source "'"$PLUGIN_DIR"'/lib/common.sh" +setup_colors +echo "RED=[$RED] GREEN=[$GREEN] BOLD=[$BOLD] RESET=[$RESET]" +') + +if echo "$output" | grep -q 'RED=\[\] GREEN=\[\] BOLD=\[\] RESET=\[\]'; then + pass "setup_colors respects NO_COLOR (all vars empty)" +else + fail "setup_colors should produce empty vars when NO_COLOR is set, got: $output" +fi + +# ============================================================ +# Test 2: show_status.sh outputs without ANSI when piped +# ============================================================ + +output=$("$PLUGIN_DIR/scripts/show_status.sh" "$TEST_DIR" 2>&1) + +# Piped output should have no ANSI escape sequences +if has_ansi "$output"; then + fail "show_status.sh should not emit ANSI when piped" +else + pass "show_status.sh suppresses ANSI when piped" +fi + +# Check it still has expected content +if echo "$output" | grep -q "INTENT LAYER STATUS DASHBOARD"; then + pass "show_status.sh outputs dashboard header" +else + fail "show_status.sh missing dashboard header" +fi + +# ============================================================ +# Test 3: show_hierarchy.sh outputs without ANSI when piped +# ============================================================ + +output=$("$PLUGIN_DIR/scripts/show_hierarchy.sh" "$TEST_DIR" 2>&1) + +if has_ansi "$output"; then + fail "show_hierarchy.sh should not emit ANSI when piped" +else + pass "show_hierarchy.sh suppresses ANSI when piped" +fi + +if echo "$output" | grep -q "Intent Layer Hierarchy"; then + pass "show_hierarchy.sh outputs hierarchy header" +else + fail "show_hierarchy.sh missing hierarchy header" +fi + +# ============================================================ +# Test 4: show_status.sh --json ignores color entirely +# ============================================================ + +json_output=$("$PLUGIN_DIR/scripts/show_status.sh" --json "$TEST_DIR" 2>&1) + +if has_ansi "$json_output"; then + fail "show_status.sh --json should never emit ANSI" +else + pass "show_status.sh --json has no ANSI escapes" +fi + +# Validate it's valid JSON +if echo "$json_output" | python3 -m json.tool > /dev/null 2>&1; then + pass "show_status.sh --json produces valid JSON" +else + fail "show_status.sh --json output is not valid JSON" +fi + +# ============================================================ +# Test 5: audit_intent_layer.sh outputs without ANSI when piped +# ============================================================ + +output=$("$PLUGIN_DIR/scripts/audit_intent_layer.sh" --quick "$TEST_DIR" 2>&1) || true + +if has_ansi "$output"; then + fail "audit_intent_layer.sh should not emit ANSI when piped" +else + pass "audit_intent_layer.sh suppresses ANSI when piped" +fi + +if echo "$output" | grep -q "OVERALL:"; then + pass "audit_intent_layer.sh outputs OVERALL status" +else + fail "audit_intent_layer.sh missing OVERALL status" +fi + +# ============================================================ +# Test 6: audit_intent_layer.sh --json ignores color +# ============================================================ + +json_output=$("$PLUGIN_DIR/scripts/audit_intent_layer.sh" --json --quick "$TEST_DIR" 2>&1) || true + +if has_ansi "$json_output"; then + fail "audit_intent_layer.sh --json should never emit ANSI" +else + pass "audit_intent_layer.sh --json has no ANSI escapes" +fi + +if echo "$json_output" | python3 -m json.tool > /dev/null 2>&1; then + pass "audit_intent_layer.sh --json produces valid JSON" +else + fail "audit_intent_layer.sh --json output is not valid JSON" +fi + +# ============================================================ +# Test 7: NO_COLOR=1 suppresses color in all scripts +# ============================================================ + +# Even if stdout is a TTY (simulated), NO_COLOR should win +for script in show_status.sh show_hierarchy.sh; do + output=$(NO_COLOR=1 "$PLUGIN_DIR/scripts/$script" "$TEST_DIR" 2>&1) + if has_ansi "$output"; then + fail "$script ignores NO_COLOR" + else + pass "$script respects NO_COLOR=1" + fi +done + +# ============================================================ +# Summary +# ============================================================ +echo "" +echo "Results: $PASSED passed, $FAILED failed" + +if [[ "$FAILED" -gt 0 ]]; then + exit 1 +fi diff --git a/tests/test_dedup.sh b/tests/test_dedup.sh new file mode 100644 index 0000000..9b2bc00 --- /dev/null +++ b/tests/test_dedup.sh @@ -0,0 +1,204 @@ +#!/usr/bin/env bash +# Tests for PreToolUse session deduplication +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PLUGIN_DIR="$(dirname "$SCRIPT_DIR")" +TEST_DIR="" +ORIG_TMPDIR="${TMPDIR:-/tmp}" +PASSED=0 +FAILED=0 + +pass() { echo "PASS: $1"; PASSED=$((PASSED + 1)); } +fail() { echo "FAIL: $1"; FAILED=$((FAILED + 1)); } + +cleanup() { + [[ -n "$TEST_DIR" && -d "$TEST_DIR" ]] && rm -rf "$TEST_DIR" + # Clean up dedup files created during tests + rm -f "${ORIG_TMPDIR}/intent-layer-dedup-test-session-"* 2>/dev/null || true +} +trap cleanup EXIT + +echo "=== PreToolUse Dedup Tests ===" +echo "" + +# ============================================================ +# Fixture: project with a covering AGENTS.md +# ============================================================ +TEST_DIR=$(mktemp -d) +export CLAUDE_PLUGIN_ROOT="$PLUGIN_DIR" +export CLAUDE_PROJECT_DIR="$TEST_DIR" +export TMPDIR="$ORIG_TMPDIR" + +mkdir -p "$TEST_DIR/.intent-layer/hooks" +mkdir -p "$TEST_DIR/src/api" + +cat > "$TEST_DIR/CLAUDE.md" << 'EOF' +# Test Project + +## Intent Layer + +### Downlinks + +| Area | Node | +|------|------| +| src | src/AGENTS.md | +EOF + +cat > "$TEST_DIR/src/AGENTS.md" << 'EOF' +# Source Module + +## Pitfalls + +### Watch out for nulls +Check for null before dereferencing. + +## Patterns + +### Use early returns +Prefer guard clauses over nested conditionals. +EOF + +# Create a real file to edit +echo "const x = 1;" > "$TEST_DIR/src/api/handler.ts" + +# Helper: run PreToolUse hook with an Edit tool input +run_pretooluse() { + local file_path="$1" + echo "{\"hook_event_name\": \"PreToolUse\", \"tool_name\": \"Edit\", \"tool_input\": {\"file_path\": \"$file_path\"}}" | \ + "$PLUGIN_DIR/scripts/pre-edit-check.sh" 2>/dev/null || true +} + +# ============================================================ +# Test 1: First injection produces full output +# ============================================================ + +export CLAUDE_SESSION_ID="test-session-first" +# Remove any stale dedup file +rm -f "${TMPDIR}/intent-layer-dedup-test-session-first" 2>/dev/null || true + +output=$(run_pretooluse "$TEST_DIR/src/api/handler.ts") + +if echo "$output" | grep -q "Pitfalls"; then + pass "First injection produces full output" +else + fail "First injection should include Pitfalls section, got: $output" +fi + +# ============================================================ +# Test 2: Same node within 5 min produces no output (deduped) +# ============================================================ + +output2=$(run_pretooluse "$TEST_DIR/src/api/handler.ts") + +if [[ -z "$output2" ]]; then + pass "Same node within 5 min is deduped (no output)" +else + fail "Should be silent on dedup, got: $output2" +fi + +# ============================================================ +# Test 3: Different session key produces separate output +# ============================================================ + +export CLAUDE_SESSION_ID="test-session-different" +rm -f "${TMPDIR}/intent-layer-dedup-test-session-different" 2>/dev/null || true + +output3=$(run_pretooluse "$TEST_DIR/src/api/handler.ts") + +if echo "$output3" | grep -q "Pitfalls"; then + pass "Different session key gets full injection" +else + fail "Different session should produce output, got: $output3" +fi + +# ============================================================ +# Test 4: Expired dedup entry (>5 min) triggers full injection +# ============================================================ + +export CLAUDE_SESSION_ID="test-session-expired" +DEDUP_FILE="${TMPDIR}/intent-layer-dedup-test-session-expired" +rm -f "$DEDUP_FILE" 2>/dev/null || true + +# Write a dedup entry with a timestamp 6 minutes ago +OLD_TS=$(( $(date +%s) - 360 )) +printf '%s\t%s\n' "$TEST_DIR/src/AGENTS.md" "$OLD_TS" > "$DEDUP_FILE" + +output4=$(run_pretooluse "$TEST_DIR/src/api/handler.ts") + +if echo "$output4" | grep -q "Pitfalls"; then + pass "Expired entry (>5 min) triggers full injection" +else + fail "Expired entry should allow injection, got: $output4" +fi + +# ============================================================ +# Test 5: Dedup file is created after first injection +# ============================================================ + +export CLAUDE_SESSION_ID="test-session-filecreated" +DEDUP_FILE="${TMPDIR}/intent-layer-dedup-test-session-filecreated" +rm -f "$DEDUP_FILE" 2>/dev/null || true + +run_pretooluse "$TEST_DIR/src/api/handler.ts" > /dev/null + +if [[ -f "$DEDUP_FILE" ]]; then + pass "Dedup file created after injection" +else + fail "Dedup file should exist at: $DEDUP_FILE" +fi + +# Verify it contains the node path and a timestamp +if grep -q "$TEST_DIR/src/AGENTS.md" "$DEDUP_FILE"; then + pass "Dedup file contains node path" +else + fail "Dedup file missing node path" +fi + +# ============================================================ +# Test 6: SessionStart cleanup removes stale dedup files +# ============================================================ + +# Create a fake old dedup file +OLD_DEDUP="${TMPDIR}/intent-layer-dedup-test-session-stale" +echo "some-node 1700000000" > "$OLD_DEDUP" +# Make it old (use touch with a past date) +touch -t 202301010000 "$OLD_DEDUP" 2>/dev/null || true + +# Run SessionStart hook +"$PLUGIN_DIR/scripts/inject-learnings.sh" < /dev/null > /dev/null 2>&1 || true + +if [[ ! -f "$OLD_DEDUP" ]]; then + pass "SessionStart cleanup removes stale dedup files" +else + fail "Stale dedup file should have been cleaned up" +fi + +# ============================================================ +# Test 7: Fallback to CLAUDE_PROJECT_DIR when no session ID +# ============================================================ + +unset CLAUDE_SESSION_ID +export CLAUDE_PROJECT_DIR="$TEST_DIR" +# Compute expected key +EXPECTED_KEY=$(printf '%s' "$TEST_DIR" | sed 's/[^A-Za-z0-9_-]/-/g') +DEDUP_FILE="${TMPDIR}/intent-layer-dedup-${EXPECTED_KEY}" +rm -f "$DEDUP_FILE" 2>/dev/null || true + +run_pretooluse "$TEST_DIR/src/api/handler.ts" > /dev/null + +if [[ -f "$DEDUP_FILE" ]]; then + pass "Fallback to CLAUDE_PROJECT_DIR creates dedup file" +else + fail "Should fallback to CLAUDE_PROJECT_DIR for dedup key" +fi + +# ============================================================ +# Summary +# ============================================================ +echo "" +echo "Results: $PASSED passed, $FAILED failed" + +if [[ "$FAILED" -gt 0 ]]; then + exit 1 +fi diff --git a/tests/test_stop_hook.sh b/tests/test_stop_hook.sh index c583cbd..705e8b2 100755 --- a/tests/test_stop_hook.sh +++ b/tests/test_stop_hook.sh @@ -130,8 +130,8 @@ fi # --- Tier 2 tests (with mock curl) --- -# Test 8: Haiku says should_capture: true → block -echo "Test 8: Haiku should_capture=true produces block" +# Test 8: Haiku says should_capture: true → stderr summary (non-blocking) +echo "Test 8: Haiku should_capture=true → non-blocking stderr summary" TEMP_PROJECT=$(mktemp -d) trap "rm -rf $TEMP_PROJECT" EXIT mkdir -p "$TEMP_PROJECT/.intent-layer/mistakes/pending" @@ -152,10 +152,11 @@ output=$(echo "{\"stop_hook_active\": false, \"transcript_path\": \"$TMPFILE\"}" "$STOP_HOOK" 2>&1 || true) rm -f "$TMPFILE" -if echo "$output" | jq -e '.decision == "block"' >/dev/null 2>&1; then - pass "Haiku true → block decision" +# Non-blocking: should write to stderr, not produce JSON block +if echo "$output" | grep -q "Intent Layer:"; then + pass "Haiku true → non-blocking stderr summary" else - fail "Should produce block decision: $output" + fail "Should produce stderr summary: $output" fi # Test 9: Haiku says should_capture: false → exit 0