practice: the learner's creation note — optional free-form input carried to partitioner + generators (owner, 2026-09-29)

- dialog: optional 'Anything else?' textarea (typing-only, 2000-char mirror)
- API: body gains note? — trimmed, whitespace-only omitted, hard 400 over 2000
- pipeline: note persisted on the set and threaded to both agent stages
- agents: THE LEARNER'S NOTE prompt block (present only when set) + the
  weighed-never-owed stance pinned in both doctrines
- fix en route: doubled THE PARAMETERS heading in both prompts since slice 3
  (renderParams owns the heading; the literal blocks removed)
This commit is contained in:
amosblomqvist
2026-09-29 22:16:28 +03:00
parent cf0ec4a2f0
commit 06032769d2
15 changed files with 593 additions and 266 deletions
+26
View File
@@ -41,3 +41,29 @@ describe("createPracticeSetResponse — strict named-level params", () => {
assert.equal(await statusOf("high"), 400);
});
});
describe("createPracticeSetResponse — the learner's note (owner, 2026-09-29)", () => {
const PARAMS = { ladderRung: 2, cueDistance: 1, presentation: "theory" } as const;
it("non-string note → 400", async () => {
const res = await createPracticeSetResponse({ ...NODE_IDS, params: PARAMS, note: 42 });
assert.equal(res.status, 400);
});
it("over 2000 characters → 400 (the API is the law; the textarea's maxLength mirrors it)", async () => {
const res = await createPracticeSetResponse({ ...NODE_IDS, params: PARAMS, note: "x".repeat(2001) });
assert.equal(res.status, 400);
const body = (await res.json()) as { error: string };
assert.match(body.error, /over 2000 characters/);
});
it("exactly 2000 passes the note check (boundary — the next check, not the note, refuses)", async () => {
// Malformed nodeIds AFTER a max-length note: reaching the nodeIds
// error proves the note check passed (all checks are rejecting-path;
// the pipeline is never reached — this suite's doctrine).
const res = await createPracticeSetResponse({ nodeIds: 5, params: PARAMS, note: "x".repeat(2000) });
assert.equal(res.status, 400);
const body = (await res.json()) as { error: string };
assert.match(body.error, /Body must be/);
});
});