Repository navigation
Plan integration follow-on (D-D): derive the plan bias from prerequisite edges, milestone order and energy demand #25
Copy link
Copy link
Closed as not planned
Closed as not planned
Copy link
Labels
ready-for-agentImplementation-ready specification with settled requirements and test seamsImplementation-ready specification with settled requirements and test seams
Milestone
Description
Origin
- Owner decision D-D (
docs/architecture/plan-integration/HANDOFF-2026-09-16.md§2): "F2 → open a ticket, don't park: a context-derived plan bias (prerequisite edges from the concept store viaget_concept_context, milestone order; per-item energy demand from struggle state) — deterministic and rubric-testable. Not an LLM tie-break (unauditable; defeats D-16)." - Evidence: rubric row 1 (
receipts/now-rubric-2026-09-16.md) — the owner ranked the plan-matching due item first because of what depends on it ("window function is the logical step before decorating it"); the engine ranked it first only because it carried the plan bias. Same answer, different reason; the reason generalises. - Full proposal, written from the code on
maina5b9f903:proposals/2026-09-16-context-derived-plan-bias.md. Follows on from Integrate Study Plans across Now, Web architect, and MCP #7 (plan integration) and council review 3 F2; not a blocker of Integrate Study Plans across Now, Web architect, and MCP #7.
What to build
Replace the single constant PLAN_RELATED_BIAS = 12 in studyloop/learning/decision.py (rule 5) with a derived bias from three deterministic inputs, each its own rule with its own rubric row, bounded so the "bias, never a filter" invariant holds (a clearly more-urgent unrelated candidate must still win):
| Rule | Input | Signal |
|---|---|---|
| 5a — plan relevance (today's rule 5) | plan refs / key intersection | the existing +12, as today |
| 5b — prerequisite order | learning/mastery.py::list_dependencies(topic) edges with relation_type == "prerequisite" (already consumed by weak_links_for_topic) |
a candidate whose concept is a prerequisite of an open milestone's concept in a matchable plan gains a small bonus; a candidate whose concept depends on a concept the learner is struggling with loses the same amount — bounded below the urgency-class gap, pinned like PLAN_RELATED_BIAS |
| 5c — per-item energy demand | struggle state (confidence, last_teachback_score) and action type vs ENERGY_CAPABILITY[energy] |
consumes item 5's (D-F) energy-demand definition when it lands; this issue must not define a second one |
Constraints (from the decision):
- Deterministic — every input is a stored fact; no model call anywhere in ranking.
- Rubric-testable — one D-16 rubric row per rule, planted world + expected primary, scored by the owner before it ships; row 1 re-run under 5b should still be yes, now for the engine's reason; a new row plants a struggling prerequisite and expects the dependent milestone not to be primary.
- Still a bias — golden
now_plan_no_active.jsonbyte-identical; the existing rule-5 pins stay green with the derived value in place of the constant:test_matching_due_concept_outranks_unrelated_same_urgency,test_unrelated_more_urgent_due_outranks_new_milestone,test_weak_due_still_beats_overdue_synthesised_milestone. - Partial knowledge is not knowledge —
get_concept_contextis explicit that omitted edges cannot support "no alternative exists"; 5b treats an absent edge as no signal, never as "not a prerequisite". - Read once, through the seam — edges read in
_PlanContext.buildbeside the plan read (rule-1 pin: no per-consumer plan reads, no checkpoint-history reads); the concept-store read budgeted and measured on the live database before shipping (the item-4 preview read was ~320 ms on an 877 MBsessions.dband recorded; this must be too).
Out of scope
- Item 5 (D-F) owns the energy-demand definition and the body-doubling floor; this issue consumes it.
- No change to what a plan document stores; prerequisite knowledge lives in the concept store.
- No filter, no reordering of urgency classes (review 3 F2 stands).
Acceptance criteria
-
PLAN_RELATED_BIASreplaced by a derived value with a pinned upper bound; the three rule-5 pins above and the golden byte-identity green unchanged. - RED tests, one per rule: a prerequisite-of-open-milestone candidate outranks a same-class sibling; a candidate dependent on a struggling concept loses to that concept's repair; an absent edge changes no score.
- A measured read cost on a real
sessions.db, recorded beside the constant. - Rubric rows added and scored by the owner (D-16), row 1 re-run.
- Docs:
docs/study-plans.md"Plan-aware now" describes the derived bias in the eligibility termstest_docs_plan_integration_contract.pypins.
Blocked by
- Rule 5c only: item 5 (D-F) of
openspec/changes/plan-integration-followons(T5.3energy_demand) — not yet a GitHub issue. Rules 5a/5b can start now.
Definition of Done
- Full unit suite green;
just lint;just typecheck; goldennow_plan_no_active.jsonbyte-identical. - Council review of the RED and the arbitration before merge (the programme's pattern: one commit per accepted finding).
- Docs and spec (
openspec/specs/active-learning-decisions) updated in the same change.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
ready-for-agentImplementation-ready specification with settled requirements and test seamsImplementation-ready specification with settled requirements and test seams
Activity
NetDevAutomate commentedon Sep 21, 2026
Closed: not planned — owner decision 2026-09-21, with a reopen condition.
Why. The one rule here that would add information the engine does not already have is 5b, prerequisite order, read from the concept store's
prerequisiteedges. On the live database (~/.config/studyloop/sessions.db, opened read-only on 2026-09-21)concept_dependenciesholds 0 rows — 0 prerequisite edges, and nothing in the product writes them for a real learner: the table is schema without data (agent_session_tools/migrations.pycreates it;learning/mastery.pycan upsert; no learner-facing path does). This issue's own constraint 4 requires an absent edge to be read as no signal, so 5b would produce nothing for a real learner today. Rule 5c is now redundant: item 5 (D-F, onmainat96806feb) governs a repair's eligibility by its energy demand; biasing on the same number a second time double-counts it. Rule 5a is today'sPLAN_RELATED_BIAS = 12unchanged. On real data the derived bias would therefore equal the constant it replaces — a RED per rule, a measured read cost, a council round and two rubric rows spent on a value that changes no recommendation.What stands. The shipped ranking is the honest implementation for the data that exists: rubric row 1 scored yes on it (2026-09-16), the golden
now_plan_no_active.jsonis unchanged, and "a bias, never a filter" holds. Owner decision D-D indocs/architecture/plan-integration/HANDOFF-2026-09-16.mdand the proposaldocs/architecture/plan-integration/proposals/2026-09-16-context-derived-plan-bias.mdremain as the record of the design; this decision supersedes D-D's when, not its shape.Reopen when: the concept store carries
prerequisiteedges for a real learner — i.e. a product path writesconcept_dependenciesrows from study evidence andSELECT COUNT(*) FROM concept_dependencies WHERE relation_type='prerequisite'is non-zero on a real database. At that point 5b is buildable exactly as written above (5a stays the constant; 5c stays out, item 5 owns demand), with the measured read cost and the rubric row this issue already specifies.