Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions claude/aqe-reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<!-- BEGIN ruflo-aqe-reference -->
<!-- ruflo-aqe-reference: merged into ~/.claude/CLAUDE.md ONLY when agentic-qe is installed.
Managed by install.sh / ruflo-reference-refresh — stripped automatically when `aqe` is
absent. Source of truth: claude/aqe-reference.md in the ruflo-machine-ref kit. -->

## Agentic-QE — operating guidance

> Applies when the standalone **agentic-qe** fleet is installed (`aqe` on PATH). This is the
> reusable subset of what `aqe init` would otherwise append to each project's `CLAUDE.md`;
> per-project specifics (enabled domains, worker config, the generation timestamp, local
> `.agentic-qe/` paths) are intentionally **not** here — `aqe init` writes those into the repo.

### Critical policies (apply whenever agentic-qe is in use)
- **Integrity (absolute):** no shortcuts, fake data, or false success claims; verify before
claiming done; use real DB queries in integration tests; run actual tests, don't assume.
- **Test execution:** never run `npm test` without `--run` (watch-mode hang risk) — use
`npm test -- --run`, or `npm run test:unit` / `test:integration` when available.
- **Data protection:** never `rm -f` `.agentic-qe/` or `*.db` without confirmation; back up
before destructive database operations.
- **Git:** never auto-commit/push without an explicit user request.

### Driving the AQE MCP
Tools are prefixed `mcp__agentic-qe__` (discover via `ToolSearch`). **`fleet_init` MUST be
called first**, e.g. `fleet_init({ topology:"hierarchical", maxAgents:15, memoryBackend:"hybrid" })`.

| Tool | Purpose |
|------|---------|
| `fleet_init` | Initialize the QE fleet (call first) · `fleet_status` for health |
| `test_generate_enhanced` | AI-powered test generation (`framework`, `strategy`) |
| `test_execute_parallel` | Parallel execution with retry |
| `coverage_analyze_sublinear` | O(log n) coverage analysis (`paths`, `threshold`) |
| `quality_assess` | Quality-gate evaluation |
| `task_orchestrate` | Multi-agent QE tasks across domains (`parallel:true`) |
| `memory_store` / `memory_query` | Patterns with `namespace` + `persist:true` (learning) |
| `security_scan_comprehensive` | SAST/DAST scanning |

### QE agents via the native Task tool
QE agents live under `.claude/agents/v3/` once `aqe init` has run in the repo:
```javascript
Task({ prompt: "Generate tests", subagent_type: "qe-test-architect", run_in_background: true })
Task({ prompt: "Find coverage gaps", subagent_type: "qe-coverage-specialist", run_in_background: true })
Task({ prompt: "Security audit", subagent_type: "qe-security-scanner", run_in_background: true })
```

<!-- END ruflo-aqe-reference -->
6 changes: 6 additions & 0 deletions claude/ruflo-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,12 @@ ruflo-setup-aqe --force # force reinitialize (aqe init --auto --upgrade

Opt-in only — `ruflo-setup-project` does NOT run it.

When agentic-qe **is** installed, the kit also merges a conditional **`ruflo-aqe-reference`**
block (AQE operating guidance — policies + MCP tool usage + QE-agent patterns) into this same
`~/.claude/CLAUDE.md`, just below this `ruflo-reference` block. It is added when `aqe` is on
PATH and **stripped automatically when agentic-qe is absent**. Source: `claude/aqe-reference.md`;
applied by `install.sh` and re-asserted by `ruflo-reference-refresh` / `ruflo-resync`.

### Security surface (verify + activate)

```bash
Expand Down
25 changes: 23 additions & 2 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -187,11 +187,12 @@ case ":$PATH:" in
esac
echo ""

# CLAUDE.md reference template
# CLAUDE.md reference template (+ the conditional agentic-qe sub-block template)
echo "## CLAUDE.md reference template -> $CFG_DIR/claude-md-template.md"
run "mkdir -p '$CFG_DIR'"
run "cp '$HERE/claude/ruflo-reference.md' '$CFG_DIR/claude-md-template.md'"
ok "template installed"
run "cp '$HERE/claude/aqe-reference.md' '$CFG_DIR/aqe-md-template.md'"
ok "templates installed (ruflo-reference + conditional aqe-reference)"
echo ""

# Shared helper lib — deployed to a stable absolute path so the standalone bin
Expand Down Expand Up @@ -224,6 +225,26 @@ else
fi
echo ""

# Conditional agentic-qe operating block: present in ~/.claude/CLAUDE.md ONLY when agentic-qe
# is installed; stripped otherwise (self-healing on uninstall). Idempotent.
echo "## ruflo-aqe-reference block (conditional on agentic-qe) -> $CLAUDE_MD"
AQE_BEGIN='<!-- BEGIN ruflo-aqe-reference -->'; AQE_END='<!-- END ruflo-aqe-reference -->'
if [ "$DRY" -eq 1 ]; then
if have aqe; then printf '%s[dry-run]%s upsert ruflo-aqe-reference block (aqe present)\n' "$C_DIM" "$C_RESET"
else printf '%s[dry-run]%s strip ruflo-aqe-reference block (aqe absent)\n' "$C_DIM" "$C_RESET"; fi
elif have aqe; then
_ruflo_block_upsert "$CLAUDE_MD" "$AQE_BEGIN" "$AQE_END" "$HERE/claude/aqe-reference.md" \
&& ok "agentic-qe present — merged ruflo-aqe-reference block" \
|| warn "could not merge ruflo-aqe-reference block (aqe-reference.md unreadable)"
else
if [ -f "$CLAUDE_MD" ] && grep -qF "$AQE_BEGIN" "$CLAUDE_MD"; then
_ruflo_block_strip "$CLAUDE_MD" "$AQE_BEGIN" "$AQE_END"; ok "agentic-qe absent — stripped stale ruflo-aqe-reference block"
else
dim "agentic-qe absent — no ruflo-aqe-reference block to manage"
fi
fi
echo ""

# Shell rc source line
if [ "$EDIT_RC" -eq 1 ]; then
echo "## shell functions"
Expand Down
40 changes: 36 additions & 4 deletions shell/ruflo-functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,25 @@ ruflo-neural-train() {
#
# ruflo-resync # re-apply learning + statusline (recommended after upgrade)
# ruflo-resync --aqe # also refresh agentic-qe skills in this repo
# Sync the conditional agentic-qe sub-block in ~/.claude/CLAUDE.md: present iff `aqe` is
# installed (upsert from the staged template), stripped otherwise (self-healing on uninstall).
# Quiet unless the block's presence actually changes. Needs ruflo-lib.sh (_ruflo_block_*).
_ruflo_sync_aqe_block() {
local ref="$HOME/.claude/CLAUDE.md"
local tmpl="$HOME/.config/ruflo/aqe-md-template.md"
local b='<!-- BEGIN ruflo-aqe-reference -->' e='<!-- END ruflo-aqe-reference -->'
command -v _ruflo_block_upsert >/dev/null 2>&1 || return 0
[ -f "$ref" ] || return 0
if command -v aqe >/dev/null 2>&1; then
[ -f "$tmpl" ] || return 0
grep -qF "$b" "$ref" || echo " + agentic-qe present → adding ruflo-aqe-reference block to $ref"
_ruflo_block_upsert "$ref" "$b" "$e" "$tmpl"
elif grep -qF "$b" "$ref" 2>/dev/null; then
echo " - agentic-qe absent → stripping stale ruflo-aqe-reference block from $ref"
_ruflo_block_strip "$ref" "$b" "$e"
fi
}

ruflo-resync() {
local do_aqe=0
[ "${1:-}" = "--aqe" ] && do_aqe=1
Expand All @@ -668,6 +687,9 @@ ruflo-resync() {
echo ""; echo "## 3/4 statusline (version + activation footer) for this project"
ruflo-fix-statusline-version

echo ""; echo "## machine-wide ~/.claude/CLAUDE.md: conditional agentic-qe reference block"
_ruflo_sync_aqe_block && echo "✓ ruflo-aqe-reference block in sync with agentic-qe install state"

if [ "$do_aqe" -eq 1 ]; then
echo ""; echo "## 4/4 refresh agentic-qe skills (--aqe)"
if [ -f .agentic-qe/memory.db ]; then
Expand Down Expand Up @@ -697,22 +719,31 @@ ruflo-reference-refresh() {
case "$1" in
--diff) mode="diff" ;;
--regenerate) mode="regenerate" ;;
--sync-aqe) mode="sync-aqe" ;;
-y|--yes) yes=1 ;;
-h|--help) echo "Usage: ruflo-reference-refresh [--diff|--regenerate [-y]]"; return 0 ;;
-h|--help) echo "Usage: ruflo-reference-refresh [--diff|--regenerate [-y]|--sync-aqe]"; return 0 ;;
*) echo "Unknown flag: $1"; return 2 ;;
esac
shift
done
# --sync-aqe only touches the conditional agentic-qe block; no ruflo template needed.
if [ "$mode" = "sync-aqe" ]; then _ruflo_sync_aqe_block; return 0; fi
if [ ! -f "$template" ]; then
echo "No template at $template (run install.sh, or extract from $ref)."
return 1
fi
local aqe_begin='<!-- BEGIN ruflo-aqe-reference -->'
case "$mode" in
status)
echo "ruflo: $(ruflo --version 2>/dev/null || echo 'not installed')"
echo "installed sentinel: $(grep -E 'ruflo-version' "$ref" 2>/dev/null || echo 'none')"
echo "template sentinel: $(grep -E 'ruflo-version' "$template" 2>/dev/null || echo 'none')"
echo "Use --diff to compare, --regenerate to rebuild."
if command -v aqe >/dev/null 2>&1; then
grep -qF "$aqe_begin" "$ref" 2>/dev/null && echo "agentic-qe: installed — aqe block present" || echo "agentic-qe: installed — aqe block MISSING (run --sync-aqe)"
else
grep -qF "$aqe_begin" "$ref" 2>/dev/null && echo "agentic-qe: absent — aqe block STALE (run --sync-aqe to strip)" || echo "agentic-qe: absent — aqe block correctly absent"
fi
echo "Use --diff to compare, --regenerate to rebuild, --sync-aqe to fix the agentic-qe block."
;;
diff)
local blk; blk=$(mktemp)
Expand All @@ -721,13 +752,13 @@ ruflo-reference-refresh() {
rm -f "$blk"
;;
regenerate)
if [ ! -f "$ref" ]; then cp "$template" "$ref"; echo "✓ Installed reference at $ref"; return 0; fi
if [ ! -f "$ref" ]; then cp "$template" "$ref"; echo "✓ Installed reference at $ref"; _ruflo_sync_aqe_block; return 0; fi
local pre post new
pre=$(mktemp); post=$(mktemp); new=$(mktemp)
awk '/<!-- BEGIN ruflo-reference -->/{exit} {print}' "$ref" > "$pre"
awk 'f; /<!-- END ruflo-reference -->/{f=1}' "$ref" > "$post"
cat "$pre" "$template" "$post" > "$new"
if diff -q "$ref" "$new" >/dev/null 2>&1; then echo "✓ Already up-to-date."; rm -f "$pre" "$post" "$new"; return 0; fi
if diff -q "$ref" "$new" >/dev/null 2>&1; then echo "✓ Already up-to-date."; rm -f "$pre" "$post" "$new"; _ruflo_sync_aqe_block; return 0; fi
diff -u "$ref" "$new" | head -80
if [ "$yes" -eq 0 ]; then
printf "Apply this regeneration? [y/N] "; local r; read -r r
Expand All @@ -736,6 +767,7 @@ ruflo-reference-refresh() {
cp "$ref" "$ref.bak.$(date +%Y%m%d-%H%M%S)"
mv "$new" "$ref"; rm -f "$pre" "$post"
echo "✓ Regenerated $ref (backup saved)"
_ruflo_sync_aqe_block
;;
esac
}
40 changes: 40 additions & 0 deletions shell/ruflo-lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,44 @@ _ruflo_bsq3_install() {
( cd "$1" && npm install "better-sqlite3@${2:-^12}" --no-save --no-audit --no-fund >/dev/null 2>&1 )
}

# --- sentinel-delimited block management (CLAUDE.md sub-blocks) -------------
# Manage a `<!-- BEGIN x -->`…`<!-- END x -->` block in a file. Used for the
# conditional ruflo-aqe-reference block in ~/.claude/CLAUDE.md (present only when
# agentic-qe is installed). Idempotent; preserves everything outside the markers.
# Markers are matched as fixed substrings (awk index()).

# _ruflo_block_upsert FILE BEGIN END SRC — replace the BEGIN..END block in FILE with
# the contents of SRC (which must itself contain the markers); append if the block is
# absent; create FILE from SRC if FILE is missing. Returns 1 if SRC is unreadable.
_ruflo_block_upsert() {
local file="$1" begin="$2" end="$3" src="$4"
[ -f "$src" ] || return 1
mkdir -p "$(dirname "$file")" 2>/dev/null
if [ ! -f "$file" ]; then cat "$src" > "$file"; return 0; fi
if grep -qF "$begin" "$file"; then
local pre post new; pre=$(mktemp); post=$(mktemp); new=$(mktemp)
awk -v b="$begin" 'index($0,b){exit} {print}' "$file" > "$pre"
awk -v e="$end" 'f; index($0,e){f=1}' "$file" > "$post"
cat "$pre" "$src" "$post" > "$new"
cat "$new" > "$file"; rm -f "$pre" "$post" "$new"
else
{ printf '\n'; cat "$src"; } >> "$file"
fi
}

# _ruflo_block_strip FILE BEGIN END — remove the BEGIN..END block (inclusive) from
# FILE. No-op if FILE or the block is absent.
_ruflo_block_strip() {
local file="$1" begin="$2" end="$3"
[ -f "$file" ] || return 0
grep -qF "$begin" "$file" || return 0
local new; new=$(mktemp)
awk -v b="$begin" -v e="$end" '
index($0,b){skip=1}
!skip{print}
index($0,e){skip=0}
' "$file" > "$new"
cat "$new" > "$file"; rm -f "$new"
}

_RUFLO_LIB=1 # sentinel: consumers check this to confirm the lib loaded
19 changes: 10 additions & 9 deletions uninstall.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
#
# By default removes ONLY the kit's own footprint:
# - every helper this repo ships in bin/ from ~/.local/bin/ (derived from bin/)
# - ~/.config/ruflo/claude-md-template.md
# - the BEGIN/END ruflo-reference block from ~/.claude/CLAUDE.md (content
# outside the sentinels is preserved)
# - ~/.config/ruflo/{claude-md-template,aqe-md-template}.md
# - the BEGIN/END ruflo-reference AND ruflo-aqe-reference blocks from
# ~/.claude/CLAUDE.md (content outside the sentinels is preserved)
# - the source line from ~/.zshrc / ~/.bashrc
#
# Leaves your ruflo install, memory DBs, and project files untouched. Per-project
Expand Down Expand Up @@ -86,23 +86,24 @@ for src in "$HERE"/bin/*; do
[ -f "$f" ] && { run "rm -f '$f'"; ok "removed $f"; }
done

# 2. template
# 2. templates (ruflo-reference + conditional agentic-qe block)
[ -f "$HOME/.config/ruflo/claude-md-template.md" ] && { run "rm -f '$HOME/.config/ruflo/claude-md-template.md'"; ok "removed template"; }
[ -f "$HOME/.config/ruflo/aqe-md-template.md" ] && { run "rm -f '$HOME/.config/ruflo/aqe-md-template.md'"; ok "removed agentic-qe template"; }

# 2b. shared helper lib (already sourced at the top, so removing it here is safe)
[ -f "$HOME/.config/ruflo/ruflo-lib.sh" ] && { run "rm -f '$HOME/.config/ruflo/ruflo-lib.sh'"; ok "removed helper lib"; }

# 3. CLAUDE.md managed block
# 3. CLAUDE.md managed blocks (ruflo-reference + the conditional ruflo-aqe-reference)
CLAUDE_MD="$HOME/.claude/CLAUDE.md"
if [ -f "$CLAUDE_MD" ] && grep -q '<!-- BEGIN ruflo-reference -->' "$CLAUDE_MD"; then
if [ -f "$CLAUDE_MD" ] && grep -qE '<!-- BEGIN ruflo-(reference|aqe-reference) -->' "$CLAUDE_MD"; then
if [ "$DRY" -eq 1 ]; then
printf '%s[dry-run]%s strip ruflo-reference block from %s\n' "$C_DIM" "$C_RESET" "$CLAUDE_MD"
printf '%s[dry-run]%s strip ruflo-reference + ruflo-aqe-reference blocks from %s\n' "$C_DIM" "$C_RESET" "$CLAUDE_MD"
else
cp "$CLAUDE_MD" "$CLAUDE_MD.bak.$(date +%Y%m%d-%H%M%S)"
new=$(mktemp)
awk '/<!-- BEGIN ruflo-reference -->/{skip=1} /<!-- END ruflo-reference -->/{skip=0; next} !skip' "$CLAUDE_MD" > "$new"
awk '/<!-- BEGIN ruflo-reference -->/{skip=1} /<!-- BEGIN ruflo-aqe-reference -->/{skip=1} /<!-- END ruflo-reference -->/{skip=0; next} /<!-- END ruflo-aqe-reference -->/{skip=0; next} !skip' "$CLAUDE_MD" > "$new"
mv "$new" "$CLAUDE_MD"
ok "stripped ruflo-reference block (backup saved; rest of file preserved)"
ok "stripped ruflo-reference + ruflo-aqe-reference blocks (backup saved; rest of file preserved)"
fi
fi

Expand Down