Skip to content

v0.5.1 — Lifecycle Hooks and Context Engineering Protocols

Choose a tag to compare

@timeleft-- timeleft-- released this 10 Mar 19:43
· 246 commits to main since this release
Immutable release. Only release title and notes can be modified.
4607734

Release v0.5.1 — Lifecycle Hooks and Context Engineering Protocols

Why

Agent memory accumulates noise — across sessions, across team members, across workstreams. Retrieval degrades as memory grows because the memory system has no opinion about quality, freshness, or relevance. v0.5 adds a typed hook system that lets you program lifecycle policy — validate writes, compress on promote, rerank on recall — and three reference protocols adapted from published research.

What you can do now

  • Gate writes — reject malformed or low-quality thoughts before they enter memory
  • Compress on promote — extractively compress verbose thoughts when they become permanent records
  • Rerank retrieval — reorder recall results based on playbook rules that evolve over time
  • Track parallel work — validate mapper outputs, monitor batch progress, get "REDUCE READY" signals
  • Observe everything — hooks return structured hook_feedback in every MCP response

Which protocol should I use?

Problem Protocol Research Module
Retrieval quality degrades as memory grows ACE Stanford, UC Berkeley, and SambaNova, ICLR 2026 fava_trails.protocols.ace
Promoted thoughts are too verbose, diluting recall SECOM Tsinghua University and Microsoft, ICLR 2025 fava_trails.protocols.secom
Parallel workers need validated, crash-safe handoffs RLM MIT fava_trails.protocols.rlm

Quick start

pip install fava-trails
# or
uv add fava-trails

Full CLI for project setup and data repo management

FAVA Trails CLI is a control plane for project initialization, data repo management, diagnostics, thought retrieval, and protocol configuration.

# Project setup
fava-trails init                 # Creates .fava-trails.yaml and .env in current directory

# Data repo management
fava-trails bootstrap            # Create a new data repo from scratch
fava-trails clone <remote-url>   # Clone an existing data repo from remote

# Diagnostics and scope management
fava-trails doctor               # Validate: Jujutsu, data repo, OpenRouter key, config
fava-trails scope set <scope>    # Set current scope
fava-trails scope list           # Show all available scopes

# Thought retrieval
fava-trails get --list <scope> --query "pattern"      # List thoughts matching query
fava-trails get <thought-id> --with-frontmatter       # Retrieve full thought + metadata
fava-trails get --exists <scope>/<thought-id>         # Check if thought exists

# Install dependencies
fava-trails install-jj           # Download and install Jujutsu binary

Protocol configuration

Pick a protocol and let the CLI handle the rest:

fava-trails ace setup --write    # Adds ACE hooks to config.yaml, commits via jj
fava-trails secom setup --write  # Adds SECOM hooks, commits via jj
fava-trails rlm setup --write    # Adds RLM hooks, commits via jj

Each command is idempotent (safe to run twice), validates the data repo, and commits the config change so it's versioned and rollback-safe. Run without --write to preview the YAML.

For SECOM, pre-download the compression model:

fava-trails secom warmup

Configure LLM provider (OpenRouter by default):

The Trust Gate and any hooks that invoke LLM models need an API key. Configure in config.yaml:

openrouter_api_key_env: "OPENROUTER_API_KEY"  # environment variable name
trust_gate_model: "google/gemini-2.5-flash"   # model for Trust Gate review

Set the environment variable:

export OPENROUTER_API_KEY="your-openrouter-key"

OpenRouter provides unified access to 300–500+ models from 60+ providers including Anthropic, OpenAI, Google, Qwen, Deepseek, and others. Future versions support additional LLM providers.

What's new in detail

Lifecycle Hooks — Event-Action Pipeline

Seven event classes powering eight lifecycle points, with a typed action vocabulary. Hooks return explicit actions instead of booleans.

Events:
BeforeSaveEvent · AfterSaveEvent · BeforeProposeEvent · AfterProposeEvent · AfterSupersedeEvent · OnRecallEvent · OnStartupEvent

Lifecycle points: before_save · after_save · before_propose · after_propose · after_supersede · on_recall · on_recall_mix · on_startup

on_recall_mix reuses OnRecallEvent with lifecycle_point="on_recall_mix" — fires after merging results from cross-trail searches so hooks can rerank the full merged set.

Actions:
Proceed · Reject(reason) · Mutate(ThoughtPatch) · Redirect · Warn · Advise · Annotate · RecallSelect

Execution model:

  • before_* and on_recall run synchronously. Output returned as hook_feedback in MCP response.
  • after_* hooks run inline on the caller's asyncio task. At-most-once delivery. Feedback is accessible in the MCP response via hook_feedback.
  • Hooks are read-only. They can gate writes, rerank recall, mutate payloads in-flight, and advise. They cannot call save_thought, supersede, or propose_truth.
  • RecallSelect can subset/rerank recall results. Cannot inject thoughts absent from the original result set.
  • Loaded once at startup from config.yaml. Never re-read at runtime.
  • TrailContext provides lazy read-only access to trail stats and recall (bypasses hooks, capped at 50 results).

Example hook_feedback in an MCP response:

{
  "hook_feedback": {
    "accepted": true,
    "annotations": {
      "rlm_batch_id": "b001",
      "rlm_mapper_id": "chunk-3",
      "rlm_batch_count": 3,
      "rlm_expected_mappers": 5,
      "rlm_reduce_ready": false
    },
    "advice": [
      {"message": "Mapper 'chunk-3' saved for batch 'b001'. Progress: 3/5 mappers reported.", "code": "rlm_mapper_progress"}
    ]
  }
}

Protocol: fava_trails.protocols.ace

Adapted from ACE: Agentic Context Engineering (Stanford, UC Berkeley, and SambaNova, ICLR 2026)

Playbook-driven recall reranking and quality enforcement. Finalized decisions rise above stale drafts. Rules evolve through correction telemetry.

  • on_startup: Lazy playbook cache init
  • on_recall: RecallSelect reranking — playbook rules score each result, reorder by relevance
  • on_recall_mix: Same reranking applied to cross-trail merged results (multi-scope searches)
  • before_save: Anti-pattern warnings + brevity advisories
  • after_save: Cache invalidation + reflector telemetry (5-min TTL fallback)
  • after_supersede: Correction telemetry — captures what was wrong and what replaced it

Implements the curation infrastructure. Reasoning and reflection stay application-layer.

Protocol: fava_trails.protocols.secom

Adapted from SECOM (Tsinghua University and Microsoft, ICLR 2025)

Extractive compression at promote time. Compress once, benefit on every subsequent read.

  • before_propose: Inline compression via Mutate(ThoughtPatch) — only original tokens survive
  • before_save: Verbosity advisory
  • on_recall: Density-aware RecallSelect boosting compressed thoughts

Original text preserved in version history.

Compression engine: LLMLingua-2 (178M-parameter token classifier). Install with pip install fava-trails[secom].

Protocol: fava_trails.protocols.rlm

Adapted from Recursive Language Models (MIT) and Anthropic multi-agent patterns

Mapper validation, batch tracking, deterministic reducer ordering. Every mapper output is a crash-safe atomic commit.

  • before_save: Validates mapper outputs (requires mapper_id, rejects malformed)
  • after_save: Per-batch distinct mapper counting, "REDUCE READY" advisory at quorum
  • on_recall: Deterministic mapper_id ordering via RecallSelect
  • on_recall_mix: Same deterministic sort for cross-trail merged results (distributed MapReduce)

fail_mode: closed. The advisory counter is advisory — reducer must verify via recall().

Native LLM Client

Unified LLM invocation for hooks that need model inference (e.g. Trust Gate review, ACE playbook scoring, SECOM compression).

Multi-provider support via any-llm-sdk:

  • Primary (default): OpenRouter — access 300–500+ models from 60+ providers including Anthropic, OpenAI, Google, Qwen, and others through a single API. Configure via OPENROUTER_API_KEY environment variable in config.yaml.
  • Extensible: any-llm-sdk supports additional providers (Anthropic, OpenAI, Bedrock, etc.). Future versions can add provider selection to config.yaml for seamless switching.

Built-in reliability: Exponential backoff with jitter on rate limits and transient failures. Configurable model aliases for version pinning and fallbacks. Unified exception hierarchy across all providers.

Trust Gate (built-in LLM verification layer): Every promoted thought passes through an independent LLM reviewer before entering shared memory. Configurable model and timeout in config.yaml; defaults to google/gemini-2.5-flash via OpenRouter.

What's Changed

  • chore: add agent guardrails and semantic PR check by @timeleft-- in #9
  • feat: Replace OpenAI SDK with any-llm-sdk by @timeleft-- in #12
  • feat(llm): Extract LLM client library with multi-provider support by @timeleft-- in #8
  • feat: Add get CLI subcommand for programmatic artifact retrieval by @timeleft-- in #10
  • feat: Add lifecycle hooks system (Spec 17) by @timeleft-- in #11
  • feat: Spec 22 — Unified Config Architecture (ConfigStore + hooks in config.yaml) by @timeleft-- in #14
  • feat: add SECOM compression hooks (protocols/secom) by @timeleft-- in #15
  • feat(rlm): add RLM MapReduce hooks protocol by @timeleft-- in #18
  • feat(ace): ACE Playbook Hooks — Curator Pattern (Spec 18) by @timeleft-- in #17
  • fix(trust-gate): prevent propose_truth from hanging indefinitely on LLM timeout by @timeleft-- in #19
  • fix(secom): add secom-skip opt-out tag and structured-data safety warnings by @timeleft-- in #20
  • fix: observer hook feedback and metadata.extra in MCP responses by @timeleft-- in #21
  • fix(ace): warn on unknown match keys; skip RecallSelect when order unchanged by @timeleft-- in #22
  • feat(hooks): add on_recall_mix lifecycle hook for cross-trail reranking by @timeleft-- in #23
  • feat: add CLI protocol setup commands for SECOM, ACE, and RLM by @timeleft-- in #24
  • fix: include on_recall_mix in ACE and RLM DEFAULT_HOOK_ENTRY by @timeleft-- in #25
  • docs: clarify LLM provider support with any-llm-sdk and multi-provider extensibility by @timeleft-- in #26
  • docs: fix factual errors in LLM provider references by @timeleft-- in #27
  • chore: bump version to 0.5.0 by @timeleft-- in #28
  • docs: sweep remaining factual errors across all docs and protocol modules by @timeleft-- in #29
  • chore: bump version to 0.5.1 by @timeleft-- in #30

Full Changelog: v0.4.12...v0.5.1