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
14 changes: 14 additions & 0 deletions .okf/log.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions .okf/workflows/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
75 changes: 75 additions & 0 deletions .okf/workflows/ruflo-runtime.md
Original file line number Diff line number Diff line change
@@ -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 <key> -v "<desc>
Details: <path>"`), 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.
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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-<section>-<slug>` entry in ruflo memory namespace `okf` (backfilled 2026-08-22, one entry per concept; runtime map: `.okf/workflows/ruflo-runtime.md`).

---

Expand Down Expand Up @@ -84,7 +84,7 @@ Operational knowledge lives in `.okf/` (`build/`, `content/`, `design/`, `workfl
- **Feature/idea intake**: `/deliver <idea>` (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 `<main>`). 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.*`).
Expand Down
3 changes: 2 additions & 1 deletion STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.**

Expand Down
24 changes: 24 additions & 0 deletions bin/agent-bootstrap
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Loading