# DeepSeek Harness Interactive Learning [中文](README.md) `@dsh-portable/interactive-learning` adds an explicit `learning` Agent preset to DeepSeek Harness. Standard, Code, Minimal, and Cordis keep their original tool schemas and prompts. ## Architecture - The package root provides the `learningActivities` Host broker and registers the `learning/state` session-event discriminator for strict validation. Import the bootstrap before restoring persisted sessions; the package registers no model-visible tools. - `./agent` is mounted only by the Learning preset. Its initial model-facing catalog contains the compact `learning_visual_select`, silent `learning_state_update`, and optional `learning_checkpoint_select` tools. A selector exposes only the chosen visual/checkpoint payload schema for the next model step. Its standing policy comes from one canonical TypeScript source rather than being duplicated in the Skill. - The preset also keeps attachment continuation, Skill loading, and `web_search`. Web search grounds current or contested-topic explanations in sources without adding shell, editing, or automation tools to the preset. - `./client` renders visuals and optional checkpoints inline. State updates have an explicitly empty tool view. V1/V2 activity calls and V3 visuals retain read-only replay support. - `./protocol` owns the closed, versioned declarative contracts. - `preset/learning/skills/interactive-teaching` provides detailed teaching judgment on demand. The ordinary conversation remains the default. A visual is an illustration inside a normal assistant response, not a form that owns the user turn. A reflective pause is the sole deliberate wait: the wire-compatible checkpoint tool is used only when the learner's response will change the next move, then terminates after one result. ## Learn intent and first-turn route The Learning preset classifies the request before choosing a teaching route. Definitions, bare concept names, ELI5/beginner requests, persistent confusion or rustiness, prerequisites and learning paths, conceptual why/how questions, and requested quizzes, flashcards, or study guides are learn intent. Coding or debugging, direct calculation, personal troubleshooting, translation, news or fact lookups, resource recommendations, and opinion requests stay on their ordinary task route. Current or contested topics remain learn intent when the user asks for structured understanding and use Web search before substantive source-backed explanation. Bare concepts get one route-changing calibration question; definitions, clear confusions, and clear goals start the minimum useful explanation. Requested study resources are created directly. Once that learning segment is active, short answers, confusion, pressure, and follow-up questions inherit it instead of being reclassified as new requests. An explicit task/topic switch, reset, completion, or closing acknowledgement ends the segment and restores ordinary routing. After refresh or process resume, an unfinished persisted learner goal restores this inheritance even though the process-local route cache is empty. ## Non-blocking learning flow 1. A short, underspecified `learn X`/`teach me X` request gets one calibration question whose answer changes the route. An explicit beginner/from-zero request starts with one minimum concept immediately; an explicit complete overview or current/contested survey can go directly to exposition. 2. The assistant explains the missing idea in ordinary prose. When manipulation is genuinely useful, it first calls `learning_visual_select` with one native kind and purpose. 3. The selected kind-specific `learning_visual` schema is exposed for the next model step and carries the selected purpose and learner action/question; no eight-kind visual catalog is injected into the initial context. While arguments are streaming, the tool call's place names the visual being prepared instead of showing a generic wait. 4. Validation returns `visual-result@4` immediately. No lesson token, pending question, submit button, reveal call, or five-minute user wait is created. The result distinguishes `ready` from `unavailable`: a composition without the Learning Client renders nothing, so the assistant carries the same explanation in prose and never points at a figure the learner cannot see. An unrendered visual is also not recorded as a teaching move that happened. 5. The chart renders in the tool call's place and remains interactive after the completed call is replayed. 6. The assistant continues with the interpretation and, if useful, one natural question. The learner answers through the normal composer on the next turn. This removes the old Question → Reveal split that duplicated rounds and left a model turn running while it waited for the learner. The surrounding prose must still make sense if a Client cannot render the enhancement. ## Session-scoped learner state Learning keeps a small, tentative teaching state for the current session only: the learner's immediate goal, demonstrated prior knowledge, current gap or misconception, phase, last explanation/question, learner-response assessment, next move, move fingerprint, learner-evidence-derived support need, urgency or stuck evidence, assessment context, bounded failed-move history with its representation and reason, and independently demonstrated evidence including fresh transfer. The production path is explicit and auditable: 1. The ordinary learner message remains in the normal conversation transcript. When a concrete observation materially changes teaching, the model may call the internal `learning_state_update`; it must not call it mechanically. 2. A completed visual and a checkpoint terminal result contribute only facts the Host can observe deterministically. Submission alone records an unevaluated learner action; it never implies correctness, independence, progress, or mastery. 3. Every accepted update appends a strict, identity-free full snapshot as the `learning/state` session event. The Host must import the bootstrap before restoring a session so the event type is registered; refresh and resume then fold and validate the snapshot normally. 4. Before every subsequent model step, the dynamic prompt context folds the durable events and renders a bounded 100–300-token tentative summary. Persisted snapshots do not contain a session id. Refresh and resume fold the same event log; a fork rebinds inherited snapshots to its new identity and then diverges independently. Reset appends a cleared snapshot and advances the revision, so a late asynchronous update cannot resurrect prior state. Disposal drops only the process-local fold cache. This is not a cross-session learner profile, personality model, learning-style classifier, or long-term mastery record. A mastery claim in an ordinary message is not promoted automatically; when the learner explicitly corrects this tentative state, however, `correct` honors the mastery override and retains its user-correction provenance. Low-confidence evidence remains useful for choosing support but cannot promote mastery automatically. A medium-or-higher-confidence, correct, independent explanation or complete attempt may end the current teaching segment while mastery remains `emerging`; automatic inference promotes `transfer` only from explicit fresh-context evidence. If the learner simply wants to stop being quizzed, mark `phase` and `nextMove` as `complete` in the correction without fabricating transfer evidence. ## Session-scoped learning route Most learning segments need no route at all: a single concept, a direct answer, or a short correction is complete without one. A route is recorded only when the goal genuinely spans several dependent moves — a multi-section source, a procedure with real prerequisites, or a multi-part objective the learner stated. The route lives in the learner state for the current session and is a revisable hypothesis rather than a contract: - At most 6 steps, with `pending`, `active`, and `evidenced` as the only statuses, and never more than one `active`. - A step advances only on evidence the learner produced, never because the material was covered. - Revising a route preserves whatever was already `evidenced` under the same step id, so demonstrated progress is never erased. - The model context carries the objective and the current step only, never the whole list, so the route cannot be read back as a checklist to march through. - Demonstrated transfer, or a medium-or-higher-confidence complete explanation/attempt, ends the segment however many steps remain; an unfinished route is never a reason to continue. - A learning-boundary reset clears the route with the rest of the state. ## Optional reflective pause (wire-compatible checkpoint protocol v1) `dsh-learning/checkpoint@1` is reserved for a prediction, explanation, contrast, design choice, debugging diagnosis, boundary case, or transfer application that will materially change the next teaching move. It is not the default input path and must never become a per-turn Continue ceremony. - At most one checkpoint may be pending in a session and at most one distinct checkpoint may be emitted in a model step. - Its five closed kinds are `free_text`, `single_choice`, `numeric`, `prediction`, and `code_slot`. Single-choice results carry the stable option id; labels are presentation only. - The card header names the cognitive move being requested — predict, explain, contrast, transfer, or attempt — rather than an internal label such as "checkpoint", which the standing policy forbids for ordinary turns. - The pending payload may contain only the current prompt, context, expected evidence, answer-free options, and a self-sufficient fallback. Correct answers, grading rubrics, solutions, and future steps are rejected. - The terminal statuses remain `submitted`, `skipped`, and `cancelled`. New non-submitted results also state whether the learner acted or the Client, timeout, Host, or provider made the checkpoint unavailable; old v1 receipts without that reason remain readable. Refresh recovers the same wait and draft; call and receipt replays are idempotent, while conflicting reuse fails closed. - Skip, cancel, timeout, renderer failure, or an unavailable rich Client restores ordinary conversation without a Reveal, animation, Continue, or second wait. ## Semantic visual protocol v4 `dsh-learning/visual@4` selects a trusted native renderer by concept semantics: - `plot` for functions, data, probability, bars, and quantitative relationships; - `node_link` for neural-network layers, trees, processes, causality, and topology; - `scene_2d` for geometry, vectors, forces, and annotated spatial schematics; - `relation` for comparisons, matrices, classifications, and set membership; - `timeline` for historical events, discoveries, phases, and eras; - `formula_steps` for derivations, algebraic transformations, and proof chains; - `study_map` for anchored sections, prerequisites, and concept roles in reference material; - `recall_deck` for hinted active-recall cards. Reveal and mastered/review actions keep local replay state and, when the Host bridge is available, are recorded as unverified session-scoped learner observations. Resetting the deck clears only the local badges; it does not erase Host observations; - `data_table` for typed records with sorting, filtering, selection, outlier marks, and a linked chart; - `state_transition` for event-driven state changes with guards and actions; - `sequence_buffer` for discrete slots, pointers, ranges, and step snapshots; - `sequence_diagram` for ordered sync, async, and return messages between participants; - `code_trace` for declarative replay of code lines, variables, call stacks, loops, and output; - `field_2d` for scalar heatmaps, contours, and vector fields; - `causal_loop` for signed, delayed reinforcing and balancing feedback loops. Any kind can add local sequence frames that progressively focus declared ids. The controls remain exploratory and never replace the ordinary conversation composer. Renderers provide a visible title, keyboard-accessible inspection, responsive layouts, structured text alternatives, and a local error boundary. `state_transition`, `sequence_buffer`, and `code_trace` can also carry compact kind-specific snapshots so states, pointers, variables, and stack frames really change from one step to the next. Plot content supports optional bounded sliders, static points, polylines, bars, computed curves, stable axes, and parameter-derived metrics. A slider is omitted when manipulation is not the lesson. In particular, formula recall is answered directly; a requested network structure is rendered as nodes and explicit edges instead of being substituted with a curve or Markdown art. When the learner supplies a document, PDF, slide deck, or several sources, the system preserves observed section and page/title anchors, uses `study_map` for a navigable overview when useful, and then routes each concept to its more specific renderer. It does not flatten a whole source into one mega-graph or mechanically turn every attachment into flashcards. Curves use a closed recursive mathematical AST. Supported leaves are `constant` and `variable`; binary operators are `add`, `sub`, `mul`, `div`, `pow`, `min`, and `max`; unary operators include trigonometric (`sin`, `cos`, `tan`, `atan`), activation (`relu`, `leaky_relu`, `step`, and numerically stable `sigmoid`), probability (`normpdf`), and basic (`neg`, `abs`, `sqrt`, `exp`, `log`, `floor`, `ceil`) functions. Curve variables are `x` plus declared parameter ids. `leaky_relu` uses a 0.01 negative slope, `step` switches at zero, and `normpdf` is the standard normal density; other normal distributions can be composed with arithmetic nodes. Metrics may use declared parameters but not `x`. The model schema and runtime parser share the same expression-depth limit. Unknown fields, undeclared variables, non-finite values, excessive payloads, invalid references, and invalid ranges are rejected. Model-provided HTML, Markdown diagrams, SVG markup, and JavaScript are never executed. A payload the schema accepts always reaches its renderer; it never degrades into Markdown, the description text, or an error box. When a series has no value inside the declared axes — `log` or `sqrt` over a negative domain, or a curve that sits entirely outside the y range — the chart still draws, states that no values fall inside the current axes, and marks that series in the legend, rather than leaving the learner with a frame that looks broken. V3 parameter charts and V1/V2 activities remain parseable only for historical replay. Their model tools are no longer exposed by the Learning preset. A failed historical result is shown as an explicit error/fallback instead of a disabled “completed” activity. ## Design system and accessibility Every learning surface shares one set of design tokens, declared on `[data-learning-scope]` in `src/client/tokens.module.css`. The two CSS Modules compile into separate `