Skip to content

Restack learning routing onto current #569 tip (#570) - #745

Merged
davekilleen merged 4 commits into
mainfrom
cursor/learning-routing-restack-6228
Sep 22, 2026
Merged

davekilleen merged 4 commits into
mainfrom
cursor/learning-routing-restack-6228

Conversation

@davekilleen

Copy link
Copy Markdown
Owner

Linked Issue

What Changed

Old fork head: 048febdefea55a067199f3cc4d7e60848d27f1de (chrisjackson-coding:learning-routing)
New same-origin head: 97c7f1f1f6cc93fb17cb839869ceef441ff05b32
Stacked on: #744 (f35e24df) which itself sits on main #568 (8cf7dd84)

The original fork PR (#570) is DIRTY and cannot be force-pushed (workflow-file restriction on the chrisjackson-coding fork). This same-origin branch is the MERGEABLE restack, same pattern as #744 / #743 / #742.

Test Plan

  • Unit/integration tests added or updated: core/tests/test_learning_routing.py (14 tests, carried forward from Starter for the learning routing step from #503: parse, cluster, propose, record #570)
  • Negative/error-path tests added or updated: malformed file, non-day file, invented status refused, two entries in one file never have statuses crossed
  • Commands run locally:
    • pytest core/tests/test_learning_routing.py14 passed
    • pytest core/tests/test_freshness.py18 passed
    • pytest core/tests/test_mcp_session_lifecycle.py10 passed (including test_parent_death_reaps_the_process_pair on first run; no wait hardening)

Ralph Wiggum Loop

  • I implemented the change.
  • I self-reviewed for defects and edge cases.
  • I requested specialist review for risky areas (testing/infra/security when relevant).
  • I addressed review findings and re-ran checks.

Quality Gates

  • I added/updated tests or documented why no tests are needed.
  • I added a regression test for bug fixes, or this PR is not a bug fix.
  • I validated failure modes / edge cases.
  • I updated docs or confirmed no docs impact.
  • CI checks for lint + tests + coverage are expected to pass.

Risk & Rollback

Docs Impact

  • Files updated: none
  • If none, reason: starter module and tests only; no skill wiring and no generated catalog/inventory changes

Notes

Open in Web Open in Cursor 

chrisjackson-coding and others added 4 commits September 22, 2026 12:22
…ure it

Concrete basis for the discussion in #565, deliberately not wired into any
skill. The design decisions worth arguing about are which artefacts require
what, and that should be settled before anything enforces it.

The problem: context carries no freshness marker. A calendar read from four
hours ago and one from a minute ago sit side by side with identical authority,
which is how a long session ends up using yesterday's date, an unchecked inbox,
and a stale task list while sounding entirely current.

Three pieces.

**A per-vault declaration** (System/knowledge-half-life.yaml, shipped as seed so
user tuning is never overwritten). Volatility is personal: one person's pipeline
moves weekly, another's task list hourly, so a fixed table ships wrong for most
people. Sources that do not decay are declared `never`, because a user's
decisions and corrections are superseded rather than aged out.

**Observations recorded mechanically.** A PostToolUse hook stamps a source the
moment a tool that reads it is called. This is the part that matters: an
assistant that cannot notice its context has gone stale is exactly the one that
will forget to record when it last looked, so self-reporting would inherit the
original defect. The ledger reflects what happened, not what was believed.

**An artefact contract**, which is the half that can honestly be enforced. An
assistant cannot audit its own memory for staleness, but "a daily plan requires
a calendar read newer than its half-life" is checkable from outside. On this
vault, run against yesterday's daily plan, it returns exactly the failure that
occurred: email STALE at 240 minutes, week_priorities NOT OBSERVED.

Distinctions the module refuses to collapse, each of which has already caused a
real failure somewhere in this codebase: a missing config is UNAVAILABLE rather
than everything-is-fresh; a typo in a half-life fails loudly rather than
silently becoming fresh-forever; an unknown source gets the cautious answer; and
"stale" reads differently from "never observed" because they call for different
responses.

18 tests. All twelve quality gates pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Co-authored-by: davekilleen <davekilleen@users.noreply.github.com>
Raised on review. The single meetings entry conflated two things with opposite
decay: whether new captures exist, which goes stale within the hour, and what
was said in a meeting, which does not go stale at all. A finalised transcript is
a record, superseded by a later meeting rather than aged out, so it belongs with
decisions and corrections in the never category.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: davekilleen <davekilleen@users.noreply.github.com>
Offered against #503, to @joshm-simril's design and @davekilleen's spec. The
routing table is Josh's, kept as data rather than code so it can be edited
without touching this module, which was one of his own open questions.

Deliberately does NOT apply anything. Dex must never silently rewrite its own
instructions, so the edit has to be shown and confirmed before it lands, and
confirmation belongs in the skill that can hold a conversation. Everything here
is analysis and bookkeeping.

The split is the point: clustering and destination-proposal are mechanical and
testable, while deciding whether a proposed edit is right is judgement. Mixing
them would bury an unreviewable decision inside something that looks like a
helper.

Four pieces, matching the spec on #503:

- Parse entries from Session_Learnings with enough location to rewrite one
  status without disturbing its neighbours.
- Cluster by proposed destination rather than by wording, because two entries
  belonging in the same file are worth reviewing together even when they read
  differently. Josh's observation was that eight related entries became one
  rule, not eight edits.
- Trigger on volume OR age. Age matters independently: a single correction left
  for a fortnight is a worse signal than ten from this morning, and a count-only
  trigger never fires on a slow, steady leak.
- Record an outcome as implemented (date and destination) or dropped (date and
  reason), so a falling count means something was installed rather than
  something ageing out of view. An invented third status is refused.

14 tests, including that two entries in one file can never have their statuses
crossed. All twelve quality gates pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

What this pull request touches

  • session hooks — feeds starting sessions and carrying useful context into the next interaction.
  • tests — feeds catching regressions before contributors and users encounter them.

Gates that will judge this change

  • Personal-data gate: added lines must not expose real identities or personal vault content.
  • Change-aware gates: source changes are checked for tests, path-contract use, documentation drift, and touched-file coverage.
  • Tests and coverage: the Python, MCP, migration, hook, and script suites must remain healthy.
  • Safety and quality: security, lint, distribution, path consistency, and large-vault checks still apply.

Based on 12 changed files.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved. Cursor Bugbot was not present after the first check poll, so that signal was skipped. No approval policy required human review, and no reviewers were assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@davekilleen
davekilleen merged commit df7987f into main Sep 22, 2026
14 of 15 checks passed
@davekilleen
davekilleen deleted the cursor/learning-routing-restack-6228 branch September 22, 2026 12:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants