- aqe memory/agent/task/team/pipeline CLI commands always failed with "Fleet not initialized": autoInitialize() built kernel+queen in its own CLIContext while the shared MCP handlers guard on the core-handlers fleet-state singleton. New adoptExternalFleet() bridges the CLI's components into that state (idempotent, never clobbers an existing fleet), restoring MCP-CLI parity. Verified E2E: store/get/delete green. - devcontainer: node_modules named-volume overlay + npm ci in postCreate so container installs Linux natives without touching the host's macOS binaries (takes effect on next rebuild; devcontainer users only) - docs/setup: drop stale ruflo@3.5.18 pins (CLAUDE.md quick setup, install-tools.sh) in favor of ruflo@3 + global `ruflo mcp start` - docs: add Fable 5 / ruflo-parity improvement plan (tracked in #520) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
17 KiB
Fable 5 / ruflo-Parity Improvement Plan (GOAP)
Date: 2026-06-10
Method: Goal-Oriented Action Planning (/goal-plan)
Source analysis: ruflo v3.10.27–v3.10.40 release review (ADR-147 nested subagents, Hermes tier-1 adoptions PR #2237, ruflo-arena PR #2315) + AQE codebase gap audit
Tracking: GitHub issue (see footer)
Goal
AQE platform exploits Fable 5 era capabilities at parity with ruflo where applicable: clean learning embeddings, prompt-cache savings, runaway-loop protection, nested-subagent readiness, deterministic adversarial orchestration, typed agent handoffs, and competitive test-strategy evolution.
Success criteria (goal state):
- No
<thinking>-contaminated embeddings written tomemory.dbafter the scrub ships - Second consecutive advisor/LLM call shows
cache_read_tokens > 0 - A command failing 5× consecutively is blocked by hooks with a recovery hint
- All
qe-*.mdagents declaretools:with a coordinator/leaf split; trajectories persistparent_agent_id+depth; probe script committed - At least one QCSD phase runs as a deterministic workflow with adversarial find→refute verification
- QE quality-gate outputs validate against published JSON schemas (
RiskDecision,CoverageGap,FindingVerdict) aqe arena runproduces a reproducible competitive array for test strategies (Phase 1)
Current State
| Capability | Status today | Evidence |
|---|---|---|
| Reasoning scrub | Absent | src/integrations/agentic-flow/reasoning-bank/experience-replay.ts embeds trajectories as-is (computeRealEmbedding(), ~L287) |
| Prompt caching | Flag dead | src/shared/llm/providers/claude.ts defines enableCache: true (~L41) but never sets cache_control |
| Tool-loop breaker | Domain-level only | src/coordination/circuit-breaker/domain-circuit-breaker.ts (ADR-064 Phase 2D); nothing at command level |
| Nested subagent plumbing | Absent | No tools: frontmatter in .claude/agents/v3/qe-*.md; no parentAgentId/depth in src/coordination/queen-types.ts or post-task hooks |
| Deterministic workflows | Absent | QCSD skills use flat Task-tool fan-out; no .claude/workflows/ |
| Typed verdict handoffs | Absent | Prose handoffs; ADR-075 covers framework types only |
| Competitive tournaments | Absent | No ADR/code coverage |
ADR Actions
| Improvement | ADR action | Status |
|---|---|---|
| 1. Reasoning-tag scrub | NEW ADR-099 — Reasoning-Tag Scrubbing for Pattern Embedding Sanitization | Proposed |
| 2. Prompt caching | UPDATE ADR-088 (Prompt Cache Latch Fields, Implemented 2026-04-02) — add ephemeral breakpoint injection section | Amend |
| 3. Tool-loop breaker | NEW ADR-100 — Tool-Loop Circuit Breaker for Hook Reliability | Proposed |
| 4. Nested subagents | NEW ADR-101 — Nested Subagent Hierarchy: Depth Limits, Privilege Model, Trajectory Provenance | Proposed |
| 5. QCSD workflows | NEW ADR-102 — Deterministic Workflow Orchestration with Adversarial Verification (relates to ADR-074 Loki Mode, Accepted) | Proposed |
| 6. Typed verdicts | NEW ADR-103 — Structured JSON-Schema Verdict Handoffs (relates to ADR-075, ADR-054) | Proposed |
| 7. qe-arena | NEW ADR-104 — Competitive Test-Strategy Tournaments (qe-arena Phase 1) | Proposed |
Highest existing ADR: 098. New ADRs follow docs/implementation/adrs/templates/ADR-TEMPLATE.md (WH(Y) statement, Options Considered, Dependencies, Governance, ECADR Definition of Done).
Plan (GOAP)
Goal: Fable 5 capability parity (7 criteria above)
Plan Cost: ~13–18 dev-days across 4 tiers
Execution order: [1 ∥ 2 ∥ 3] → 4 → 6 → 5 → 7
(6 before 5: workflow scripts consume the verdict schemas)
Improvement 1 — Reasoning-Tag Scrub Before Distillation (ADR-099) · Tier 1 · Cost S
Why now: Fable 5 emits far more extended thinking than prior models; every fleet run
dilutes memory.db pattern embeddings with reasoning-scratchpad text.
Steps
- Add
scrubReasoningBlocks(text)utility — strips<think>,<thinking>,<reasoning>,<REASONING_SCRATCHPAD>blocks; boundary-gated (prose mentioning the tags is left intact). Precondition: none. Effect: reusable sanitizer with unit tests. - Apply in
experience-replay.tsto trajectoryaction/resultfields before distillation andcomputeRealEmbedding(). Precondition: step 1. Effect: new embeddings clean. - Apply in
src/workers/workers/learning-consolidation.tsconsolidation path. Effect: consolidated patterns clean. - Unit tests: tagged trajectory → stored pattern contains no tag content; prose mention survives.
Integration points: ReasoningBank trajectory pipeline, post-task hook → recordFeedback path, memory.db qe_patterns writes. No schema migration. Existing rows untouched (data-protection rules apply — no rewrite of memory.db).
User verification (reproduction-first):
# CLI path: record a trajectory whose result embeds a thinking block
aqe hooks post-task --task-id scrub-test \
--result "$(printf '<thinking>secret scratchpad</thinking>real outcome')"
sqlite3 .agentic-qe/memory.db \
"SELECT content FROM qe_patterns ORDER BY rowid DESC LIMIT 1;"
# EXPECT: row contains "real outcome", does NOT contain "secret scratchpad"
MCP parity: same check via mcp__agentic-qe__memory_query on the latest pattern.
Improvement 2 — Wire Prompt Caching (ADR-088 update) · Tier 1 · Cost S
Steps
- In
claude.tsrequest builder: whenenableCache, sendsystemas a content-block array withcache_control: { type: "ephemeral" }on the final system block (system + trailing-message strategy, per ruflo #2237). Effect: ~90% discount on cached input tokens, 5-min TTL. - Surface
cache_creation_input_tokens/cache_read_input_tokensfrom the API response into the existing ADR-088 latch/usage metrics and ADR-042 token tracking. - Gate by provider — ephemeral breakpoints only on the Anthropic-native path; no-op for non-Anthropic providers (ADR-043/ADR-092 vendor independence).
- Tests: assert
cache_controlpresent in serialized request body when enabled, absent when disabled.
Integration points: src/shared/llm/providers/claude.ts, token tracking (ADR-042), routing_economics / routing_metrics MCP tools, aqe costs.
User verification:
# Two consecutive advisor calls within 5 minutes
aqe advisor consult --question "test strategy for checkout flow"
aqe advisor consult --question "test strategy for payment flow"
aqe costs # or: routing_metrics via MCP
# EXPECT: second call reports cache_read_tokens > 0 and lower input cost
MCP parity: mcp__agentic-qe__advisor_consult ×2 → mcp__agentic-qe__routing_metrics shows cache reads.
Improvement 3 — Tool-Loop Circuit Breaker (ADR-100) · Tier 1 · Cost M
Why now: Fable 5 is more persistent than prior models — runaway retry loops are more expensive, not less.
Steps
- New
tool-loop-guardrailmodule reusing the closed→open→half-open state machine fromdomain-circuit-breaker.ts, keyed by normalized command signature instead of domain. post-commandhook records(command, success);pre-commandhook consults the breaker: warn at 3, block at 5 consecutive failures of the same command, emitting a recovery hint ("same command failed 5×; change approach or inspect the error").- Advisory by default;
AQE_STRICT_TOOL_LOOP=1upgrades warn→block. Orthogonal to security guardrails. - Tests: 7 cases (below threshold, warn boundary, block boundary, reset on success, distinct commands independent, half-open recovery, env-var enforcement).
Integration points: hooks pre-command/post-command handlers, existing circuit-breaker module (reuse, don't fork), in-process state (no DB write per command).
User verification:
for i in 1 2 3 4 5; do
aqe hooks pre-command --command "npm run definitely-broken"
aqe hooks post-command --command "npm run definitely-broken" --success false
done
# EXPECT: iteration 3 prints a WARN with failure count; iteration 5 prints BLOCK + recovery hint
aqe hooks post-command --command "npm run definitely-broken" --success true
aqe hooks pre-command --command "npm run definitely-broken"
# EXPECT: breaker reset, command allowed
MCP parity: same sequence through the MCP hooks tool returns the same warn/block envelope.
Improvement 4 — Nested Subagent Readiness, depth=5 (ADR-101) · Tier 2 · Cost M–L
Why now: Anthropic announced nested subagent support (depth=5) on 2026-06-09. ruflo's
probe shows runtime plumbing exists but Task is stripped parent→child (upstream denylist).
Building now means AQE activates with zero code changes the day the gate lifts.
Steps
- Add
tools:frontmatter to all.claude/agents/v3/qe-*.md: coordinators (qe-queen-coordinator,qe-fleet-commander,qe-parallel-executor,qe-learning-coordinator) declareTask; leaf specialists explicitly do not (least-privilege boundary). Mirror onlyqe-*.mdchanges intoassets/agents/v3/(npm distribution rule — no non-QE agents there). - Extend trajectory recording:
parentAgentId?: string,depth?: numberonTaskExecution(src/coordination/queen-types.ts) and post-task hook flags--parent-agent-id/--depth(validated: identifier check, integer 0 ≤ d ≤ 32). Lands in the JSON metadata blob — no schema migration for stage 1. - Forward both fields through
recordFeedbackinto ReasoningBank so learning can segment patterns per hierarchy level. - Commit
scripts/probe-nested-spawn-depth.mjs(port of ruflo's probe): spawns a coordinator that recursively chains L1→L2→… until refusal; commit probe output underdocs/probes/. This is the regression test that announces when the upstream denylist lifts — re-run after everyclaude update. - Tests: propagation, omission, depth=0 boundary, invalid id rejection, negative/non-integer/>32 depth rejection (7 cases, mirroring ruflo's suite).
Integration points: .claude/agents/v3/, assets/agents/v3/, hooks post-task (CLI + MCP schema), ReasoningBank feedback, queen coordinator types.
User verification:
# Agents parse cleanly with new frontmatter
aqe health # no agent-load errors
node scripts/probe-nested-spawn-depth.mjs
# EXPECT today: "level=1 status=NO_AGENT_TOOL" (denylist active — documented, expected)
# EXPECT post-rollout: level≥2 — signal to activate follow-up phases
aqe hooks post-task --task-id nest-test --parent-agent-id qe-fleet-commander --depth 2
sqlite3 .agentic-qe/memory.db "SELECT ... ORDER BY rowid DESC LIMIT 1;"
# EXPECT: persisted entry contains parentAgentId=qe-fleet-commander, depth=2
MCP parity: hooks_post-task MCP input schema accepts both fields; same persistence check.
Improvement 5 — Deterministic Workflow Orchestration for QCSD (ADR-102) · Tier 3 · Cost L
Depends on: Improvement 6 (consumes verdict schemas).
Steps
- Create
.claude/workflows/with the first script:qcsd-development-review— dimensions → parallel finders → adversarial refuters per finding (N=3 skeptics prompted to refute; kill on majority refute) → synthesis. Findings/verdicts use ADR-103 schemas via theagent(…, {schema})option. - Update
qcsd-development-swarmSKILL.md:execution.primary: workflowwhere the harness supports it, keepingtask-toolas documented fallback (not all users run a Workflow-capable harness). - Wire ADR-074 Loki-mode escalation rules (blind review, sycophancy detection) as refuter prompt constraints.
- Baseline measurement: run old fan-out vs new workflow on the same fixture; record finding count, confirmed-finding count, false positives.
- Roll out to remaining QCSD phases (ideation/refinement/cicd/production) as follow-up once the development phase proves out.
Integration points: .claude/skills/qcsd-*, qe agents as agentType, ADR-074, ADR-103 schemas.
User verification:
# In Claude Code, on a fixture repo:
/qcsd-development-swarm
# EXPECT: workflow progress tree (Find → Verify → Synthesize phases visible);
# final report lists ONLY confirmed findings, each carrying refuter verdicts (e.g. 3/3 upheld);
# comparison note vs baseline shows reduced false positives
Improvement 6 — Structured Verdict Handoffs (ADR-103) · Tier 3 · Cost M
Steps
- New
src/contracts/verdicts.ts(typed + Zod/JSON Schema, versioned envelope):FindingVerdict {id, title, file, severity, confidence, evidence[], verdict, refutations[]},CoverageGap {file, range, riskScore, suggestedTests[]},RiskDecision {decision: approve|block|escalate, riskFactors[], confidence, rationale}. - Validate at MCP boundaries:
quality_assess,coverage_analyze_sublinear, quality-gate handlers emit schema-conformant payloads (validation at the boundary per project rules). - Export schemas for workflow
agent(…, {schema})use (improvement 5) — malformed agent output is auto-retried at the tool-call layer. - Contract tests: golden samples validate; mutated samples (missing severity, confidence > 1) rejected.
Integration points: ADR-075 type system (extend, don't fork), MCP handlers, QCSD workflows, A2A envelopes (ADR-054) unchanged — verdicts ride inside them.
User verification:
aqe analyze --quality-gate --json > verdict.json
npx ajv validate -s schemas/risk-decision.schema.json -d verdict.json
# EXPECT: "verdict.json valid"
MCP parity: mcp__agentic-qe__quality_assess response body validates against the same schema.
Improvement 7 — qe-arena: Competitive Test-Strategy Tournaments (ADR-104) · Tier 4 · Cost L
Why: QE has objective fitness functions (mutation kill rate, coverage delta, runtime) — a better fit for ruflo-arena's tournament model than almost any other domain.
Steps (Phase 1, self-contained — no core changes)
- Strategy = declarative test-generation config (framework, technique mix, edge-case emphasis, model tier). Seeded RNG; no
Date.now()/randomness in scoring paths — reproducible under--seed. - Arena engine: run N candidate strategies against a fixture project; fitness =
w1·mutationKillRate + w2·coverageDelta − w3·runtimePenalty(Stryker for mutation scoring via the existing mutation-testing skill). - Tournament → competitive array (pairwise fitness matrix); hill-climb evolution over strategy parameters.
- Persistence to
memory.dbvia existing memory layer (unified persistence ADR — no new SQLite file); winners feed qe-test-architect as learned priors. - Surface:
aqe arena run|tournament|listCLI +arena_run/tournament_runMCP tools (registered through the standard handler registry — avoid ruflo's unregistered-plugin-tools gap).
Integration points: mutation-testing skill, qe-test-architect, memory layer, optionally dream cycles (ADR-094) for offline evolution.
User verification:
aqe arena run --strategies 4 --target fixtures/demo-project --seed 42
# EXPECT: competitive array table (4×4 fitness matrix), ranked strategies,
# winner with mutation kill-rate and coverage numbers
aqe arena run --strategies 4 --target fixtures/demo-project --seed 42
# EXPECT: identical output (reproducibility)
MCP parity: arena_run with the same seed returns the same ranked result envelope.
Risk Factors (replan triggers)
| Risk | Affected | Mitigation |
|---|---|---|
Anthropic never lifts the Task denylist for nested spawns |
4 | All work is forward-compatible and independently useful (provenance fields help flat spawns today); probe script tells us when to proceed |
| Workflow harness not available in every user environment | 5 | Keep task-tool execution path as documented fallback in QCSD skills |
cache_control rejected by non-Anthropic gateways/proxies |
2 | Provider-gated; no-op elsewhere (ADR-092) |
| Mutation runs too slow for tournaments | 7 | Fixture-scoped Phase 1; sampled mutants; runtime penalty in fitness |
| Scrub regex too aggressive (eats legitimate prose) | 1 | Boundary-gated matching + prose-mention tests before merge |
| Schema changes break existing MCP consumers | 6 | Versioned envelope; additive fields only in v1 |
Fallback: if Tier 3 (5+6) proves too large in one pass, ship ADR-103 schemas alone — they are independently useful for MCP output validation — and defer workflow conversion.
Verification Gates (per project policy)
- Reproduction-first: each improvement closes only after its user-perspective command sequence above runs green on a real fixture project
- MCP–CLI parity: every CLI verification has an MCP twin, verified through the protocol server
- No batch-close: 7 improvements = 7 separate verification records on the tracking issue
npm run build+npm testgreen before any merge; smoke test before release
Tracking issue: see "Fable 5 / ruflo-parity improvement initiative" on proffesor-for-testing/agentic-qe.