Oregami
Repositories/oxedyne/daimond

oxedyne/daimond/dev/verify_defaults.mjs

5.5 KiB, 1 run

created by r2519314175:351, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1// verify_defaults.mjs — Help and the Optimiser are FEATURES, so everybody gets
2// them; but a Diamond somebody deletes stays deleted.
3//
4// The two default Diamonds were treated as onboarding furniture: seeded only
5// into an EMPTY rail, on the reasoning that a person with thirteen Diamonds does
6// not want two more. The flag was written either way, so that decision was taken
7// once and for ever. The consequence was reported in notes3, by the author, about
8// his own app: "I do not see the Daimond Help or Daimond Optimiser diamonds at
9// all." He never had an empty rail on the boot that offered them.
10//
11// They are not furniture. Daimond Help is the only thing that reads the guide
12// mirror at `system/guide/`, and the Optimiser is the only thing that reads the
13// usage digest at `system/usage/digest.md`. Withholding them withheld two
14// features.
15//
16// What is pinned here, and none of it held before:
17// * a rail that already has a Diamond STILL receives the two defaults;
18// * booting again does not make a second copy of either;
19// * a default the user DELETES stays deleted, because the app must not argue.
20//
21// Proved against broken code: restore `if ((diamonds || []).length) { ...; return; }`
22// at the top of `seedDefaultDiamonds` and the first check goes red.
23//
24// node dev/verify_defaults.mjs
25//
26// Needs dev/serve.mjs (DAIMOND_PORT, default 8777). No gateway, no mock LLM.
27import fs from 'node:fs';
28import { open, scratch, signInAs } from './harness.mjs';
29
30const PROFILE = scratch('pw', 'defaults');
31fs.rmSync(PROFILE, { recursive: true, force: true });
32
33let bad = 0;
34const check = (pass, name, detail) => {
35 if (!pass) bad++;
36 console.log((pass ? ' ok ' : ' FAIL ') + name + (detail ? ' — ' + detail : ''));
37};
38
39/// The names in the STORE, sorted. The store rather than the rail, because the
40/// question here is whether the two Diamonds were CREATED; whether the rail has
41/// re-read since is a different property with its own verifier, and mixing the
42/// two would make this file fail for reasons that are nothing to do with it.
43const names = async () => (JSON.parse(await wasm(async (app) => await app.list_diamonds())))
44 .map((d) => d.name).sort();
45
46const HELP = 'Daimond Help';
47const OPT = 'Daimond Optimiser';
48
49// `defaults: false` removes the two the first boot seeds, so this session owns
50// the rail outright and the state below is built rather than inherited.
51const s = await open({ name: 'defaults', profile: PROFILE, connect: false, defaults: false });
52const { page } = s;
53
54/// The store, driven directly, so the fixture is built rather than clicked.
55const wasm = (fn, arg) => page.evaluate(async ({ src, arg }) => {
56 const m = await import('/pkg/oxedyne_daimond.js');
57 const app = new m.DaimondApp('http://127.0.0.1/v1/chat/completions', '', 'none', 4096, '', true);
58 return await (new Function('app', 'arg', `return (${src})(app, arg);`))(app, arg);
59}, { src: fn.toString(), arg });
60
61/// Reload, sign back in, and let the boot finish.
62///
63/// The sign-in is not optional: a reload lands on the LOCK SCREEN, and an app
64/// sitting behind it never reaches `seedDefaultDiamonds` at all. Without this the
65/// file reported that the defaults were never seeded, on a build that seeds them.
66const reboot = async (settle) => {
67 await page.reload({ waitUntil: 'domcontentloaded' });
68 await signInAs(s, 'defaults');
69 await page.waitForTimeout(settle);
70};
71try {
72 await page.waitForTimeout(1200);
73
74 // ── A rail that is not empty ─────────────────────────────────
75 // One Diamond of the user's own, and the OLD flag set with the new one absent:
76 // that is exactly an account which was using the app when the feature shipped,
77 // was recorded as having been offered the defaults, and never saw them.
78 await wasm(async (app) => { await app.create_diamond('Mine'); });
79 await reboot(1500);
80
81 await page.evaluate(() => {
82 localStorage.setItem('daimond-defaults-seeded', '1'); // the old flag, as it was
83 localStorage.removeItem('daimond-defaults-seeded-2'); // the re-ask
84 });
85 await reboot(2500);
86
87 const after = await names();
88 check(after.includes(HELP) && after.includes(OPT),
89 'a rail that already holds a Diamond still receives both defaults', JSON.stringify(after));
90 check(after.includes('Mine'), 'and the Diamond that was already there is untouched',
91 JSON.stringify(after));
92
93 // ── Once, not once per boot ──────────────────────────────────
94 await reboot(2500);
95 const twice = await names();
96 check(twice.filter((n) => n === HELP).length === 1
97 && twice.filter((n) => n === OPT).length === 1,
98 'booting again makes no second copy of either', JSON.stringify(twice));
99
100 // ── A deletion is a decision, and the app must not argue ─────
101 const gone = await wasm(async (app, name) => {
102 const rows = JSON.parse(await app.list_diamonds());
103 const row = rows.find((d) => d.name === name);
104 if (!row) return 'no Diamond named ' + name;
105 await app.delete_diamond(row.id);
106 return '';
107 }, HELP);
108 if (gone) {
109 check(false, 'a deleted default stays deleted', 'could not delete it: ' + gone);
110 } else {
111 await page.waitForTimeout(700);
112 await reboot(2500);
113 const back = await names();
114 check(!back.includes(HELP), 'a deleted default stays deleted', JSON.stringify(back));
115 check(back.includes(OPT), 'and deleting one does not take the other with it',
116 JSON.stringify(back));
117 }
118} finally {
119 await s.close();
120}
121
122console.log(bad ? `\n${bad} check(s) FAILED` : '\nall checks passed');
123process.exit(bad ? 1 : 0);