diff --git a/CLAUDE.md b/CLAUDE.md index 00545e4..a33481f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -350,9 +350,9 @@ five-minute demo of persistence and sessions, with runnable scripts in `runPath` gap below was found. **`gemdb file.py` starts with a dirty session, so `gemdb.transaction()` cannot -be a script's first statement.** Measured 2026-08-23, and it contradicts what -`cli.ts` claims a few lines above its driver. Walking the preamble one send at -a time in a clean session: `___canonicalClassesEnabled___: true` leaves +be a script's first statement.** Measured 2026-08-23 against the payload of +that date, before Grail retired the canonical-modules flag. Walking the +preamble one send at a time in a clean session: setting the flag left `System needsCommit` false, the `#GrailConsole` store leaves it false, and `importlib runPath:` sets it true — twice from clean, so it is `runPath` itself, not the file's own code (a script whose first line is diff --git a/src/__tests__/cli.test.ts b/src/__tests__/cli.test.ts index 96f0c15..d01ae0c 100644 --- a/src/__tests__/cli.test.ts +++ b/src/__tests__/cli.test.ts @@ -71,10 +71,10 @@ describe('writeCliScripts', () => { // SystemExit's Python args tuple, and CPython truncates an int to n % 256. expect(run).toContain("objectNamed: #'SystemExit'"); expect(run).toContain('\\\\ 256'); - // Deployed modules (gemdb above all) warm-bind only when the session - // enables canonical modules — without this line every CLI run - // cold-imports and gemdb's clean-session contract is void. - expect(run).toContain('___canonicalClassesEnabled___: true'); + // Grail retired the canonical-modules flag when warm binding became its + // only path. Sending it is now a doesNotUnderstand that kills the run at + // that line, so the driver must not carry it. + expect(run).not.toContain('___canonicalClassesEnabled___'); // A file run is linked topaz, so it never reaches session.ts and would // otherwise sit in the shared cache as the stock 'TopazL'. The truncation // is not optional: 32 characters raises OutOfRange, at login. diff --git a/src/cli.ts b/src/cli.ts index 39c6c64..e1ec99f 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -133,12 +133,11 @@ set gemstone ${STONE_NAME} login run | args ofs target status statusFile label | -"Canonical modules, session-local and default off: with it on, the modules -the extent ships deployed (gemdb above all) warm-bind instead of -cold-importing, so running a script leaves no uncommitted plumbing behind -and gemdb.transaction() works as its first statement. Mirrors the same -setting in the extension's session.ts." -importlib ___canonicalClassesEnabled___: true. +"No canonical-modules flag is set here; see cli.ts. Grail retired that +flag once warm binding became its only path -- what is warm is now +decided by what has been committed, which is what the shipped extent +already provides -- and the send became a doesNotUnderstand that killed +every file run at this line." args := System commandLineArguments. 1 to: args size do: [:j | (args at: j) = '--' ifTrue: [ofs := j]]. statusFile := System gemEnvironmentVariable: 'GEMDB_STATUS_FILE'. diff --git a/src/session.ts b/src/session.ts index f39229e..b495a1e 100644 --- a/src/session.ts +++ b/src/session.ts @@ -418,24 +418,13 @@ export class GciSession { } const session = new GciSession(gci, result.session, resolved); liveSessions.add(session); - // Canonical modules are a session-local Grail flag, default off. The - // shipped extent deploys gemdb (committed, caches warmed) precisely so - // that a session's `import gemdb` leaves nothing to commit — but the - // import only consults that deployed state when this flag is on. Without - // it every session cold-imports, and gemdb's transaction() entry check - // reports the import's own writes as the user's pending changes. Guarded - // send, best-effort: a database this extension did not install may - // predate the flag, and a session without it still works — just colder. - try { - session.execute( - '(System myUserProfile symbolList objectNamed: #importlib) ' + - 'ifNotNil: [:imp | imp ___canonicalClassesEnabled___: true]. true', - ); - } catch (e) { - log( - `Could not enable canonical modules (${resolved.label}): ${e instanceof Error ? e.message : e}`, - ); - } + // Nothing is sent here to make imports warm. Grail once gated that on a + // session-local flag, `___canonicalClassesEnabled___`, which this login + // turned on; the flag was retired when warm binding became the only path, + // and what is warm is now decided by what has been committed — which is + // exactly what the shipped extent, with gemdb deployed and its caches + // warmed, provides. The send survived here for a while as a caught DNU, + // logging a failure on every single login, which is worse than nothing. // Record GemStone's own serial for this session, so what the extension // knows (which notebook owns it) can be joined to what the database knows // (`gemdb.sessions`, idle times, who is holding resources). Best-effort: