commit ef01fcd6406aa333ce294f1cfe5c236547664eb7
parent af054e224d5cf9021fe1696411e7c60fd0e6bf55
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Fri, 9 Oct 2026 13:08:39 -0400
umtool: the two-section Note spec waits for its mark before reading notes.json; the edit-guard test takes its kind from the registry
From the B5 umtool e2e run: the new article-notes test read notes.json
before the save had landed (the existing tests wait for the mark first, and
now this one does), and projects.spec's registry guard caught a kind id
spelled out in lib/report/edit-guard.test.mjs — it now asks the registry for
a kind that takes notes. Two comments name REPORTS_DIR instead of a home path.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Diffstat:
4 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/umtool/docs/cli.md b/umtool/docs/cli.md
@@ -56,7 +56,7 @@ projects answering to one name is reported, never resolved by picking one.
"The checkout" is the one the CLI script itself lives in (`<repo>/umtool/bin/umtool.mjs`),
whatever directory it is run from — `umtool notes --all` from a report workspace under
-`~/reports` reads the corpus's sites. The app (`next dev`/`start`) finds it by walking up
+`REPORTS_DIR` reads the corpus's sites. The app (`next dev`/`start`) finds it by walking up
from its cwd to `pnpm-workspace.yaml`.
| `VIDEO_ROOT` (`song/spec.mjs`, `song/video-dir.mjs`) | `~/reports/quartering-uh-song/videos` |
diff --git a/umtool/e2e/article-notes.spec.ts b/umtool/e2e/article-notes.spec.ts
@@ -100,12 +100,14 @@ test("a selection across two sections gets a Note, anchored in the first", async
await page.getByLabel("note text").fill("This runs on.");
await page.getByRole("button", { name: "save note" }).click();
+ // The mark is drawn once the note is saved: then the file is there.
+ await expect(page.locator('[data-block="first"] mark[data-note]').first()).toBeVisible();
+ await expect(page.locator('[data-block="later"] mark[data-note]')).toHaveCount(0);
const anchor = JSON.parse(readFileSync(NOTES, "utf8")).notes[0].anchor;
expect(anchor).toMatchObject({ kind: "text", section: "first" });
expect(anchor.quote.startsWith("Nobody checked the claim")).toBe(true);
expect(anchor.quote).toContain("for the record.");
expect(anchor.quote).not.toContain("different show");
- await expect(page.locator('[data-block="first"] mark[data-note]').first()).toBeVisible();
});
test("section, whole-article and citation notes; resolve, reopen, reply, filters", async ({ page }) => {
diff --git a/umtool/lib/paths.mjs b/umtool/lib/paths.mjs
@@ -205,7 +205,7 @@ export function findRepoRoot(start) {
* server, a test runner, report-to-video's own CLIs).
*
* A CLI is run from wherever its user stands: `node ~/…/umtool/bin/umtool.mjs
- * notes --all` from a report workspace under ~/reports has no
+ * notes --all` from a report workspace under REPORTS_DIR has no
* pnpm-workspace.yaml above its cwd, so the cwd walk fell back to the cwd's
* parent and SITES_DIR (and CHANNELS_DIR) pointed at nothing. The script's own
* path names the checkout it is from. Only the bin/ entries: the server keeps
diff --git a/umtool/lib/report/edit-guard.test.mjs b/umtool/lib/report/edit-guard.test.mjs
@@ -11,17 +11,21 @@ import path from "node:path";
import test from "node:test";
import { fileURLToPath } from "node:url";
import { readNotes } from "../annotations/store.mjs";
+import { PROJECT_KINDS, kindTakesNotes } from "../projects/kinds.mjs";
import { updateClip } from "./manifest.mjs";
import { withEditNotes } from "./edit-guard.mjs";
const CLI = fileURLToPath(new URL("../../bin/umtool.mjs", import.meta.url));
+// A kind that takes notes, from the registry -- never named here (projects.spec
+// refuses a kind id outside lib/projects/).
+const NOTES_KIND = PROJECT_KINDS.find((k) => kindTakesNotes(k.id)).id;
async function project(manifest) {
const root = await mkdtemp(path.join(tmpdir(), "umtool-editguard-"));
const dir = path.join(root, "ws", "clipcut");
await mkdir(dir, { recursive: true });
await writeFile(path.join(dir, "video.manifest.json"), `${JSON.stringify(manifest, null, 2)}\n`);
- return { root, dir, project: { id: "ws/clipcut", dir, kind: "report-video" } };
+ return { root, dir, project: { id: "ws/clipcut", dir, kind: NOTES_KIND } };
}
const MANIFEST = (generated) => ({