You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 38befac
Browse filesBrowse the repository at this point in the historyBrowse files
to preview — the preview is a read-only per-table count, because the
318
+
engine's delete has no preview form). Deleting the mcode record drops
319
+
it from both lists.
318
320
-**Startup cleanup** prunes records that are empty AND default-titled
319
321
AND older than 24h — the "+"-then-never-typed leftovers.
320
322
-**Search** (`GET /api/sessions/search`) fuzzy-matches titles across
@@ -509,7 +511,7 @@ Fifteen files, one job each:
509
511
|`engine/account-reads.js`| The account family's facade call (`readEngineAccount`) and the endpoint→capability table `ACCOUNT_READ_ENDPOINTS` (step M3, batch B4). Gates **hard** on `authCredentials` · `getAccountStatus` — the same pair and the same provider method as `engine/usage-reads.js`, because #20 and #15/#16 read the same engine projection. Its read is **asynchronous** and it lives under the ordinary `await import()` boot-path rule |
510
512
|`engine/model-reads.js`| The model-catalogue family's facade call (`readEngineModelCatalogue`), the whole projection as named pure functions (`projectModelCatalogue`, `deriveModelSelection`, `buildModelCataloguePayload`, `catalogueSourceLabel`, `webuiFullModelId`, `providerOfModelId`, `attachContextWindowOptions`, `configOption`), and the endpoint→capability table `MODEL_READ_ENDPOINTS` (step M3, batch B4). Gates **soft**: `checkModelReadCapability` reports and never throws, because the catalogue's primary sources are files webui owns. Its read is **synchronous**, and it is the one engine module **not** re-exported from `engine/index.js` — see the boot-path note below |
511
513
|`engine/capability-reads.js`| The capability-declaration family's facade call (`readEngineCapabilityView`) and the endpoint→capability table `CAPABILITY_READ_ENDPOINTS` (step M3, batch B4). Declares **no capability for #73** — it IS the declaration endpoint, and gating the gate would let a `none` hide the declaration that says so. It is the only endpoint in the migration whose response CONTRACT changed (`capabilities` is now the 14-key declaration, replacing the ACP wire table) |
512
-
|`engine/session-writes.js`| The session WRITE family's facade calls (`planEngineSessionDelete`, `commitEngineSessionDelete`, `commitEngineOrphanSessionDelete`, `previewEngineSessionDelete`, `applyEngineSessionRename`, `readOrphanSessionWriteIds`), the pure derivations they are built from (`resolveSessionTarget`, `isMcodeSessionId`, `isOrphanSessionRecord`, `selectOrphanSessionIds`, the two fan-out predicates, the per-client state resets), and the endpoint→capability table `SESSION_WRITE_ENDPOINTS` (step M3, batch B5). Gates **hard** on `sessionCrud` · `deleteSession` for #7 and #6, and declares **no capability at all** for #4. Forwards the 32-table SQL to `lib/mcode-session-delete.js` rather than moving it — see the write-path section below |
514
+
|`engine/session-writes.js`| The session WRITE family's facade calls (`planEngineSessionDelete`, `commitEngineSessionDelete`, `commitEngineOrphanSessionDelete`, `previewEngineSessionDelete`, `applyEngineSessionRename`, `readOrphanSessionWriteIds`), the pure derivations they are built from (`resolveSessionTarget`, `isMcodeSessionId`, `isOrphanSessionRecord`, `selectOrphanSessionIds`, the two fan-out predicates, the per-client state resets), and the endpoint→capability table `SESSION_WRITE_ENDPOINTS` (step M3, batch B5). Gates **hard** on `sessionCrud` · `deleteSession` for #7 and #6, and declares **no capability at all** for #4. Issues no SQL of its own — the engine destroys the rows, through `engine/session-delete.js` — see the write-path section below |
513
515
514
516
Routes take the host from the facade and never from `lib/acp-client.js`:
515
517
`routes/plugins.js` and `routes/turn-diff.js` call
@@ -701,7 +703,7 @@ same rule: their static imports are `engine/capabilities.js` and
701
703
`await import()` inside the functions. `engine/session-writes.js` adds
702
704
`node:fs` at module scope (a builtin, and `engine/usage-reads.js`
703
705
already does the same) and reaches `lib/sessions.js`,
704
-
`lib/mcode-session-delete.js`, `lib/state-bus.js` and
706
+
`engine/session-delete.js`, `lib/state-bus.js` and
705
707
`lib/config.js` dynamically — all six of its storage dependencies, which
706
708
is what lets it be re-exported from `engine/index.js` at all.
707
709
@@ -1119,7 +1121,7 @@ answer twice in a row.
1119
1121
1120
1122
| Endpoint | Facade function | Capability · sub-item | Enforcement | Value source |
1121
1123
| --- | --- | --- | --- | --- |
1122
-
|`DELETE /api/sessions/:id` (#7) |`engine/session-writes.js#planEngineSessionDelete` → `engine/session-writes.js#commitEngineSessionDelete` / `engine/session-writes.js#commitEngineOrphanSessionDelete` / `engine/session-writes.js#previewEngineSessionDelete`|`sessionCrud` · `deleteSession`| hard — 501 | the webui session store, the in-memory ACP session cache, the sidebar tree cache, and the engine's own `local_runtime_*` rows via `lib/mcode-session-delete.js#deleteMcodeSessionFromDb`|
1124
+
|`DELETE /api/sessions/:id` (#7) |`engine/session-writes.js#planEngineSessionDelete` → `engine/session-writes.js#commitEngineSessionDelete` / `engine/session-writes.js#commitEngineOrphanSessionDelete` / `engine/session-writes.js#previewEngineSessionDelete`|`sessionCrud` · `deleteSession`| hard — 501 | the webui session store, the in-memory ACP session cache, the sidebar tree cache, and the engine's own `local_runtime_*` rows via the engine's `deleteSession`, reached through `engine/session-delete.js#deleteSessionThroughEngine`|
1123
1125
|`POST /api/sessions/rename` (#4) |`engine/session-writes.js#applyEngineSessionRename`| none of the 14 keys | none — the gate is a reported no-op | webui's own session store, and nothing else. The engine's title is not written |
1124
1126
|`POST /api/sessions/cleanup-orphans` (#6) |`engine/session-writes.js#readOrphanSessionWriteIds`, then each selected id delegated to `engine/session-writes.js#commitEngineOrphanSessionDelete`|`sessionCrud` · `deleteSession`| hard — 501 | the same store, plus each selected id delegated to #7, so it reaches the same engine rows |
1125
1127
@@ -1191,16 +1193,32 @@ memory and rewrites its registry row on its next request — that is the
1191
1193
cache: invalidating the whole cache empties the sidebar, refills it, and
1192
1194
reads to the user like the delete failed.
1193
1195
1194
-
**The 32-table SQL was not moved, and that is recorded rather than
1195
-
quietly dropped.** The plan for this batch annotated
1196
-
`lib/mcode-session-delete.js` "delete". It is kept because
1197
-
`lib/acp-client.js` imports `deleteMcodeSessionFromDb` from it and four
1198
-
test files bind to that specifier; collecting it means moving those
1199
-
first. The facade reaches it through `await import()` and issues no SQL
1200
-
of its own — the same split B3 drew for `lib/mavis-usage.js` and B4 for
1201
-
`lib/mcode-rpc.js`. A test asserts both halves: the table list is still
1202
-
32 entries exported from the lib module, and the facade contains no SQL
1203
-
verb at all.
1196
+
**M4-3a collected the debt this batch recorded: the 32-table
1197
+
row-destroying SQL is gone, and the engine destroys the rows.** The
1198
+
retired module (the bare-SQL session delete, removed here) opened the
1199
+
engine's runtime database and deleted by hand across a hand-curated
1200
+
table list; the
1201
+
destructive step is now the engine's own `deleteSession`, reached from
1202
+
`engine/session-delete.js` through the process-local catalogue host — the
1203
+
same `getEngineCatalogueHost()` seam the plugin and turn-diff routes use.
1204
+
The facade reaches that module through `await import()` and still issues
1205
+
no SQL of its own.
1206
+
1207
+
**What stayed is the read-only half, and the reason is a fact rather than
1208
+
caution: the engine exposes no dry-run or preview form of its delete.**
1209
+
`?dryRun=true` is part of #7 and #6's contract, so the per-table COUNT
1210
+
remains, against the same 32-table list, in the same module that now
1211
+
drives the engine call. webui still READS a schema layout it maintains by
1212
+
hand; it no longer WRITES one. The real delete takes its `log` and
1213
+
`totalRowsDeleted` from the same readonly pass, taken immediately before
1214
+
the engine call, so the `rowsAffected` and `mcodeRowsAffected` fields the
1215
+
HTTP layer derives from them carry the values they always carried.
1216
+
1217
+
`test/lib/engine/session-delete-ownership.test.js` is the tripwire: no
1218
+
server module may import the retired module, issue a DELETE against a
1219
+
`local_runtime_*` table, or open the engine's database without
1220
+
`readonly: true`. It is a static-source check on purpose — a behavioural
1221
+
test cannot distinguish "the engine deleted it" from "webui deleted it".
1204
1222
1205
1223
**#6's response shape is this batch's byte-for-byte red line, so the
1206
1224
payload is built in the facade and never re-assembled in the route.** The
@@ -1216,12 +1234,15 @@ turn a cleanup request into a 500. `dryRun` suppresses the kill and the
1216
1234
cache drop, because a preview mutates nothing and a preview that shuts
1217
1235
down the user's ACP child is a side effect the `?dryRun=true` contract
1218
1236
does not include; the COUNT still runs, read-only, inside
1219
-
`lib/mcode-session-delete.js`.
1237
+
`engine/session-delete.js`.
1220
1238
1221
1239
**Three things this batch records as known debt instead of deciding:**
1222
1240
1223
-
1. The 32-table SQL is still in `lib/mcode-session-delete.js`, for the
1224
-
consumer reasons above.
1241
+
1. Collected in M4-3a: the 32-table row-destroying SQL. What remains of
1242
+
the same debt is the READ side — `engine/session-delete.js` still
1243
+
counts against a hand-maintained table list, because the engine has no
1244
+
preview form of its delete. Closing that needs a count surface on the
1245
+
engine itself, which is a local-runtime-v2 change.
1225
1246
2. A rename is a **webui-side label only**. The engine's own title in
1226
1247
`local_runtime_sessions` is untouched while the sidebar tree reads its
1227
1248
titles from the engine, so for an engine-backed session a rename can be
0 commit comments