Skip to content

madcop v1.3.0-rc.2 — Outcome-aware L3

Pre-release
Pre-release

Choose a tag to compare

@linmy666 linmy666 released this 26 Jun 13:11

v1.3.0-rc.2 closes the second half of the loop: every reflection is now stamped with outcome: success|failure at write time, and a new L3 layer re-ranks lessons accordingly before the planner sees them.

Backward-compat: rc.1 contract is bit-identical for any brain whose pages lack the outcome: field. Old skills, old tests, old chains keep working.

L1 side — outcome stamp

ReflectionMiddleware now stamps every skill page it writes with outcome: success|failure in the frontmatter and as a tag. The value is exposed on ctx.shared["reflection_outcome"] for chain observability.

L3 side — outcome-aware re-rank

New module madcop.agent.outcome ships:

  • boost_outcome(lessons, outcome_weight=0.4, half_life_days=60) — pure additive rerank. score += outcome_weight * (-1|0|+1) * recency_factor. Stable for ties (preserves rc.1 FTS5+recency order).
  • OutcomePrioritizer — middleware at HOOK_PLAN_START, runs after RetrievalMiddleware, rewrites ctx.shared["prior_lessons"] in place. strategy="boost" (default) or "filter" (drops outcome:failure lessons).
  • format_lessons_with_outcome(lessons) — renders a ## Prior lessons (outcome-tagged) block with //? glyphs per line, so the planner can weight lessons visually without a second LLM call.

Quick start

from madcop.agent import (
    MiddlewareChain, QianControlMiddleware,
    RetrievalMiddleware, OutcomePrioritizer,
)

chain = MiddlewareChain([
    RetrievalMiddleware(db=db),                    # L2 — writes prior_lessons
    OutcomePrioritizer(outcome_weight=0.4),        # L3 — re-ranks them
    QianControlMiddleware(),
])

Defaults

  • outcome_weight = 0.4 — small enough to preserve strong FTS5 hits, large enough to reorder ties.
  • outcome_half_life_days = 60.0 — 60-day-old failure tag carries ~50% weight; 1-year-old tag carries ~3%.
  • strategy = "boost" (default) — additive, never destructive.

Tests

23 new tests in tests/agent/test_outcome.py. Total 901/901 passing.

Install

pip install --upgrade madcop==1.3.0rc2

Verification

  • pytest: 901 passed in 4.90s
  • python3 -c "from madcop import __version__" -> 1.3.0rc2
  • Fresh-venv pip install --force-reinstall madcop==1.3.0rc2 -> imports L3 surface; synthetic succ -> unk -> fail E2E order PASS