Skip to content

Persist durable interview problem attempts and resumable workspaces #61

Description

@rosshd

Parent: #56

Depends on: the activity-contract and problem-catalog children of #56.

Related: #54.

Problem

The current drill implementation stores one active_drill path and appends tutor output after /check.

It does not represent a durable problem attempt with planning evidence, code revisions, test iterations, hint use, elapsed time, abandonment, resumption, or later transfer.

Without an attempt lifecycle, the tutor cannot distinguish an independent solve from a heavily scaffolded completion or explain why a problem should return later.

Goal

Add a durable, local-first problem-attempt model and resumable workspace lifecycle.

Attempt record

Track:

  • Attempt ID, problem ID and revision, topic, profile, language, and activity ID.
  • Start, last-active, completion, abandonment, and resumption timestamps.
  • Practice, placement, mastery-check, review, or mock-interview purpose.
  • Initial clarification and plan when requested.
  • Workspace location and bounded code snapshots or content hashes.
  • Public and hidden test runs, outcomes, timeouts, and failure classes.
  • Hints requested, scaffolding received, editorial or full-solution exposure, and tutor interventions.
  • Learner complexity explanation, edge-case reasoning, and final reflection.
  • Final disposition such as solved independently, solved with help, partial, abandoned, invalid, or runner failure.
  • Skill-evidence references and scheduled follow-up or transfer activity.

Storage and durability

  • Keep attempt state out of human-edited topic frontmatter.
  • Use an atomic sidecar record plus append-only events, consistent with existing local ownership.
  • Keep workspaces under the topic's local drill or activity directory.
  • Store relative or safely rebased workspace references where practical.
  • Preserve the learner's code and input before provider calls or external tool launches.
  • Make retry after process or provider failure explicit and idempotent.
  • Never commit attempts, learner code, private problem content, or generated workspaces.

Lifecycle behavior

  • Starting the same problem creates a new attempt unless the learner explicitly resumes an unfinished one.
  • Only one active mutation owner may update an attempt at a time.
  • A completed attempt remains immutable except for additive evaluation or review evidence.
  • Abandonment and cancellation remain distinct.
  • Runner or adapter failures do not count as learner failure.
  • Full-solution exposure marks later success as scaffolded until independent transfer evidence exists.

Acceptance criteria

  • Attempts survive CLI restart, provider failure, editor exit, and interrupted test execution.
  • The learner can list, inspect, resume, abandon, and retry attempts.
  • Code and learner input are saved before failure-prone external actions.
  • Hint and scaffolding history is sufficient to distinguish independent and assisted completion.
  • Attempt events are idempotent and do not duplicate test runs or mastery evidence on replay.
  • Problem revisions remain traceable.
  • A runner failure cannot be misclassified as an incorrect solution.
  • Completing tests does not independently grant mastery.
  • Tests cover new, resumed, concurrent, abandoned, completed, corrupted, migrated, and provider-failure attempts.
  • Existing /drill and /check behavior remains available during migration.
  • make check passes.

Out of scope

  • Cloud synchronization.
  • Git-backed version control inside every attempt.
  • Recording every keystroke.
  • Global analytics uploads.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions