Skip to content

v5.1.0

Choose a tag to compare

@github-actions github-actions released this 22 Jun 20:54
· 314 commits to main since this release

Consolidated 5.1.0. The tier1 graph/session-intelligence layer ships
together with handoff-v2 persistence, the dynamic-flow firewall + router,
named pipelines, capability-aware dispatch, and the session-lifecycle
catch-up/summarizer. First PyPI publish since 5.0.1.

Added — dynamic-flow, session-lifecycle, SDD

  • Dynamic-flow firewall + closure (Phase 1): scripts/mb-flow-verify.sh is
    the sole exit-code authority (0=pass / 1=fail / 2=broke); Stop-hook
    (mb-flow-closure-guard.sh) + git-hooks closure guards gated on a goal.md
    predicate; AGENTS.md firewall contract; goal primitive + validator. Shipped
    through the governed dual-review (Codex + lead) + judge pipeline. (REQ-DF-010..062)
  • Dynamic-flow router + patterns (Phase 2): analyze-task deterministic
    router, five-route catalogue, six workflow pattern templates, stateless
    mb-fanout.sh agent-invoke + per-agent sub-invoke contract with
    parallel-fence write-once discipline. (REQ-DF-070..084)
  • Session-lifecycle: mb-session-catchup.sh (SessionStart lazy-summarize of
    sessions left summarized:false by a SIGKILLed SessionEnd), extracted DRY
    mb-session-summarize.sh, mb-session-prune.sh (archive contentless stubs),
    mb-settings-ensure-timeout.py (inject the SessionEnd timeout). All fail-safe.
  • SDD hybrid requirements: requirements.md now pairs Kiro User Stories with
    EARS acceptance criteria; mb-ears-validate.sh is case-insensitive and
    validates only the REQ bullets; mb-plan.sh plan template gains YAML
    frontmatter (type/topic/status/depends_on/parallel_safe/linked_specs/created).
  • Cursor extension finished — sessionEnd registry auto-capture.

handoff-v2. A persistence layer that lets a long-running agent survive
context compaction and session boundaries: a small handoff capsule written
before compaction and restored at the next session, mandatory /mb done
gates that run even without an active plan, and a sha256 hash chain that makes
tampering of historic progress.md entries a CRITICAL drift. Shipped through
the governed dual-review (Codex + lead) + judge pipeline, with a fix-cycle per
task.

Added

  • Handoff capsule (scripts/mb-handoff.sh + memory_bank_skill/handoff_capsule.py).
    --actualize/--read/--rotate a ≤1500-byte capsule under
    .memory-bank/handoff/. The five sections (Now / Done / Open blockers / Next
    concrete step / Pointers) always survive truncation — the skeleton is reserved
    first and only the bullet lists are byte-fit, so the most important section is
    never dropped. UTF-8-safe byte cap; colon-free archive names;
    copy-then-atomic-rename so a capsule is never lost on interrupt; owner-token
    mkdir lock for single-writer safety. (REQ-120)
  • PreCompact actualize (hooks/mb-pre-compact.sh, renamed from
    mb-compact-reminder.sh). On preCompact, refreshes the capsule within a ~2s
    portable budget and never blocks compaction — on timeout/failure/no-bank it
    WARNs and exits 0, killing the whole actualize process tree (no orphans). Opt
    out with MB_PRECOMPACT_HANDOFF=off. (REQ-120, REQ-121)
  • SessionStart capsule consumption (hooks/mb-session-start-context.sh).
    Prepends the capsule only when it is newer than the most recent progress.md
    date heading; otherwise the normal context is unchanged. (REQ-121)
  • Mandatory /mb done gates (scripts/mb-done-gates.sh). Tests + rules
    (with --diff-files so the CRITICAL TDD-delta check runs) + placeholder scan,
    honouring done_gates.required. --force requires a single-line --reason
    (newline-injection rejected), records a NOTE in progress.md + a failure JSON,
    and fails closed when allow_force:false or a project pipeline.yaml
    cannot be parsed. Configurable via pipeline.yaml:done_gates. (REQ-122, REQ-123)
  • Append-only hash chain (scripts/mb-progress-chain.sh +
    memory_bank_skill/progress_chain.py). --rebuild-tail/--verify a sha256
    chain of the last 20 progress.md entries in index.json:progress_chain;
    mb-drift.sh raises CRITICAL on a mismatch, deletion, ambiguous match, or a
    malformed index.json. Canonical-form hashing (LF-normalised, trailing
    separators excluded) keeps legitimate appends stable while in-body content and
    whitespace edits remain tamper. (REQ-124)
  • scripts/mb-rules-check.sh --placeholders-only — scan-only mode for the
    done-gate, with tests/-path and # mb-rules-check: allow-placeholder
    exemptions.
  • Docsdocs/handoff-2.0.md (capsule lifecycle, done-gate + force
    semantics, hash-chain limits).

Changed — defaults

  • /mb done now runs the done-gate set as step 0 (enabled by default; failures
    require --force --reason). Existing plan/spec verification is unaffected.
  • settings/hooks.json registers mb-pre-compact.sh on preCompact (replacing
    the old weekly compact reminder, which remains available in adapters/cline.sh
    via MB_COMPACT_REMIND). Re-registration stays idempotent.

tier1-graph-memory (Phase 5) — 2026-06-14

tier1-graph-memory. Sharper code-graph retrieval (RRF fusion, import-aware
Python call resolution, PageRank god-nodes), richer session memory
(progressive-disclosure recall, per-turn outcomes, structured summaries), and
three new $0 memory-hygiene commands (/mb recap, /mb conflicts,
/mb consolidate). Every new opt-in layer keeps base output byte-identical.

Changed — defaults

  • RRF fusion is the default auto-backend in code search. With embeddings
    installed, mb-semantic-search.py --backend auto now fuses the embeddings and
    BM25 rankings via Reciprocal Rank Fusion (rrf_merge, by_id built at index
    time, O(k) query fusion) instead of using embeddings alone. auto without
    embeddings stays pure BM25 (byte-identical to before); explicit --backend bm25/embeddings are regression-locked. (REQ-001/REQ-002)
  • Import-aware call resolution for Python. call edges in .py files now
    resolve through the file's actual imports — binding order is: local def wins

    explicit import (relative level + as-alias aware) > single star-import
    match > unique project-wide fallback > suppress homonyms. Dotted dst
    namespacing via the new codegraph_binding.py. Non-.py edges pass through
    verbatim; the graph cache is bumped to CACHE_VERSION=2. Resolution for the
    tree-sitter languages (Go/JS/TS/Rust/Java) stays name-based. (REQ-003/REQ-004)

  • god-nodes.md is ranked by PageRank, with degree as a secondary column
    (was degree-only). Pure-stdlib power iteration (networkx.pagerank semantics,
    no numpy/scipy) in codegraph_rank.py, full-precision sort with 6-dp display,
    cross-process deterministic. Without networkx the report degrades to
    degree-only and prints a one-line install hint. (REQ-005/REQ-006)

Added

  • rrf_merge(rankings, k=60) — standalone Reciprocal Rank Fusion module
    (memory_bank_skill/rrf.py), the single source of truth for rank fusion across
    code search and /mb recall. (REQ-001)
  • churn_30d ranking signal under /mb graph --cochange. Per-file 30-day
    churn is derived from the same git-log pass as co-change mining (one
    subprocess, asserted) and emitted as additive {"type":"node-attr"} JSONL
    rows only under --cochange; semantic search applies a 1+0.1·log1p(churn)
    boost after ranking/fusion over the full candidate set, then truncates. No
    churn attrs → ranking byte-identical. (REQ-007)
  • Community-summary retrieval in code search. When a /mb wiki article lands
    in the top-3 final hits, mb-semantic-search.py appends a labeled
    community_files block (member files from .wiki-packs.json, sorted, capped
    at 10). Fail-open: missing/malformed packs or non-article hits → byte-identical
    no-wiki output. (REQ-008)
  • Per-turn capture upgrade — outcome + diffstat. Each session Live-log
    bullet now records an ok | err(N) outcome (turn-scoped is_error count) and
    an aggregate +A/-B diffstat from a single git diff --numstat; fails closed
    outside work trees / bare repos. (REQ-009)
  • Structured summary schema v2. The session-end Haiku summarizer now consumes
    the session's own distilled Live log (never the raw transcript tail) and is
    prompted for exactly four sections — What changed / Decisions / Open questions
    / Files
    . summary_schema: v2 is stamped only after a strict in-order heading
    validation passes (duplicate/out-of-order headings are rejected, see I-069);
    non-conforming output is stored unflagged. (REQ-010/REQ-011)
  • Progressive-disclosure /mb recall. Default output is now a compact index
    — one id · age · summary · source line per hit (~15 tokens/line, no chunk
    bodies). --expand <id> returns one full chunk (exit 3 on unknown id),
    --full keeps the legacy bodies. Semantic + lexical hits are fused via RRF
    when the semantic backend is available (fail-open to lexical-only otherwise);
    [SUPERSEDED] chunks sort last with a label. (REQ-001/REQ-016–019)
  • /mb recap <sid> — rebuild a full progress.md entry from a session stub
    via one Haiku call (scripts/mb-recap.sh). Surgically replaces only that
    session's auto-capture stub (atomic temp→mv, neighbors byte-identical),
    idempotent via recapped frontmatter; strict no-write refuse paths with pinned
    exit codes (missing session/progress → 2, no claude → 3, no stub → 4,
    error-shaped output → 5); ambiguous prefix → refuse and list candidates.
    (REQ-020/REQ-021)
  • /mb conflicts [--judge] [--threshold N] — surface memory entries with
    high lexical overlap and opposing/replacement assertions (en+ru negation
    markers) as conflict candidates over notes/ + lessons.md + recent
    progress.md. $0 default pass (token-set Jaccard > N, default 0.3, zero
    LLM calls); --judge confirms/rejects each candidate via one Sonnet call and
    prints a suggested [SUPERSEDED: YYYY-MM-DD -> <ref>] marker. PRINT-ONLY —
    never writes to any bank file. (REQ-022/REQ-023)
  • /mb consolidate [--apply] [--days N] — fold sessions older than N days
    (default 30) that cluster by shared files / lexical overlap into 5–15 line
    notes/ candidates, archive those session files verbatim → session/archive/,
    and move only their contiguous auto-capture progress stubs verbatim →
    progress-archive.md. Zero LLM calls; dry-run is the default (bank
    byte-identical); real progress entries never move. (REQ-012/013/014)
  • [SUPERSEDED] convention + drift checker. The append-new + mark-old
    [SUPERSEDED: YYYY-MM-DD -> <ref>] convention is documented in
    agents/mb-manager.md + references/metadata.md and enforced by a new
    mb-drift.sh checker: malformed markers and dangling refs across notes/,
    lessons.md, progress.md, session/ → greppable warnings + exit 1 (with
    real Gregorian calendar validation). (REQ-015)
  • /mb graph --sessions layer. Bridges session memory into the code graph:
    one session node per session that touched a graph module, a worked_on edge
    to each touched module carrying a one-line work summary, and an append of that
    summary to the module node's doc (capped at the 3 most recent sessions per
    module) so semantic search answers work-history queries. Every
    session-derived string is redact_secrets'd and <private>-stripped at
    graph-write time (graph.json stays committable). The layer is applied as the
    last mutation — after community/betweenness/PageRank analytics — so god-node
    ranking is never skewed (god-nodes.md is byte-identical with or without the
    flag). (REQ-024/025/026)
  • Staleness-aware incremental /mb wiki rebuild. wiki/index.md records a
    per-article SHA256 over the canonical graph records touching each community's
    files; a $0 plan splits communities into scheduled vs fresh and filters the
    dispatch — a fully-fresh cache → zero Haiku/Sonnet dispatches, --force or a
    legacy/no cache → full rebuild. Hash recording is idempotent. (REQ-027)
  • Deterministic Decisions section in wiki evidence packs. Each community pack
    can carry a decisions list — notes/ entries + session summaries matched
    against the community's file basenames (token-bounded matching), top-5 with
    source refs, $0, deterministic order. Session files contribute only their
    ## Summary body (frontmatter / Live log / ### Files path list never leak).
    (REQ-028)
  • semantic edge confidence bands documented + a 0.5 floor enforced. The
    references/code-graph.md reference now defines the meaning of confidence on
    semantic edges (High ≥ 0.9 / Medium 0.7–0.9 / Low 0.5–0.7 / dropped < 0.5) as
    the single source of truth; the wiki synthesizer assigns by these bands and
    merge-edges enforces the < 0.5 drop, so a semantic edge in graph.json
    always means confidence ≥ 0.5. (REQ-029)

Added — named pipelines

  • Multiple named pipelines per project. A project can keep several pipelines
    under .memory-bank/pipelines/<name>.yaml, each a full standalone config (same
    schema + validator as pipeline.yaml) with its own model routing and workflow.
    /mb work --pipeline NAME (or $MB_PIPELINE) selects one explicitly; a
    pipeline whose agents: lists the current code-agent host
    (claude-code/pi/opencode/codex/…) is auto-selected per host, so one
    repo can run a fast solo loop under Claude Code and a governed review-ensemble
    under pi/opencode with no flag. Selection ladder: flag/env → host binding →
    .mb-config pipeline=NAME → in-file default: true → legacy pipeline.yaml
    bundled default.
  • /mb pipeline command (commands/pipeline.md): list ·
    new NAME [--agent a,b] [--from NAME|default] [--default] [--force] ·
    use NAME (non-destructive default switch via <bank>/.mb-config) · show ·
    path · validate [--all] (cross-file conflict detection: duplicate
    pipeline_name, more than one default, an agent bound to multiple pipelines).
  • scripts/_lib.sh: mb_detect_host (host from $MB_PIPELINE_HOST$MB_AGENT
    → env signatures), mb_pipeline_dir, mb_pipeline_meta. mb-pipeline.sh
    selection ladder; mb-pipeline-validate.sh validates the optional
    pipeline_name/default/agents metadata keys.
  • Consumers (mb-work-*.sh, mb-workflow.sh) read the selected pipeline with no
    changes — they already resolve through mb-pipeline.sh path, which now honors
    $MB_PIPELINE and host binding.
  • Backward compatible: with no pipelines/ directory and no --pipeline,
    resolution is byte-for-byte identical to the prior single-pipeline.yaml path.

Added — security

  • Automatic secret redaction in session capture (default on). Recognizable
    API keys/tokens (sk-…, ghp_…/github_pat_…, AKIA…/ASIA…, xox?-…,
    AIza…, hf_…, npm_…, pypi-…, JWTs, Bearer <token>, *_API_KEY=-style
    env assignments) are replaced with [REDACTED] before they reach
    .memory-bank/session/*.md or the semantic index. Applies at three layers:
    the per-turn Live-log bullet, the transcript fed to the Haiku summarizer /
    Sonnet judge, and the semantic chunker. Off-switch: MB_REDACT_SECRETS=off.
    Implementation: hooks/lib/redact.py + sc_redact_secrets in
    hooks/lib/session-common.sh. Regression for a real leak: an OpenRouter key
    quoted in a transcript error was persisted verbatim.
  • Semantic-index chunker now also strips <private>…</private> blocks
    (mirrors mb-index-json.py), closing the gap where private content was
    excluded from index.json but still indexed for /mb recall.

Fixed

  • I-069 — strict v2 heading state machine. The schema-v2 summary validator
    now rejects a duplicate or out-of-order ### … heading instead of stamping
    summary_schema: v2 on it; a rejected body is still stored, just without the
    (now-honest) flag.
  • I-066 — unique-fallback binds module-level defs only. Rule 3 of the
    import-aware binder no longer collapses a class method (Worker.process) or
    nested function to its bare suffix, so it can no longer invent a false call
    edge to a non-module-level definition.
  • I-067 — no leading-dot dst for root __init__.py. A unique definition in
    a root __init__.py (empty module prefix) now emits a bare dst instead of a
    leading-dot .foo.
  • session-end-autosave.sh progress stub no longer promises a reconstruction
    that never happened ("Details will be reconstructed on the next /mb start");
    it now points at the actually-captured session summary (/mb recall).