diff --git a/.okf/log.md b/.okf/log.md index 6b04a1009..445c4da41 100644 --- a/.okf/log.md +++ b/.okf/log.md @@ -111,6 +111,20 @@ Also corrected: the ~1e-6 noise figure in test-gates and in the code comment was macOS-local and read as universal. Same overclaim shape the #566 reviewer caught one layer down. +## 2026-08-22 - ruflo self-learning enabled, memory unified, OKF backfilled + +Two silent failure modes closed: fresh worktrees had dead learning hooks +(`.claude/helpers/` is gitignored; every settings.json hook no-opped behind +`|| true` - stats sat at zero for months) and a private `.swarm` memory DB +that died with the worktree. `bin/agent-bootstrap` now self-heals both at +SessionStart: `init upgrade` when the handler is missing, and a `.swarm` +symlink to the main checkout so every session shares ONE memory store. +The OKF bundle was backfilled into ruflo memory (namespace `okf`, one entry +per concept + pointer) with a sync rule, and the first distill run mined 660 +reasoning patterns / 650 causal edges (44 promoted) from the main agentdb. +Full runtime map incl. the v3.6.30 CLI bugs: +[ruflo-runtime](workflows/ruflo-runtime.md). + ## 2026-08-22 - STATUS.md round two: the surface broke its own rule on commit one A clean-context peer reviewer (second, independent 4-eyes pass after the diff --git a/.okf/workflows/index.md b/.okf/workflows/index.md index 97fbbdf6b..7616e3ade 100644 --- a/.okf/workflows/index.md +++ b/.okf/workflows/index.md @@ -12,3 +12,4 @@ * Test suites, rake tasks, and the visual-regression gate live in [test-gates](/build/test-gates.md) (`workflows/testing.md` was squashed into it 2026-08-20 - it duplicated the gate rules and still carried the superseded "run both suites per commit" instruction) * [Analytics Access](analytics-access.md) - live GA4 + Search Console MCP servers, correct property IDs, credential split, data-lag traps, and why GA4 sessions must be reconciled against GSC clicks before being quoted * [Outbound Sprint Machinery](outbound-sprint.md) - 2607 browser-agent send/monitor loop, pipeline ledger, board conventions, mail-routing gotchas +* [Ruflo runtime](ruflo-runtime.md) - agent-bootstrap self-heals the gitignored scaffolding, worktrees share the main .swarm memory via symlink, the okf memory namespace mirrors this bundle, and the v3.6.30 CLI bugs not to re-fight diff --git a/.okf/workflows/ruflo-runtime.md b/.okf/workflows/ruflo-runtime.md new file mode 100644 index 000000000..4ca0d5584 --- /dev/null +++ b/.okf/workflows/ruflo-runtime.md @@ -0,0 +1,75 @@ +--- +type: Playbook +title: Ruflo runtime - self-heal, shared memory, and the learning loop +description: How ruflo (claude-flow) runs in this repo - bin/agent-bootstrap self-heals the gitignored scaffolding, worktrees symlink .swarm to the main checkout so memory is shared, and the okf memory namespace mirrors the OKF bundle one entry per concept. +tags: [ruflo, claude-flow, memory, hooks, learning] +generated: + by: claude-fable/5 + at: 2026-08-22T00:00:00Z +timestamp: 2026-08-22T00:00:00Z +--- + +Ruflo = `@claude-flow/cli` (same codebase, two npm names). The repo commits NO +ruflo artifacts - `.claude/helpers/`, `.swarm/`, `.claude-flow/`, and +`claude-flow.config.json` are all gitignored scaffolding. That design created +two silent failure modes, both closed 2026-08-22 by a self-heal block in +`bin/agent-bootstrap` (the SessionStart hook): + +1. **Dead hooks**: every `.claude/settings.json` hook calls + `.claude/helpers/hook-handler.cjs` with `|| true`. In a fresh + worktree/checkout the helper does not exist, so the whole learning pipeline + no-ops silently (intelligence stats sat at zero for months). The bootstrap + now runs `npx @claude-flow/cli@latest init upgrade` whenever the handler is + missing - `init upgrade` regenerates helpers while preserving data and + never touches tracked files. +2. **Doomed worktree memory**: `.swarm/` is cwd-relative, so a worktree + session wrote to a private DB that died with the worktree. The bootstrap + now symlinks a worktree's `.swarm` to the main checkout's (only when + `.swarm` does not already exist), so every session - CLI and MCP tools - + reads and writes the ONE shared store. + +# The okf memory namespace mirrors this bundle + +Backfilled 2026-08-22: namespace `okf` holds one entry per OKF concept — all +39 concepts across all six sections, plus two log-derived lessons and the +backfill marker. Key prefixes abbreviate the section: `okf-build-`, +`okf-content-`, `okf-wf-` (workflows), `okf-design-`, `okf-arch-` +(architecture), `okf-cs-` (content-strategy), `okf-log-`. Each entry is a +distilled fact plus a pointer to its `.okf/` file; semantic recall routes a +session to the right concept, the file stays canon. **Sync rule: a commit +that changes a concept's title/description also upserts its `okf-*` entry** +(`npx @claude-flow/cli@latest memory store -n okf -k -v " +Details: "`), or the namespace drifts from the bundle. The mirror lives +in the gitignored `.swarm/` store, so a fresh MACHINE (not worktree) starts +with an empty namespace — regenerate by re-running the backfill: one store +per concept from its frontmatter title/description, exactly as above. + +# The learning loop, and where each piece lives + +- `memory.db` - KV + vector store (memory_store/search; 384-dim ONNX + embeddings). `agentdb-memory.db` - the learning store (reasoning_patterns, + episodes, causal_edges, skills), fed by the in-session memory bridge. +- `memory distill run --db .swarm/agentdb-memory.db` mines agentdb entries + into reasoning patterns (first run 2026-08-22: 660 patterns, 650 causal + edges, 44 promoted). Plain `memory distill run` targets `memory.db`, which + by design has no pattern tables - the skip message "agentdb schema not + initialised" means you pointed it at the wrong DB, not that init is needed. +- 12 background workers exist (`hooks worker list`); the daemon runs them. + +# CLI bugs observed 2026-08-22 (ruflo v3.38.16) - do not re-fight these + +The bootstrap installs `@latest`, so no pin can hold - these are dated +observations, not version guarantees; re-measure before assuming one is fixed +or still present. + +- `config init` generates a config the loader rejects ("reading 'map'" + warning on every call). Run on defaults; delete any generated config. +- `memory export` fails ("Exported to undefined"); `memory_import_claude` + finds 0 files even with `allProjects: true` (path-encoding). The auto-memory + corpus is deliberately NOT mirrored into ruflo - `MEMORY.md` already loads + every session. +- CLI `memory search --type semantic` returns empty in terminals (needs + @ruvector/core); single-term `--type keyword` works; real semantic search is + MCP-only. (Also in CLAUDE.md research protocol.) +- `CLAUDE_FLOW_DB_PATH` redirects store/list/search/retrieve but NOT + backup/init (cwd-resolved) - superseded by the symlink for normal use. diff --git a/CLAUDE.md b/CLAUDE.md index 89f9d10d3..0b4be9d3e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -40,7 +40,7 @@ Operational knowledge lives in `.okf/` (`build/`, `content/`, `design/`, `workflows/` — one concept per file). Consume via progressive disclosure: `/okf:okf` (consume) at session start; never hand-read or hand-edit the bundle format — the skills carry the spec. Validate with `/okf:validate .okf --strict` before committing bundle changes. -**Maintain as you work (ENFORCED)**: a durable learning updates its concept + section index + a dated `.okf/log.md` entry, riding the SAME commit as the change — dispatch a background okf-maintainer in parallel, or inline for tiny fixes; a weekly maintain pass back-fills misses. A session that shipped durable knowledge without an OKF entry is not done. +**Maintain as you work (ENFORCED)**: a durable learning updates its concept + section index + a dated `.okf/log.md` entry, riding the SAME commit as the change — dispatch a background okf-maintainer in parallel, or inline for tiny fixes; a weekly maintain pass back-fills misses. A session that shipped durable knowledge without an OKF entry is not done. **Ruflo mirror**: a concept title/description change also upserts its `okf-
-` entry in ruflo memory namespace `okf` (backfilled 2026-08-22, one entry per concept; runtime map: `.okf/workflows/ruflo-runtime.md`). --- @@ -84,7 +84,7 @@ Operational knowledge lives in `.okf/` (`build/`, `content/`, `design/`, `workfl - **Feature/idea intake**: `/deliver ` (from the `jt-delivery` plugin) — triage → GOAL → author≠verifier orchestration per the `jt-delivery:contract` skill §1a; repo-specific bindings (gates, canon, reviewer routing): `docs/workflows/autonomous-delivery-prompt.md`. - **Manager triage (Paul 2026-08-01)**: Paul adds requests mid-flight; triage each against the active plan — now / sequenced / backlog / groom-first — and report the verdict in one line so he can override. Deferring is a decision; interrupting a gated pipeline for a non-critical request is the failure. **Autonomy grant**: handle sprints end-to-end; for big/critical calls AND any highly OPINIONATED question (design taste, naming, strategy trade-offs — anywhere reasonable people disagree) run a voting panel of subagents with DISTINCT PERSONAS/lenses and organize an explicit vote (Paul 2026-08-21); make the call (split + irreversible → hold for Paul). Record every autonomous call with its evidence. Paul's explicit words override any panel. - **Agent 4-eyes on EVERY stage, author ≠ verifier (Paul 2026-08-20, widened 2026-08-21)**: every change is written by one agent and verified by a different one; review lands BEFORE the artifact leaves the workshop (plan before Paul sees it, diff before commit, finding before reported, measurement before quoted). Brief reviewers with goal + artifact, never conclusions; ask for measurements, not verdicts. Internal sub-agents per stage — **model routing (Paul 2026-08-21): critical decisions, editing/outlining AND design critique on fable; coding, code review AND content writing on opus; mechanical/simple tasks on sonnet; spawns never inherit the session model implicitly — pass `model` on every Agent call**; `/codex:review` once at the merge gate for user-facing changes. Full protocol: `jt-delivery:contract` skill §5; repo routing: `docs/workflows/autonomous-delivery-prompt.md`. (Evidence: 2026-08-20/21 — reviewers caught a CSS-breaking defect, a fabricated quote, and 11 findings on the delivery prompt itself, all after author self-review.) -- **Async-first (MANDATORY)**: written, discoverable artifacts for every decision, finding, and handoff; sync is the exception, written back same-day. A task is not done until a cold session can read its state with zero questions. Canonical surfaces: `.agents/skills/async-first-communication/SKILL.md`; same SOP in `AGENTS.md`. **Cold-start surface: `STATUS.md` at repo root** — a session that changed what's in flight (started/finished/parked a workstream, shipped a PR, hit a blocker) without updating `STATUS.md` in the same commit/PR is not done. +- **Async-first (MANDATORY)**: written, discoverable artifacts for every decision, finding, and handoff; sync is the exception, written back same-day. A task is not done until a cold session can read its state with zero questions. Canonical surfaces: `.agents/skills/async-first-communication/SKILL.md`; same SOP in `AGENTS.md`. **Cold-start surface: `STATUS.md` at repo root** — a session that changed what's in flight (started/finished/parked a workstream, shipped a PR that changes a workstream's state, hit a blocker) without updating `STATUS.md` in the same commit/PR is not done. - **Company facts have a canon**: check `.okf/content/claims-canon.md` before publishing any number (founding 2008-09-01; tenure from `site.Params.foundingYear`; "4.8/5 on Clutch" linked, NO review count; founder 22+ vs company 18+). A number with no in-repo source is a defect. Correcting one means sweeping the instruction layer too — `PRODUCT.md`, `docs/business/`, outreach kits have re-introduced bad canon before (4 of 8 published figures were wrong on 2026-08-14). - **Text ratchets read RENDERED output, not source**: `marketing_copy_test` globs source and missed three rendered-only defects on 2026-08-14 (unglobbed partial, line-wrapped banned phrase, composed nested `
`). Queued: `docs/20-29-testing-qa/20.10` §3b P0-4. - **Zero**: generic AI language · unsupported claims · Hugo build breaks (`bin/hugo-build` validates) · ad hoc test scripts (header Test line commands only) · Python for analysis (use `rg`/`sed`/`awk`) · duplicate files (`*_new.*`, `*_backup.*`). diff --git a/STATUS.md b/STATUS.md index ca1205204..78fce6085 100644 --- a/STATUS.md +++ b/STATUS.md @@ -3,7 +3,8 @@ > Cold-start surface. One screen: goals, WIP, blockers. Links carry the detail — > this file never duplicates project state, it points at it. > **Update rule**: any session that changes what's in flight (starts/finishes/parks -> a workstream, ships a PR, hits a blocker) updates this file in the same commit/PR. +> a workstream, ships a PR that changes a workstream's state, hits a blocker) +> updates this file in the same commit/PR. > **When updating: verify against the artifact (the ledger, the file, the PR), never > a tracker line — trackers rot, and this file must not inherit their staleness.** diff --git a/bin/agent-bootstrap b/bin/agent-bootstrap index 55aecb74d..0a489b14b 100755 --- a/bin/agent-bootstrap +++ b/bin/agent-bootstrap @@ -21,6 +21,30 @@ bundle install --quiet || log "WARN bundle install failed - Ruby tests/validator log "bun install" bun install --frozen-lockfile >/dev/null 2>&1 || log "WARN bun install failed - PostCSS/lint unavailable" +# Ruflo (claude-flow) runtime self-heal. .claude/helpers/ and .swarm/ are +# gitignored scaffolding, so in a fresh worktree the settings.json hooks call a +# missing handler (silent no-op) and memory writes land in a DB that dies with +# the worktree. Skipped in CI: no MCP session there to feed. +if [ -z "${CI:-}" ]; then + log "ruflo runtime" + GIT_COMMON="$(git rev-parse --path-format=absolute --git-common-dir 2>/dev/null)" + MAIN_ROOT="${GIT_COMMON%/.git}" + if [ -n "$MAIN_ROOT" ] && [ "$MAIN_ROOT" != "$PWD" ] && [ -d "$MAIN_ROOT/.swarm" ] && [ ! -e .swarm ]; then + # -sfn also heals a DANGLING .swarm symlink (main checkout moved/renamed): + # -e follows links, so a dangling one enters this branch and gets replaced. + ln -sfn "$MAIN_ROOT/.swarm" .swarm && log " .swarm -> shared main-checkout memory DB" \ + || log "WARN .swarm symlink failed - ruflo memory will die with this worktree" + fi + if [ ! -f .claude/helpers/hook-handler.cjs ]; then + npx @claude-flow/cli@latest init upgrade >/dev/null 2>&1 + if [ -f .claude/helpers/hook-handler.cjs ]; then + log " helpers regenerated (init upgrade)" + else + log "WARN ruflo init upgrade did not produce hook-handler.cjs - learning hooks will silently no-op" + fi + fi +fi + # libvips runtime for screenshot diffs (Debian/Ubuntu containers) if ! ruby -e 'require "vips"' >/dev/null 2>&1 && type apt-get >/dev/null 2>&1; then log "installing libvips42"