amosblomqvist
27c5d9df19
practice slice 4 — pipeline, registry, API, feed
src/agent/subagents/practice-pipeline.ts (sibling of practice.ts —
orchestration vs calls): createPracticePipeline(graphStore+practiceStore
+chatStore+PracticeModels). Fire-and-forget front doors returning
{set, done}: createProblemSet (refuse → resolve selection (chatId =
ANY-provenance membership per brief; nodeIds raw) → chains → snapshot →
createSet partitioning → registry row → runPartitioner → stubs land
(generating) → ONE generator per problem behind the process-wide
3-permit abort-aware semaphore (__lhPracticeSlots, extraction idiom) →
per-problem failure isolation → ready (errored problems included);
abortPractice (idempotent: controllers + 'Aborted' marks; dropped
grades keep answers, re-submittable); submitAnswers (ready-only,
already-graded rejects, one grading job per answer under the same
semaphore); deleteProblemSet (abort-first). Per-set write mutex on
globalThis (__lhPracticeLocks, audit-lock idiom); registry
__lhPracticeRuns one row per set per kind; boot sweep marks orphaned
partitioning/generating sets 'Interrupted (server restarted)'. Typed
errors: EmptySelection/UnknownChat/SetNotFound/SetNotReady/BadAnswers.
Usage folds stage logs into the registry row (v1: completion-folded).
src/server/practice.ts: thin service — strict params parsing, typed
error → response mapping (503 envelope family, 400/404/409), list/get.
Routes: POST+GET /api/practice/sets (202 {id}), GET+DELETE
/api/practice/sets/[id], POST /api/practice/sets/[id]/answers (202).
Composition root: chat-handler wires createPracticePipeline (engineFor
fresh + providerKeyMissing gate) exported as ; barrel re-
exports. Feed: observability activityFeed() += practice rows
(ActivityPractice); dock blobs (process 'practice', GraduationCap
icon, set-keyed abort); /api/activity/abort kind 'practice'.
tests/practice-pipeline.test.ts — 13 tests: end-to-end (stubs mid-
flight via gated generators, coverage complete), failure isolation,
3-permit semaphore pin, abort mid-generation, registry shape pins,
refusal-before-create, chatId any-provenance selection, typed errors,
answers→grades land + graded rejects, boot sweep (orphan + live-row),
delete. 1114/1114, tsc 0, lint 0, build 0.
2026-09-29 18:31:53 +03:00
..
2026-09-19 15:24:26 +03:00
2026-09-24 02:10:06 +03:00
2026-09-25 21:24:43 +03:00
2026-09-22 00:02:07 +03:00
2026-09-19 22:52:40 +03:00
2026-09-19 20:54:16 +03:00
2026-09-24 23:20:59 +03:00
2026-09-28 23:30:11 +03:00
2026-09-27 09:13:34 +03:00
2026-09-23 15:37:34 +03:00
2026-09-24 19:33:35 +03:00
2026-09-28 22:37:18 +03:00
2026-09-23 03:53:57 +03:00
2026-09-24 20:06:22 +03:00
2026-09-26 21:45:51 +03:00
2026-09-27 04:36:00 +03:00
2026-09-29 02:25:32 +03:00
2026-09-25 20:12:57 +03:00
2026-09-23 00:19:16 +03:00
2026-09-25 23:32:13 +03:00
2026-09-12 06:02:40 +03:00
2026-09-23 20:20:36 +03:00
2026-09-23 20:20:36 +03:00
2026-09-29 04:10:38 +03:00
2026-09-24 19:25:37 +03:00
2026-09-29 02:25:32 +03:00
2026-09-23 03:53:57 +03:00
2026-09-27 04:14:42 +03:00
2026-09-25 02:39:11 +03:00
2026-09-29 02:25:32 +03:00
2026-09-22 16:56:44 +03:00
2026-09-28 23:30:11 +03:00
2026-09-19 13:16:34 +03:00
2026-09-19 15:24:26 +03:00
2026-09-19 16:52:09 +03:00
2026-09-27 08:55:13 +03:00
2026-09-26 01:52:47 +03:00
2026-09-27 08:55:13 +03:00
2026-09-27 00:47:48 +03:00
2026-09-29 18:14:30 +03:00
2026-09-29 18:31:53 +03:00
2026-09-29 17:53:36 +03:00
2026-09-29 17:48:20 +03:00
2026-09-29 04:39:01 +03:00
2026-09-26 00:37:46 +03:00
2026-09-27 04:14:42 +03:00
2026-09-27 09:13:34 +03:00
2026-09-27 09:13:34 +03:00
2026-09-25 23:32:13 +03:00
2026-09-29 04:30:15 +03:00
2026-09-27 09:13:34 +03:00
2026-09-27 00:48:46 +03:00
2026-09-24 15:51:40 +03:00
2026-09-25 01:52:20 +03:00
2026-09-23 22:05:58 +03:00
2026-09-19 13:16:34 +03:00
2026-09-28 23:30:11 +03:00
2026-09-24 15:26:22 +03:00
2026-09-27 00:47:48 +03:00
2026-09-29 03:00:57 +03:00
2026-09-25 20:02:19 +03:00
2026-09-17 13:48:04 +03:00
2026-09-29 04:30:15 +03:00
2026-09-26 23:53:43 +03:00
2026-09-22 00:02:07 +03:00
2026-09-22 00:02:07 +03:00
2026-09-29 02:25:32 +03:00
2026-09-24 20:06:22 +03:00
2026-09-27 00:48:46 +03:00
2026-09-28 22:37:18 +03:00
2026-09-29 18:14:30 +03:00
2026-09-27 08:55:13 +03:00
2026-09-28 23:30:11 +03:00
2026-09-22 21:55:33 +03:00
2026-09-28 23:30:11 +03:00
2026-09-29 18:14:30 +03:00
2026-09-26 01:52:47 +03:00
2026-09-22 22:05:27 +03:00
2026-09-25 23:32:13 +03:00
2026-09-27 09:13:34 +03:00
2026-09-27 08:55:13 +03:00
2026-09-25 02:26:37 +03:00
2026-09-01 01:57:13 +03:00
2026-09-29 04:30:15 +03:00
2026-09-25 23:32:13 +03:00
2026-09-29 18:14:30 +03:00