Sprinter Docs

Exercises

Workshop-style ranking, voting, scoring, assessment, generating, and answering exercises composed onto sessions + responses.

Sprinter exercises are the OG Amble workshop primitive — ranking, voting, scoring, assessment, generating, answering — composed onto Sprinter's sessions, views, criteria_sets, and entity_responses substrate. No new tables, no new session_type. The discriminator is sessions.metadata.exercise_kind.

Spec & plan: documents/work/2026-05-03-exercises-module/spec.md and plan.md. PR1 ships the foundation; PR2 ships the runtime; PR5-slim ships the agent-facilitated demo.

Architecture

Facilitator (wizard surface)              Participants (rank/swipe/form surface)
        │                                          │
        ▼                                          ▼
  exercise-setup wizard ──────────► Exercise (mixed session)
   1. pick kind                       metadata.exercise_kind
   2. attach criteria                 metadata.target_entity_ids[]
   3. select target entities          metadata.invited_user_ids[]
   4. invite users                    metadata.timer
   5. set timer                       metadata.target_view_id


                                 Per-user response child sessions
                                 (session_type='response', status='draft')


                                 entity_responses (source='workshop')


                                 computeResponseAggregate / leaderboard

The diagram above is the entire module. Boxes on the right side are already-shipped Sprinter primitives — features/sessions, features/views, features/responses. The new code is the LEFT side (wizard + the kind→surface mapping + the registered tool) plus PR4's Inngest timer. Everything else is composition.

Platform-native pattern: one tool, two callers

createExercise is registered as a first-class AI tool in features/tools/exercise-tools.ts. The setup wizard's "Create" button and an in-chat agent delegation both invoke that same tool — neither uses a custom code path. The only observable downstream difference is session_events.metadata.origin:

Caller classrolemetadata.originmetadata.agent_slug
Wizard / createExerciseActionuser"user"null
Agent in chat / heartbeatagent"agent"<slug>

This keeps humans + agents truly interchangeable. The PR5 demo ("Run a 10-minute scoring exercise on these 5 concepts with the team") is a tool-call away from PR1's foundation.

Six exercise kinds → view surfaces

KindSurfaceParticipant action
rankingrankDrag the target entity list into preferred order
votingswipeSwipe / multi-select yes-no
scoringformScore each entity on each criteria dimension
assessmentformSingle-entity multi-criteria scoring
generatingformOpen-ended brainstorm — produce new concepts
answeringformFree-text answers to facilitator-set questions

The votingswipe mapping delivers the OG Trinder pattern as a free byproduct.

PR1 surface

Shipped:

  • features/exercises/types.tsEXERCISE_KINDS, ExerciseTimerSchema, ExerciseMetadataSchema, parseExerciseMetadata, EXERCISE_SURFACE_BY_KIND, assertNever.
  • features/exercises/server/create-exercise.ts — manual-rollback transactional insert (view + session + session.created event).
  • features/exercises/server/list-exercises-for-user.ts — RLS-respecting gallery filter.
  • features/tools/exercise-tools.tscreateExercise registered as an AI tool with requiredPermission: "entities.team.create".
  • app/exercises/page.tsx — invitee gallery.
  • app/exercises/new/page.tsx — minimal setup form (the polished 5-step wizard is the iteration-2 follow-up).

Cross-references

  • content/docs/features/tool-system.mdx — tool registry and dispatch.
  • content/docs/features/sessions.mdx — session lifecycle and session_events.
  • content/docs/features/view-system.mdx — surface types (rank, swipe, form).
  • content/docs/features/response-system.mdxentity_responses, criteria sets, aggregation.

On this page