Problem Statement
StudyLoop can create, persist, activate, and evaluate evidence-grounded Study Plans, but the plan is disconnected from the product surfaces learners use to decide and act. Activating a plan does not influence studyloop now or Today, live study sessions are not plan-bound, the Web UI cannot launch the Study Plan Architect, and MCP clients cannot manage or evaluate plans.
This creates a misleading gap between a plan being active and the system behaving as though it matters. Policy is also duplicated across CLI and Web callers, including activation readiness and milestone mutation, which permits inconsistent behavior such as creating an active-but-unready plan through one Web path.
Solution
Introduce one deep PlanApplication module as the shared seam for Study Plan use cases. CLI, Web, MCP, and recommendation callers use its immutable views, domain errors, lifecycle changes, assessments, planning briefs, and active-plan guidance instead of mutating plan documents directly.
Use this seam to deliver three coordinated capabilities:
- Add active-plan guidance to the existing recommendation engine so
studyloop now, Today, recap, and MCP get_next_action remain consistent.
- Let the Web UI launch the existing Study Plan Architect through the current session-launch, one-session-authority, and PTY/ACP transport machinery while retaining the manual form.
- Add MCP Study Plan lifecycle tools as thin adapters over the same application module.
Live study-session binding remains a separate future feature. This change launches planning conversations and biases recommendations, but does not persist a plan identifier on live session state or automatically complete milestones.
User Stories
- As a learner with an active plan, I want
studyloop now to consider my next milestone, so that activating a plan changes what StudyLoop recommends.
- As a learner, I want recommendations to name the matching plan and milestone, so that I understand why an action is relevant.
- As a learner, I want urgent due reviews and active struggles to remain eligible to outrank new milestone work, so that plan focus does not damage spaced learning.
- As a learner with low energy, I want demanding milestone work deferred with an explanation, so that the plan adapts without disappearing silently.
- As a learner with multiple active plans, I want all plans considered deterministically, so that StudyLoop does not silently choose a global singleton.
- As a learner whose active plan has all milestones complete, I want guidance to complete or extend it, so that stale active plans do not generate fake study work.
- As a learner with no active plan, I want current recommendation behavior unchanged, so that this feature is backward-compatible.
- As a learner, I want CLI Now, Web Today, recap, and MCP next action to share one recommendation result, so that surfaces cannot drift.
- As a learner, I want a plan-backed recommendation preserved among the primary action and alternates when feasible, so that an active plan remains visible without becoming a hard filter.
- As a learner, I want matching to use normalized topics and concepts rather than loose substrings, so that unrelated names do not receive plan relevance.
- As a learner, I want to launch “Plan with architect” from the Web Plans view, so that I can build a plan conversationally.
- As a learner, I want the architect grounded in my interview questions, learning evidence, existing plans, and optional brain dump, so that it does not start from generic prompts.
- As a learner, I want the architect to ask one question at a time, so that planning remains AuDHD-friendly.
- As a learner, I want starting an architect conversation to create no draft by itself, so that abandoned conversations leave no junk plans.
- As a learner, I want the manual plan form retained, so that agent availability never blocks plan management.
- As a learner, I want Web launch conflicts and reconnect behavior to match ordinary study sessions, so that one-session authority remains predictable.
- As a learner, I want the live console to show that its purpose is planning, so that refresh and reattach preserve context.
- As a learner, I want plan activation refused consistently when mission, success criteria, or milestones are incomplete, so that every surface enforces readiness.
- As an MCP agent, I want to list and filter Study Plans, so that I can discover current work.
- As an MCP agent, I want structured plan details, readiness, optional canonical Markdown, and checkpoint history, so that I can reason without scraping files.
- As an MCP agent, I want the data-grounded planning interview and seed, so that I can conduct the same architect workflow as the CLI.
- As an MCP agent, I want to create and revise plans through structured fields, so that normal edits do not require replacing raw Markdown.
- As an MCP agent, I want to activate, pause, complete, or abandon a plan, so that lifecycle management has parity with CLI and Web.
- As an MCP agent, I want to set a milestone explicitly done or undone, so that retries are idempotent and never reverse a successful mutation.
- As an MCP agent, I want to preview or record start, midpoint, and end evaluations, so that checkpoints remain evidence-grounded.
- As an MCP agent, I want deletion to require explicit confirmation, so that accidental tool calls cannot remove plans.
- As an MCP agent, I want domain failures returned as clear tool errors, so that I can recover from not-found, conflict, invalid input, not-ready, and partial-recording outcomes.
- As a maintainer, I want one application seam for lifecycle policy, so that CLI, Web, and MCP do not implement activation and mutation rules independently.
- As a maintainer, I want Markdown to remain the source of truth and SQLite to remain derived, so that current recovery and second-brain guarantees remain valid.
- As a maintainer, I want immutable serialization-ready plan views returned to callers, so that adapters cannot mutate domain objects and bypass policy.
- As a maintainer, I want plan identity and creation time preserved across revision and document replacement, so that history remains coherent.
- As a maintainer, I want partial checkpoint-recording failures reported honestly, so that a Markdown append cannot masquerade as a fully recorded DB checkpoint.
- As a maintainer, I want existing adapters migrated through the application seam before new features land, so that the change removes duplication rather than adding another implementation.
- As a maintainer, I want tests at the shared interface and product surfaces, so that refactors can change implementation without weakening behavior guarantees.
Implementation Decisions
Shared plan application module
Create a use-case-oriented PlanApplication module with six cohesive operations:
- Browse plans: return deterministic immutable summaries, optionally filtered by lifecycle state.
- Inspect a plan: return structured detail, readiness, optional canonical Markdown, and optional checkpoint history.
- Prepare planning: return the ordered interview, history-derived evidence seed, and existing-plan summaries needed by an architect.
- Get active guidance: derive transport-neutral guidance from every active plan, including next milestone, normalized matching keys, target urgency, energy eligibility, completion actions, and malformed-plan warnings.
- Apply a plan change: accept an explicit create, revise, validated document replacement, lifecycle transition, milestone set, or confirmed delete intent; load, validate, persist, and return the new immutable view.
- Assess a plan: preview or record a start, midpoint, or end checkpoint with an optional study identifier and explicit partial-write warnings.
Do not expose the plan store or mutable domain objects to transport adapters. Do not create one generic arbitrary-action interface. Storage, evaluator, and clock substitution remain internal seams because there is currently one real Markdown store.
Application invariants
- Markdown remains authoritative. A successful plan mutation means the canonical document was atomically replaced.
- Index refresh remains best-effort and recoverable; index failure does not invalidate a successful canonical write.
- Activation is readiness-gated for every entry path, including create-and-activate and raw-document import.
- Multiple active plans remain valid and are all considered.
- Milestone mutation sets an explicit boolean and is idempotent. Existing toggle routes may translate to an explicit set for compatibility.
- Revision and document replacement preserve plan identifier and creation time; the application controls update time.
- Create refuses duplicate identifiers unless a separately privileged import/overwrite path explicitly requests replacement.
- Deletion retains checkpoint history, matching existing behavior.
- Checkpoint DB history and Markdown append remain intentionally independent. The assessment result reports either failed write and never claims complete recording after a partial failure.
- Domain errors contain no CLI, HTTP, or MCP types. Adapters map not-found, invalid identifier, conflict, invalid field, not-ready, invalid milestone, and partial-recording outcomes.
- No operation associates a live study session with a plan.
Active-plan guidance and ranking
- The recommendation engine remains the only place that ranks global learning candidates.
- Active guidance is cheap and plan-static; it does not rerun full evidence evaluation on each Now request.
- Map low, medium, and high energy to capabilities 3, 6, and 10 when comparing plan energy floors.
- Defer new milestone work when capability is below the plan floor, but keep plan-related due recall or struggle repair eligible.
- Match candidates by normalized topic/course equality or named milestone concepts. Avoid broad substring matching.
- Plan-related due review and struggle repair outrank unrelated work in the same urgency class.
- Globally urgent reviews and fresh struggles may outrank a new milestone. Plan influence is a bias, not a hard filter.
- Synthesize a recommendation from an eligible next milestone when no gathered candidate represents it.
- Preserve at least one eligible plan-backed action among primary and alternates when active unfinished plan work exists and time/energy permit it.
- Deduplicate candidates before attaching plan references. When one action matches multiple plans, retain every reference and order by target urgency, most recent update, then plan identifier.
- A fully checked active plan produces lifecycle guidance rather than another study candidate.
- With no active plans, existing candidate collection, ordering, rendering, and JSON remain unchanged.
Extend the shared Now result additively. Include top-level active-plan summaries, energy-deferred milestones, completion actions, and warnings. Add an optional explicit plan reference to each recommendation containing plan and milestone identity. Do not hide the stable plan contract in open-ended metadata.
CLI Now, Web /api/now, Today, recap, and MCP get_next_action continue to consume the same decision result. The MCP wrapper also gains the existing interleave option for parity.
Web architect launch
- Add a “Plan with architect” action beside the manual New Plan path.
- Reuse the existing session-start endpoint, one-session claim, binary detection, agent selection, PTY/ACP launch, conflict response, WebSocket transport, reconnect flow, and live console.
- Add a
planning session purpose and resolve the existing Study Plan Architect persona and shared protocol instead of hardcoding the normal focus persona.
- Keep normal focus as the default purpose.
- Build the planning brief through
PlanApplication.prepare planning before launch.
- Starting a conversation creates no plan. The architect creates or revises only after gathering enough information.
- Use MCP lifecycle tools when available, with existing CLI commands as a harness fallback.
- Retain the manual structured form and existing CRUD/checkpoint screens.
- Reuse the existing console rather than mounting a second competing terminal/chat listener. Persist only planning purpose for labeling and reconnect.
MCP lifecycle parity
Register thin MCP adapters over PlanApplication for:
list_study_plans
get_study_plan
get_planning_interview
create_study_plan
update_study_plan
set_study_plan_status
set_study_plan_milestone
evaluate_study_plan
delete_study_plan
Raw Markdown replacement remains an import/editor capability rather than the default agent mutation. Deletion requires explicit confirmation. Reindex administration, storage paths, downloads, and live-session binding are not MCP lifecycle parity.
Delivery order
- Add the application seam, immutable views, domain errors, and interface tests.
- Migrate existing CLI plan commands and Web plan routes through it while preserving behavior.
- Add active guidance and integrate it once in the shared recommendation engine; extend renderers additively.
- Add MCP lifecycle tools and registration/documentation updates.
- Add planning-purpose persona resolution and the Web launch affordance using the existing transport stack.
- Reconcile public docs and installer language so they state exactly which surfaces are automatic.
Update the normative capability specs for active learning decisions, MCP, Web UI, agent adapters, and CLI plan behavior as implementation slices land. Record a new ADR only if the shared application seam or planning-purpose session semantics remain load-bearing and are not already captured by existing source-of-truth/session-authority decisions.
Testing Decisions
Tests assert external behavior through the highest available seam. They must not assert private helper calls, internal file layout beyond documented source-of-truth contracts, framework-specific implementation details, or model prose.
Application interface
- Test every operation against an isolated plan directory and database.
- Prove activation refusal is identical for create-and-activate, lifecycle transition, and document replacement.
- Prove identifier and creation time preservation across revision.
- Prove milestone set is idempotent under retries.
- Prove multiple active plans remain valid.
- Prove deletion retains checkpoint history.
- Prove checkpoint partial writes return explicit warnings.
- Prove malformed plans are skipped or reported consistently with existing listing behavior.
- Use existing store, evaluation, CLI plan, and Web plan tests as prior art.
Adapter migration parity
- Run existing CLI and Web plan suites unchanged while migrating callers.
- Add cross-surface tests showing equivalent CLI and Web changes yield the same immutable plan state and readiness failures.
- Add a lightweight architecture test preventing CLI/Web/MCP adapters from directly importing mutable store operations after migration.
Recommendation behavior
- Test no active plan as an exact backward-compatibility case.
- Test one active plan with a matching due concept.
- Test an unrelated but more urgent due concept outranking a new milestone.
- Test multiple active plans and one action matching several plans.
- Test a milestone without concepts, an energy-blocked milestone, and a fully checked active plan.
- Test exact normalized matching so short topic names do not match unrelated text.
- Test additive JSON fields and concise CLI rendering.
- Test that Web Now, Today, recap, and MCP still delegate to the shared decision result rather than reading plans independently.
MCP
- Extend the real stdio handshake/tool-list test to require the nine plan tools.
- Test tool schemas, application delegation, error mapping, idempotent milestone retries, preview-versus-record evaluation, and confirmed deletion.
- Do not duplicate lifecycle-policy tests in the MCP adapter layer.
Web architect
- Use the existing fake agent and representative browser journey to cover PTY/ACP launch without paid model calls.
- Prove planning purpose selects the architect persona and includes the evidence-grounded planning brief.
- Prove the first interaction follows the one-question-at-a-time protocol without asserting exact wording.
- Prove manual form fallback, one-session conflict behavior, reconnect labeling, and structured launch errors.
- Prove starting the architect creates no plan and writes no live-session plan identifier.
- Prove the existing console receives one addressed launch and no duplicate WebSocket/terminal listener is mounted.
Verification gates
- Run focused suites per delivery slice.
- Run the complete unit suite after adapter migration and after recommendation integration.
- Run representative Web and MCP integration journeys before completion.
- Update documentation examples and capability matrices in the same slice that changes behavior.
Out of Scope
- Persisting a plan identifier on live study-session state.
- Automatically selecting a plan when a normal study session starts.
- Automatically running start, midpoint, or end checkpoints from session events.
- Automatically completing milestones from study-session evidence.
- Hard-blocking off-plan study or turning plan focus into an exclusion filter.
- Enforcing exactly one active plan.
- Changing the one-active-session invariant or introducing a second session authority.
- Building a second planning-specific PTY, ACP, WebSocket, or terminal implementation.
- Wholesale merge or resurrection of the archived browser-architect branch.
- Two-way editing from second-brain projections.
- Provider/model selection changes unrelated to the existing agent adapter and launch interfaces.
- Scheduling autonomous recurring planning sessions.
- Replacing the current Markdown source of truth with SQLite.
Further Notes
- Study Plans are current public functionality and were not removed. This spec closes integrations that were never completed on main.
- The current plan-aware product boundary is documented accurately in the Study Plans guide; stale installer language claiming that an active plan already changes Now must be corrected.
- The application-seam migration must close the existing active-status readiness bypass and surface silent checkpoint-index false returns before new transports depend on it.
- The current targeted plan/focus/Web/MCP suites pass. Preserve that behavior as the migration baseline.
- This issue is intentionally one implementation specification. Break delivery into tracer-bullet tickets after approval, following the stated ordering and dependency edges.
Problem Statement
StudyLoop can create, persist, activate, and evaluate evidence-grounded Study Plans, but the plan is disconnected from the product surfaces learners use to decide and act. Activating a plan does not influence
studyloop nowor Today, live study sessions are not plan-bound, the Web UI cannot launch the Study Plan Architect, and MCP clients cannot manage or evaluate plans.This creates a misleading gap between a plan being active and the system behaving as though it matters. Policy is also duplicated across CLI and Web callers, including activation readiness and milestone mutation, which permits inconsistent behavior such as creating an active-but-unready plan through one Web path.
Solution
Introduce one deep
PlanApplicationmodule as the shared seam for Study Plan use cases. CLI, Web, MCP, and recommendation callers use its immutable views, domain errors, lifecycle changes, assessments, planning briefs, and active-plan guidance instead of mutating plan documents directly.Use this seam to deliver three coordinated capabilities:
studyloop now, Today, recap, and MCPget_next_actionremain consistent.Live study-session binding remains a separate future feature. This change launches planning conversations and biases recommendations, but does not persist a plan identifier on live session state or automatically complete milestones.
User Stories
studyloop nowto consider my next milestone, so that activating a plan changes what StudyLoop recommends.Implementation Decisions
Shared plan application module
Create a use-case-oriented
PlanApplicationmodule with six cohesive operations:Do not expose the plan store or mutable domain objects to transport adapters. Do not create one generic arbitrary-action interface. Storage, evaluator, and clock substitution remain internal seams because there is currently one real Markdown store.
Application invariants
Active-plan guidance and ranking
Extend the shared Now result additively. Include top-level active-plan summaries, energy-deferred milestones, completion actions, and warnings. Add an optional explicit plan reference to each recommendation containing plan and milestone identity. Do not hide the stable plan contract in open-ended metadata.
CLI Now, Web
/api/now, Today, recap, and MCPget_next_actioncontinue to consume the same decision result. The MCP wrapper also gains the existing interleave option for parity.Web architect launch
planningsession purpose and resolve the existing Study Plan Architect persona and shared protocol instead of hardcoding the normal focus persona.PlanApplication.prepare planningbefore launch.MCP lifecycle parity
Register thin MCP adapters over
PlanApplicationfor:list_study_plansget_study_planget_planning_interviewcreate_study_planupdate_study_planset_study_plan_statusset_study_plan_milestoneevaluate_study_plandelete_study_planRaw Markdown replacement remains an import/editor capability rather than the default agent mutation. Deletion requires explicit confirmation. Reindex administration, storage paths, downloads, and live-session binding are not MCP lifecycle parity.
Delivery order
Update the normative capability specs for active learning decisions, MCP, Web UI, agent adapters, and CLI plan behavior as implementation slices land. Record a new ADR only if the shared application seam or planning-purpose session semantics remain load-bearing and are not already captured by existing source-of-truth/session-authority decisions.
Testing Decisions
Tests assert external behavior through the highest available seam. They must not assert private helper calls, internal file layout beyond documented source-of-truth contracts, framework-specific implementation details, or model prose.
Application interface
Adapter migration parity
Recommendation behavior
MCP
Web architect
Verification gates
Out of Scope
Further Notes