Public: anyone can read this; the crew can change it.

"migrate > a migrated fork shows its trail, and its owner can hide it and bring it back" passes every time on a loaded check machine #5548

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

mason/forge:mason/5326-migrate-a-migrated-fork-shows-its-trail → main 1 commit fork

  • Merged. mason/5326-migrate-a-migrated-fork-shows-its-trail was merged into main as 7004365.

Review

Sign in to review this change.
2 files changed +96 −59
src/apps/scaffold.ts +87 −57
@@ -2674,7 +2674,7 @@ const SITE_TEST = `/**
26742674 * inherits every one of these and fails its own \`bun test\` if it loses one.
26752675 */
26762676 import { afterAll, expect, test } from "bun:test";
2677 import { mkdtempSync, readFileSync } from "node:fs";
2677 import { mkdtempSync, readFileSync, rmSync } from "node:fs";
26782678 import { tmpdir } from "node:os";
26792679 import { join } from "node:path";
26802680 import { compress, MIN_BYTES } from "./compress.ts";
@@ -2685,13 +2685,17 @@ import { CARD, websiteLd } from "./site.ts";
26852685 import { serve } from "./server.ts";
26862686 import { ANON } from "./who.ts";
26872687
2688 const dataDir = mkdtempSync(join(tmpdir(), "app-"));
26882689 const server = serve({
26892690 port: 0,
2690 dataDir: mkdtempSync(join(tmpdir(), "app-")),
2691 dataDir,
26912692 identityKey: "a-key-only-the-forge-holds",
26922693 });
26932694 const base = \`http://\${server.hostname}:\${server.port}\`;
2694 afterAll(() => server.stop(true));
2695 afterAll(() => {
2696 server.stop(true);
2697 rmSync(dataDir, { recursive: true, force: true });
2698 });
26952699 const get = (path: string, headers: Record<string, string> = {}) =>
26962700 fetch(base + path, { headers, redirect: "manual" });
26972701
@@ -3481,8 +3485,8 @@ test("the terminal trusts its environment", () => {
34813485 });
34823486 `;
34833487
3484 const SIGNIN_TEST = `import { beforeAll, expect, test } from "bun:test";
3485 import { mkdtempSync } from "node:fs";
3488 const SIGNIN_TEST = `import { afterAll, beforeAll, expect, test } from "bun:test";
3489 import { mkdtempSync, rmSync } from "node:fs";
34863490 import { tmpdir } from "node:os";
34873491 import { join } from "node:path";
34883492 import { openDb } from "./db.ts";
@@ -3490,6 +3494,10 @@ import { begin, finish, sessionWho, verify, type Signin } from "./signin.ts";
34903494
34913495 const dir = mkdtempSync(join(tmpdir(), "app-"));
34923496 const db = openDb(dir);
3497 afterAll(() => {
3498 db.close();
3499 rmSync(dir, { recursive: true, force: true });
3500 });
34933501 const ISS = "https://forge.test";
34943502 const b64 = (v: unknown): string => Buffer.from(JSON.stringify(v)).toString("base64url");
34953503 const generate = () =>
@@ -3639,7 +3647,7 @@ test("a session is a cookie that names a person, and only until it expires", ()
36393647 `;
36403648
36413649 const DB_TEST = `import { expect, test } from "bun:test";
3642 import { mkdtempSync } from "node:fs";
3650 import { mkdtempSync, rmSync } from "node:fs";
36433651 import { tmpdir } from "node:os";
36443652 import { join } from "node:path";
36453653 import { check, migrate, migrations, openDb } from "./db.ts";
@@ -3647,31 +3655,41 @@ import { check, migrate, migrations, openDb } from "./db.ts";
36473655 test("migrations apply once, in order, and the file checks out", () => {
36483656 const dir = mkdtempSync(join(tmpdir(), "app-db-"));
36493657 const db = openDb(dir);
3650 expect(check(db).version).toBe(migrations.length);
3651 // Opening again finds nothing to do — a migration that has run is history.
3652 expect(migrate(db)).toBe(migrations.length);
3653 expect(() => openDb(dir)).not.toThrow();
3654 expect(check(db)).toEqual({ version: migrations.length, integrity: "ok" });
3655 expect(
3656 db.query<{ journal_mode: string }, []>("PRAGMA journal_mode").get()
3657 ?.journal_mode,
3658 ).toBe("wal");
3659 expect(
3660 db.query<{ foreign_keys: number }, []>("PRAGMA foreign_keys").get()
3661 ?.foreign_keys,
3662 ).toBe(1);
3658 try {
3659 expect(check(db).version).toBe(migrations.length);
3660 // Opening again finds nothing to do — a migration that has run is history.
3661 expect(migrate(db)).toBe(migrations.length);
3662 expect(() => openDb(dir)).not.toThrow();
3663 expect(check(db)).toEqual({ version: migrations.length, integrity: "ok" });
3664 expect(
3665 db.query<{ journal_mode: string }, []>("PRAGMA journal_mode").get()
3666 ?.journal_mode,
3667 ).toBe("wal");
3668 expect(
3669 db.query<{ foreign_keys: number }, []>("PRAGMA foreign_keys").get()
3670 ?.foreign_keys,
3671 ).toBe(1);
3672 } finally {
3673 db.close();
3674 rmSync(dir, { recursive: true, force: true });
3675 }
36633676 });
36643677 `;
36653678
3666 const ACTIONS_TEST = `import { expect, test } from "bun:test";
3667 import { mkdtempSync } from "node:fs";
3679 const ACTIONS_TEST = `import { afterAll, expect, test } from "bun:test";
3680 import { mkdtempSync, rmSync } from "node:fs";
36683681 import { tmpdir } from "node:os";
36693682 import { join } from "node:path";
36703683 import { addNote, deleteNote, listNotes } from "./actions.ts";
36713684 import { openDb } from "./db.ts";
36723685 import type { Who } from "./who.ts";
36733686
3674 const db = openDb(mkdtempSync(join(tmpdir(), "app-actions-")));
3687 const dir = mkdtempSync(join(tmpdir(), "app-actions-"));
3688 const db = openDb(dir);
3689 afterAll(() => {
3690 db.close();
3691 rmSync(dir, { recursive: true, force: true });
3692 });
36753693 const anon: Who = { role: "anon" };
36763694 const alice: Who = { role: "user", id: "u1", name: "alice" };
36773695 const bob: Who = { role: "user", id: "u2", name: "bob" };
@@ -3729,8 +3747,8 @@ const CONTRACT_TEST = `/**
37293747 * someone else — and calls the real actions. A rule written by hand in an
37303748 * action, or a cell changed without its door, fails here.
37313749 */
3732 import { expect, test } from "bun:test";
3733 import { mkdtempSync } from "node:fs";
3750 import { afterAll, expect, test } from "bun:test";
3751 import { mkdtempSync, rmSync } from "node:fs";
37343752 import { tmpdir } from "node:os";
37353753 import { join } from "node:path";
37363754 import {
@@ -3748,7 +3766,12 @@ import { contract } from "./contract.ts";
37483766 import { openDb } from "./db.ts";
37493767 import type { Who } from "./who.ts";
37503768
3751 const db = openDb(mkdtempSync(join(tmpdir(), "app-contract-")));
3769 const dir = mkdtempSync(join(tmpdir(), "app-contract-"));
3770 const db = openDb(dir);
3771 afterAll(() => {
3772 db.close();
3773 rmSync(dir, { recursive: true, force: true });
3774 });
37523775
37533776 /** The identity the evaluator acts as, as the forge would have signed it. */
37543777 function whoIs(identity: string): Who {
@@ -3843,7 +3866,7 @@ test("every door answers as the table says, as every identity", () => {
38433866 `;
38443867
38453868 const SERVER_TEST = `import { afterAll, expect, test } from "bun:test";
3846 import { mkdtempSync } from "node:fs";
3869 import { mkdtempSync, rmSync } from "node:fs";
38473870 import { tmpdir } from "node:os";
38483871 import { join } from "node:path";
38493872 import { openDb } from "./db.ts";
@@ -3855,7 +3878,10 @@ const KEY = "a-key-only-the-forge-holds";
38553878 const dataDir = mkdtempSync(join(tmpdir(), "app-"));
38563879 const server = serve({ port: 0, dataDir, identityKey: KEY });
38573880 const base = \`http://\${server.hostname}:\${server.port}\`;
3858 afterAll(() => server.stop(true));
3881 afterAll(() => {
3882 server.stop(true);
3883 rmSync(dataDir, { recursive: true, force: true });
3884 });
38593885
38603886 /** The headers the forge sends for a signed-in person. */
38613887 const as = (
@@ -4925,7 +4951,7 @@ const DESIGN_TEST = `/**
49254951 * anywhere but design/tokens.json.
49264952 */
49274953 import { expect, test } from "bun:test";
4928 import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
4954 import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
49294955 import { tmpdir } from "node:os";
49304956 import { join } from "node:path";
49314957 import { lint, rawColours, unknownTokens } from "../scripts/lint-design.ts";
@@ -5022,13 +5048,17 @@ test("the lint refuses a raw colour and a token that is not there", () => {
50225048 ),
50235049 ).toEqual(["a.css:1: --spcae-2 is not a token in design/tokens.json"]);
50245050 const root = mkdtempSync(join(tmpdir(), "app-lint-"));
5025 mkdirSync(join(root, "static"));
5026 mkdirSync(join(root, "src"));
5027 writeFileSync(join(root, "static", "extra.css"), "a {\\n color: #fff;\\n}\\n");
5028 writeFileSync(join(root, "src", "ok.test.ts"), "const red = '#f00';\\n");
5029 expect(lint(root)).toEqual([
5030 "static/extra.css:2: raw colour #fff — name it in design/tokens.json and use var(--…)",
5031 ]);
5051 try {
5052 mkdirSync(join(root, "static"));
5053 mkdirSync(join(root, "src"));
5054 writeFileSync(join(root, "static", "extra.css"), "a {\\n color: #fff;\\n}\\n");
5055 writeFileSync(join(root, "src", "ok.test.ts"), "const red = '#f00';\\n");
5056 expect(lint(root)).toEqual([
5057 "static/extra.css:2: raw colour #fff — name it in design/tokens.json and use var(--…)",
5058 ]);
5059 } finally {
5060 rmSync(root, { recursive: true, force: true });
5061 }
50325062 });
50335063 `;
50345064
@@ -5038,7 +5068,7 @@ const AUDIT_TEST = `/**
50385068 * written costs a log line, never the request.
50395069 */
50405070 import { afterAll, expect, spyOn, test } from "bun:test";
5041 import { mkdtempSync } from "node:fs";
5071 import { mkdtempSync, rmSync } from "node:fs";
50425072 import { tmpdir } from "node:os";
50435073 import { join } from "node:path";
50445074 import { addNote } from "./actions.ts";
@@ -5048,13 +5078,13 @@ import { serve } from "./server.ts";
50485078 import { sign } from "./who.ts";
50495079
50505080 const KEY = "a-key-only-the-forge-holds";
5051 const server = serve({
5052 port: 0,
5053 dataDir: mkdtempSync(join(tmpdir(), "app-audit-")),
5054 identityKey: KEY,
5055 });
5081 const dataDir = mkdtempSync(join(tmpdir(), "app-audit-"));
5082 const server = serve({ port: 0, dataDir, identityKey: KEY });
50565083 const base = \`http://\${server.hostname}:\${server.port}\`;
5057 afterAll(() => server.stop(true));
5084 afterAll(() => {
5085 server.stop(true);
5086 rmSync(dataDir, { recursive: true, force: true });
5087 });
50585088
50595089 const as = (
50605090 id: string,
@@ -5196,7 +5226,7 @@ test("only an admin reads the trail, at every door the table names", async () =>
51965226 });
51975227
51985228 test("a trail that cannot be written is a log line, and the change still happens", () => {
5199 const db = openDb(mkdtempSync(join(tmpdir(), "app-audit-broken-")));
5229 const db = openDb(mkdtempSync(join(dataDir, "broken-")));
52005230 db.exec("DROP TABLE audit");
52015231 const said = spyOn(console, "error").mockImplementation(() => {});
52025232 try {
@@ -5227,7 +5257,7 @@ const SECURITY_TEST = `/**
52275257 * table says could never pass — and nobody it would let through.
52285258 */
52295259 import { afterAll, expect, test } from "bun:test";
5230 import { mkdtempSync } from "node:fs";
5260 import { mkdtempSync, rmSync } from "node:fs";
52315261 import { tmpdir } from "node:os";
52325262 import { join } from "node:path";
52335263 import { readContract } from "./can.ts";
@@ -5245,13 +5275,13 @@ import { serve } from "./server.ts";
52455275 import { sign } from "./who.ts";
52465276
52475277 const KEY = "a-key-only-the-forge-holds";
5248 const server = serve({
5249 port: 0,
5250 dataDir: mkdtempSync(join(tmpdir(), "app-door-")),
5251 identityKey: KEY,
5252 });
5278 const dataDir = mkdtempSync(join(tmpdir(), "app-door-"));
5279 const server = serve({ port: 0, dataDir, identityKey: KEY });
52535280 const base = \`http://\${server.hostname}:\${server.port}\`;
5254 afterAll(() => server.stop(true));
5281 afterAll(() => {
5282 server.stop(true);
5283 rmSync(dataDir, { recursive: true, force: true });
5284 });
52555285 const as = (id: string, role: "user" | "admin"): Record<string, string> => {
52565286 const identity = \`\${id}|\${id}|\${role}|\${Date.now() + 60_000}\`;
52575287 return {
@@ -5366,7 +5396,7 @@ test("the API's description is shut to strangers when the table opens them no do
53665396 });
53675397
53685398 test("strangers are rationed at the API, reads too", () => {
5369 const db = openDb(mkdtempSync(join(tmpdir(), "app-door-rate-")));
5399 const db = openDb(mkdtempSync(join(dataDir, "rate-")));
53705400 const knock = () =>
53715401 door(
53725402 db,
@@ -5417,7 +5447,7 @@ const OPENAPI_TEST = `/**
54175447 * app serves exactly that file.
54185448 */
54195449 import { afterAll, expect, test } from "bun:test";
5420 import { mkdtempSync, readFileSync } from "node:fs";
5450 import { mkdtempSync, readFileSync, rmSync } from "node:fs";
54215451 import { tmpdir } from "node:os";
54225452 import { join } from "node:path";
54235453 import { emit, openapi } from "./openapi.ts";
@@ -5474,12 +5504,12 @@ test("every API route is described, and every door names its cell of the table",
54745504 });
54755505
54765506 test("GET /openapi.json serves the committed file", async () => {
5477 const server = serve({
5478 port: 0,
5479 dataDir: mkdtempSync(join(tmpdir(), "app-openapi-")),
5480 identityKey: "k",
5507 const dataDir = mkdtempSync(join(tmpdir(), "app-openapi-"));
5508 const server = serve({ port: 0, dataDir, identityKey: "k" });
5509 afterAll(() => {
5510 server.stop(true);
5511 rmSync(dataDir, { recursive: true, force: true });
54815512 });
5482 afterAll(() => server.stop(true));
54835513 const response = await fetch(
54845514 \`http://\${server.hostname}:\${server.port}/openapi.json\`,
54855515 );
test/scaffold.test.ts +9 −2
@@ -32,13 +32,14 @@ const SUITE_BUDGET_MS = 3_000;
3232 const run = async (
3333 cwd: string,
3434 argv: string[],
35 temp = process.env.TMPDIR ?? tmpdir(),
3536 ): Promise<{ code: number; out: string }> => {
3637 const child = Bun.spawn(argv, {
3738 cwd,
3839 env: {
3940 PATH: process.env.PATH ?? "/usr/bin:/bin",
4041 HOME: process.env.HOME ?? cwd,
41 TMPDIR: process.env.TMPDIR ?? tmpdir(),
42 TMPDIR: temp,
4243 },
4344 stdout: "pipe",
4445 stderr: "pipe",
@@ -74,12 +75,18 @@ describe("a scaffolded app, written out and run on its own", () => {
7475 test("its own suite is green, inside its 3 s budget", async () => {
7576 // Every deploy and every pull on the app waits on this suite, so it is
7677 // held to a budget (docs/APPS.md, "What a new app starts as").
78 const temp = await mkdtemp(join(tmpdir(), "forge-scaffold-tmp-"));
7779 const started = performance.now();
78 const { code, out } = await run(dir, [process.execPath, "test"]);
80 const { code, out } = await run(dir, [process.execPath, "test"], temp);
7981 const ms = Math.round(performance.now() - started);
8082 console.log(`the scaffold's own suite ran in ${ms} ms (budget ${SUITE_BUDGET_MS} ms)`);
8183 expect([code, out.includes(" 0 fail")]).toEqual([0, true]);
8284 expect(ms).toBeLessThanOrEqual(SUITE_BUDGET_MS);
85 // It leaves its temporary directory as it found it: a check cell's /tmp
86 // is a small tmpfs every scaffolded suite in the forge's own check shares
87 // (#5326), and every app's own check cell has one too.
88 expect(await readdir(temp)).toEqual([]);
89 await rm(temp, { recursive: true, force: true });
8390 // Each guarantee has its own file of tests in the suite.
8491 for (const name of [
8592 "design.test.ts",

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs