feat(M023): storage lifecycle, disk reclamation, and orphan cleanup - #40
Open
hiepau1231 wants to merge 60 commits into
Open
feat(M023): storage lifecycle, disk reclamation, and orphan cleanup#40hiepau1231 wants to merge 60 commits into
hiepau1231 wants to merge 60 commits into
Conversation
GSD-Unit: M023/S01/T01
- src/task/sqlite/client.ts - src/task/sqlite/protocol.ts - src/task/sqlite/worker.ts - src/task/sqlite/rpc.ts - src/task/sqlite/storage-report.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S01 - Storage accounting and report surface - Task: T01 - Wired the path-redacted SQLite storage report through DbClient, strict RPC validation, and worker-side page and table accounting. GSD-Task: S01/T01
- src/host/storage-orphans.ts - src/host/storage-orphans.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S01 - Storage accounting and report surface - Task: T02 - Added a path-redacted storage orphan classifier that distinguishes the live SQLite trio, legacy JSON store, active leases, and stale leases. GSD-Task: S01/T02
- package.json - src/extension.ts - src/task/sqlite/sqlite-only-activation.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S01 - Storage accounting and report surface - Task: T03 - Registered Muster’s storage report command with a path-redacted output channel and store-unavailable diagnostic. GSD-Task: S01/T03
- scripts/sqlite-extension-host-smoke.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S01 - Storage accounting and report surface - Task: T04 - Added live Extension Development Host assertions for the packaged SQLite storage report and recorded Electron’s dbstat provenance. GSD-Task: S01/T04
- src/task/sqlite/connection.ts - src/task/sqlite/rpc.ts - src/task/sqlite/storage-pragmas.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S02 - Page reclamation for new and legacy databases - Task: T01 - Fresh SQLite stores now claim `auto_vacuum = INCREMENTAL`, owned connections bound residual WAL to 16 MiB, and both measured pragmas are readable through the safe RPC. GSD-Task: S02/T01
- src/task/sqlite/reclaim.ts - src/task/sqlite/reclaim.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S02 - Page reclamation for new and legacy databases - Task: T02 - Added a worker-local SQLite reclamation module that checkpoint-baselines, boundedly incrementally vacuums fresh stores, and preflight-gates legacy full compaction. GSD-Task: S02/T02
- src/task/sqlite/rpc.ts - src/task/sqlite/worker.ts - src/task/sqlite/protocol.ts - src/task/sqlite/client.ts - src/task/sqlite/reclaim-rpc.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S02 - Page reclamation for new and legacy databases - Task: T03 - Wired path-redacted SQLite page reclamation through the typed worker RPC and exposed DbClient.reclaimStorage(). GSD-Task: S02/T03
- src/host/sqlite-maintenance-commands.ts - src/host/sqlite-maintenance-commands.test.ts - src/extension.ts - package.json - docs/SQLITE-STORAGE.md - src/task/sqlite/sqlite-only-activation.test.ts - scripts/verify-sqlite-storage-docs.test.mjs GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S02 - Page reclamation for new and legacy databases - Task: T04 - Added the user-invocable `muster.compactStorage` command, which dispatches reclamation from measured `auto_vacuum` and writes safe measurements to Muster Storage Report. GSD-Task: S02/T04
- scripts/sqlite-extension-host-smoke.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S02 - Page reclamation for new and legacy databases - Task: T05 - Extended the packaged Extension Host smoke with live storage-pragma and seed/delete/incremental-reclaim assertions. GSD-Task: S02/T05
- scripts/sqlite-extension-host-smoke.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S02 - Page reclamation for new and legacy databases - Task: T06 - Extended the packaged Extension Host smoke to reopen a schema-current legacy SQLite store in persistent auto_vacuum NONE mode without mutation. GSD-Task: S02/T06
- src/shared/tool-file-change-contract.ts - src/types.ts - src/shared/tool-file-change-retention.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S03 - File change evidence truncation on a recurring schedule - Task: T01 - Added a fail-closed retention evidence marker and pure transform that removes file diff bytes while retaining safe paths and logical line summaries. GSD-Task: S03/T01
- src/task/repository.ts - src/task/retention-row-invariance.test.ts - src/task/repository.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S03 - File change evidence truncation on a recurring schedule - Task: T02 - Removed terminal retention row deletion so retention preserves task, turn, message, and operation history. GSD-Task: S03/T02
- src/task/repository.ts - src/task/retention-file-evidence.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S03 - File change evidence truncation on a recurring schedule - Task: T03 - Wired terminal retention to persist fail-closed, line-summary file-change stripping for turns outside the retained window. GSD-Task: S03/T03
- src/host/retention-scheduler.ts - src/host/retention-scheduler.test.ts - src/extension.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S03 - File change evidence truncation on a recurring schedule - Task: T04 - Replaced one-shot activation retention with a disposable, injectable recurring scheduler. GSD-Task: S03/T04
- src/host/retention-scheduler.ts - src/host/sqlite-maintenance-commands.ts - src/host/retention-report.test.ts - src/extension.ts - src/task/repository.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S03 - File change evidence truncation on a recurring schedule - Task: T05 - Added path-free retention pass blocks to Muster Storage Report with completed and failed schedule counts. GSD-Task: S03/T05
- webview/src/lib/types.ts - webview/src/lib/tool-diff-view.ts - webview/src/components/ToolCard.svelte - webview/src/lib/tool-diff-view.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S03 - File change evidence truncation on a recurring schedule - Task: T06 - Rendered retention-stripped file changes as static line-count summaries without diff disclosure bodies. GSD-Task: S03/T06
- src/task/m023-s03-retention-bytes.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S03 - File change evidence truncation on a recurring schedule - Task: T07 - Added an end-to-end retention invariant test proving payload byte reduction, reclaimable file-size reduction, durable-row preservation, and schema stability. GSD-Task: S03/T07
- src/host/storage-orphans.ts - src/host/storage-orphans.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S04 - Orphan and uninstall reclamation - Task: T01 - Added path-safe, best-effort removal of classifier-selected legacy stores and stale leases with reclaimed-byte accounting. GSD-Task: S04/T01
- src/host/sqlite-maintenance-commands.ts - src/host/sqlite-maintenance-commands.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S04 - Orphan and uninstall reclamation - Task: T02 - Added a confirmation-gated, single-flight orphan-reclamation command handler with bounded Storage Report diagnostics. GSD-Task: S04/T02
- src/extension.ts - src/task/sqlite/sqlite-only-activation.test.ts - package.json GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S04 - Orphan and uninstall reclamation - Task: T03 - Registered the confirmation-gated orphan reclamation command and declared its VS Code command and uninstall hook. GSD-Task: S04/T03
- src/uninstall.ts - scripts/verify-uninstall-entrypoint.test.mjs GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S04 - Orphan and uninstall reclamation - Task: T04 - Added an extension-id-guarded compiled VS Code uninstall hook that best-effort clears Muster global storage and emits one exit-zero diagnostic. GSD-Task: S04/T04
- docs/SQLITE-STORAGE.md - scripts/verify-sqlite-storage-docs.test.mjs GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S04 - Orphan and uninstall reclamation - Task: T05 - Documented safe orphan reclamation and VS Code uninstall cleanup, with verifier-enforced command and lifecycle markers. GSD-Task: S04/T05
- src/host/retention-scheduler.ts - src/host/retention-scheduler.test.ts - src/extension.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S05 - End to end storage lifecycle proof - Task: T01 - Added a UAT-only, fail-closed retention interval override while preserving the 30-minute production cadence. GSD-Task: S05/T01
- src/host/uat-commands.ts - src/host/uat-commands.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S05 - End to end storage lifecycle proof - Task: T02 - Added dependency-injected UAT helpers that seed a retention-eligible workload and expose numeric-only storage lifecycle state from the activated production surfaces. GSD-Task: S05/T02
- src/extension.ts - src/task/sqlite/sqlite-only-activation.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S05 - End to end storage lifecycle proof - Task: T03 - Wired UAT-only storage lifecycle commands to the activated repository, SQLite client, and retention-report singletons. GSD-Task: S05/T03
- scripts/m023-s05-storage-lifecycle-evidence-schema.mjs - scripts/m023-s05-storage-lifecycle-evidence-schema.test.mjs - scripts/verify-m023-s05-storage-lifecycle-evidence.test.mjs - package.json GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S05 - End to end storage lifecycle proof - Task: T04 - Added a pure, allowlisted storage lifecycle evidence validator with invariant and privacy negative coverage. GSD-Task: S05/T04
- scripts/m023-s05-storage-lifecycle-evidence-schema.mjs - scripts/m023-s05-storage-lifecycle-evidence-schema.test.mjs GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S05 - End to end storage lifecycle proof - Task: T07 - Corrected storage lifecycle row preservation validation to compare seeded and retained snapshots. GSD-Task: S05/T07
- scripts/sqlite-two-window-live-uat.ts - scripts/run-sqlite-two-window-live-uat.mjs - scripts/sqlite-two-window-live-uat.test.mjs - package.json GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S05 - End to end storage lifecycle proof - Task: T08 - Added a storage lifecycle scenario to the existing two-window packaged Electron UAT runner. GSD-Task: S05/T08
- scripts/sqlite-two-window-live-uat.ts - scripts/sqlite-two-window-live-uat.test.mjs - docs/plans/m023-s05-storage-lifecycle-evidence.json GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S05 - End to end storage lifecycle proof - Task: T10 - Stabilized scenario-H peer mailbox ordering and added privacy-safe restart diagnostics, but the packaged B2 durable-surface readback still times out and no lifecycle evidence was written. GSD-Task: S05/T10
- scripts/sqlite-two-window-live-uat.ts - scripts/sqlite-two-window-live-uat.test.mjs GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S05 - End to end storage lifecycle proof - Task: T11 - Repaired fresh-host Scenario H to prove durable outbox and presentation restoration through legitimate pending-send recovery, with privacy-safe diagnostics; the later scheduled-retention live assertion remains unresolved. GSD-Task: S05/T11
- src/host/uat-commands.ts - src/host/uat-commands.test.ts - scripts/run-sqlite-two-window-live-uat.mjs - scripts/sqlite-two-window-live-uat.test.mjs GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S05 - End to end storage lifecycle proof - Task: T12 - Corrected the storage-lifecycle UAT seed to exercise SQLite’s real open-task file-change truncation path and isolated the accelerated timer to orchestrator A. GSD-Task: S05/T12
- src/task/repository.ts - src/task/retention-file-evidence.test.ts - src/host/uat-commands.ts - src/host/uat-commands.test.ts - docs/plans/m023-s05-storage-lifecycle-evidence.json GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S05 - End to end storage lifecycle proof - Task: T14 - Repaired open-task retention so bounded aged file changes and oversized tool output are atomically truncated, then captured validated two-host lifecycle evidence. GSD-Task: S05/T14
- src/host/sqlite-maintenance-commands.ts - src/host/sqlite-maintenance-commands.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S06 - Orphan cleanup command confirmation correctness - Task: T01 - Made orphan-reclamation confirmation derive its count and byte total from the exact classifier snapshot and skip prompting for an empty set. GSD-Task: S06/T01
- src/task/sqlite/sqlite-only-activation.test.ts - docs/SQLITE-STORAGE.md - scripts/verify-sqlite-storage-docs.test.mjs GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S06 - Orphan cleanup command confirmation correctness - Task: T02 - Pinned orphan reclamation to its explicit Command Palette entrypoint and documented zero-result and cancellation lifecycle guarantees. GSD-Task: S06/T02
- webview/src/components/ToolCard.svelte - webview/src/lib/render-probe.ts - webview/src/lib/render-probe.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S07 - Live host proof that truncated file change history renders - Task: T01 - Added stable ToolCard render markers and a pure DOM collector for retention-summary UAT observations. GSD-Task: S07/T01
- src/host/webview-render-probe.ts - src/host/webview-render-probe.test.ts - src/host/uat-commands.ts - src/host/uat-commands.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S07 - Live host proof that truncated file change history renders - Task: T02 - Added a correlated single-flight host coordinator and UAT-only render-probe command identifier for live webview DOM observations. GSD-Task: S07/T02
- src/extension.ts - webview/src/App.svelte - src/host/uat-commands.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S07 - Live host proof that truncated file change history renders - Task: T03 - Wired the UAT-gated host-to-webview render probe round trip for live DOM observations. GSD-Task: S07/T03
- scripts/m023-s07-truncated-render-evidence-schema.mjs - scripts/m023-s07-truncated-render-evidence-schema.test.mjs - package.json GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S07 - Live host proof that truncated file change history renders - Task: T04 - Added a fixture-tested M023/S07 evidence schema that accepts only live Extension Development Host DOM provenance for pass verdicts. GSD-Task: S07/T04
- scripts/m023-s07-render-evidence-assembly.mjs - scripts/m023-s07-render-evidence-assembly.test.mjs - scripts/m023-s07-truncated-render-host.ts - scripts/run-m023-s07-truncated-render-uat.mjs - package.json GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S07 - Live host proof that truncated file change history renders - Task: T05 - Added a packaged single-window Extension Development Host runner and fail-closed pure assembly for truncated-render UAT evidence. GSD-Task: S07/T05
- docs/plans/m023-s07-truncated-render-evidence.json - scripts/verify-m023-s07-truncated-render-evidence.test.mjs - scripts/run-m023-s07-truncated-render-uat.mjs - scripts/m023-s07-truncated-render-host.ts - src/shared/tool-file-changes.ts - src/host/snapshot.ts - src/host/repository-snapshot.test.ts - docs/SQLITE-STORAGE.md GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S07 - Live host proof that truncated file change history renders - Task: T06 - Recorded a schema-validated live Extension Development Host DOM ledger proving retention-truncated file rows render paths and summaries without diff bodies. GSD-Task: S07/T06
- src/host/uat-orphan-lifecycle.ts - src/host/uat-orphan-lifecycle.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S08 - Orphan reclamation composed into end to end lifecycle - Task: T01 - Added path-free orphan lifecycle observations that validate classified cleanup totals and protected live-storage survival. GSD-Task: S08/T01
- src/host/uat-commands.ts - src/extension.ts - src/task/sqlite/sqlite-only-activation.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S08 - Orphan reclamation composed into end to end lifecycle - Task: T02 - Registered live-UAT-only orphan fixture and production reclamation delegates while preserving the single explicit production handler invocation. GSD-Task: S08/T02
- scripts/m023-s08-orphan-lifecycle-evidence-schema.mjs - scripts/m023-s08-orphan-lifecycle-evidence-schema.test.mjs - scripts/verify-m023-s08-orphan-lifecycle-evidence.test.mjs - package.json GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S08 - Orphan reclamation composed into end to end lifecycle - Task: T03 - Added a pure, anti-vacuity S08 orphan lifecycle evidence schema and tracked-artifact verifier command. GSD-Task: S08/T03
- src/extension.ts - src/task/sqlite/sqlite-only-activation.test.ts - scripts/sqlite-two-window-live-uat.ts - scripts/sqlite-two-window-live-uat.test.mjs - scripts/run-sqlite-two-window-live-uat.mjs - package.json - docs/plans/m023-s08-orphan-lifecycle-evidence.json GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S08 - Orphan reclamation composed into end to end lifecycle - Task: T04 - Composed classified orphan reclamation into the packaged two-host lifecycle UAT and emitted validated S08 evidence. GSD-Task: S08/T04
- docs/plans/m023-requirement-evidence.md - scripts/verify-m023-requirement-evidence.test.mjs - package.json GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S08 - Orphan reclamation composed into end to end lifecycle - Task: T05 - Mapped R040 through R045 to validated S05 and S08 tracked lifecycle evidence with a fail-closed artifact verifier. GSD-Task: S08/T05
- src/task/repository.ts - src/task/workflow-metadata-reclamation.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S09 - Terminal workflow metadata reclamation - Task: T02 - Added a workspace-scoped guarded command that reclaims only safely terminal workflow metadata and reports its removed-run count. GSD-Task: S09/T02
- src/extension.ts - src/host/sqlite-maintenance-commands.ts - src/host/retention-report.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S09 - Terminal workflow metadata reclamation - Task: T03 - Scheduled payload retention now reclaims safely terminal workflow metadata and reports the removed-run count. GSD-Task: S09/T03
- src/task/m018-s07-workflow-status-projection.test.ts GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S09 - Terminal workflow metadata reclamation - Task: T04 - Realigned M018 terminal workflow coverage so payload retention preserves transcript turns while guarded metadata reclamation deletes only safe terminal workflow runs. GSD-Task: S09/T04
- package.json - .github/workflows/ci.yml - docs/plans/m023-requirement-evidence.md GSD context: - Milestone: M023 - Storage Lifecycle and Disk Reclamation - Slice: S09 - Terminal workflow metadata reclamation - Task: T05 - Added a CI-enforced aggregate for all six M023 static evidence verifiers and corrected R042’s retained-pass citation to the tracked ledger. GSD-Task: S09/T05
M023 branched from 168b39c (the M021 merge), before M022 landed the UAT surface tiering, so main was 35 commits ahead and the conflict fell directly on the security boundary M022 introduced. M022 redefined isUatModeEnabled as resolveUatSurface(...) !== 'none', which now returns true for a Production VSIX with MUSTER_UAT_MODE=1 -- the redacted 'packaging' tier the real-install gate needs. M023 had gated its store-mutating harness commands on that same boolean, so taking either side verbatim would have reopened the marketplace exposure M022 closed in its review round 2. Resolution: - registerLiveUatCommands keeps M022's tier parameter and gains M023's storage args: (context, uatSurface, storageDirectory, reclaim...). All six M023 command ids are registered after the `tier !== 'full'` early return, so a packaging host cannot reach them. - The two M023 affordances that are not commands -- the path-bearing DOM render probe (D079) and the retention-interval override -- now key off a new `fullUatSurface` (uatSurface === 'full') instead of liveUatEnabled, keeping both Development-only. - uat-commands.test.ts: both sides only appended tests; kept both. - Updated the two source-scanning guards for the new signature and classified the six M023 command ids in the tiering invariant, which requires every declared command to be bucketed deliberately. Verified after merge: tsc --noEmit, full vitest (201 files / 2591 passed / 4 skipped), compile, check:svelte, test:webview (82 passed), test:m023-evidence-gate, test:source-boundary(+:fixtures), test:evidence, test:settings-docs, test:settings-live-evidence, and test:m022-s02..s05 -- all exit 0.
CI failed on exactly one test -- "M020 S03 collapse" -- with expect(expandedBox!.height).toBeGreaterThan(1) receiving 0, while every assertion around it passed: aria-expanded was 'true', data-collapsed was 'false', and the added diff line was visible. That combination rules out a rendering regression and points at timing. The panel expands through a `grid-template-rows: 0fr -> 1fr` transition (0.2s). Playwright's attribute and visibility assertions auto-retry, so they settle as soon as the class flips, but boundingBox() is a single sample with no retry -- it can be taken while the row is still animating. A loaded Linux runner is simply more likely to land inside that window than a local machine. Confirmed by controlled experiment rather than inference: temporarily raising the transition to 5s reproduced the failure locally with height 0.046875 (mid-animation), and the polled assertion passed with the transition still at 1s. Production CSS is unchanged at 0.2s. Negative control: with the threshold temporarily set to 999999 the test fails and reports the real settled height of 21.33px, so the assertion still has teeth and is not vacuously passing. Verified: npm run test:webview -- 82 passed. Also re-ran the six verifiers that reference this spec file; all pass except test:file-drop-docs, which fails identically without this change and is not wired into CI (pre-existing, unrelated).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
M023 makes Muster account for its own disk footprint and actually give bytes back — without deleting a single row of conversation history and without bumping the schema version.
The milestone is ordered so the measurement instrument lands first, and every later byte claim is forced through it. The storage report and the reclamation therefore cannot disagree.
storageReportrequest kind on the SQLite worker protocol returns file/WAL/shm bytes, page and freelist counts, page size, liveauto_vacuummode, and a descending per-table breakdown — plus a four-bucket orphan classifier separating the live SQLite trio from dead legacy stores, active leases, and stale leases. Both tracked ledgers reporttableBytesSource: dbstatfrom a real Extension Host, sodbstatavailability under Electron is proven rather than assumed.auto_vacuum = INCREMENTALwithjournal_size_limit = 16777216; reclamation runs in bounded page batches with checked WAL checkpoints. LegacyNONEstores need roughly twice the file size in free space, so anfs.statfsSyncprecheck refuses up front reporting required vs available bytes instead of dying mid-VACUUM. A legacy fixture reopens unmutated andSQLITE_SCHEMA_VERSIONstays2.tool_calls.payload_jsondiff text is stripped on aged turns whilepathand change summaries survive behind an explicitretentionTruncatedflag, so the webview can distinguish truncation from an empty change set.DELETE FROM turns/DELETE FROM messagespath was removed, not gated behind a flag, so retention cannot be reconfigured into deleting history.vscode:uninstallhook is profile-aware: activation registers the actualcontext.globalStorageUri; uninstall reclaims only an exact registered extension-id path (or the explicit test override), never guesses Stable/Insiders/portable locations. Concurrent Extension Hosts tolerate Windows registry-write contention without blocking activation.Composition detail worth knowing: truncation alone only moves bytes to the freelist. The byte tests assert on-disk shrink only after the reclaim call, so S03 cannot report savings that never materialise.
Observed in one continuous packaged two-window run:
fileBytes6,811,648 → 1,507,328 withfreelistCount: 0;tool_callsbytes 6,127,616 → 819,200 while durable counts stay identical at tasks 8 / turns 12 / messages 14. Uninstall emitsreclaimed_bytes: 2448/absent/refused, exit 0 each, no paths in stdout.52 commits, 78 files changed. No
.gsd/planning artifacts in the diff.Merge resolution — please read, it touches the M022 security boundary
This branch was cut from
168b39c(the M021 merge), before M022 landed the UAT surface tiering, somainwas 35 commits ahead and the conflict fell directly on the boundary M022 introduced.M022 redefined
isUatModeEnabledasresolveUatSurface(...) !== 'none', which now returns true for a Production VSIX withMUSTER_UAT_MODE=1— that is the redactedpackagingtier the real-install gate needs. M023 had gated its store-mutating harness commands on that same boolean. Taking either side verbatim would have reopened exactly the marketplace exposure M022 closed in its review round 2.registerLiveUatCommandssignature — M022 addedtier, M023 added storage args(context, uatSurface, storageDirectory, reclaimOrphanedFilesForUat). All six M023 command ids register after thetier !== 'full'early return, so a packaging host cannot reach themliveUatEnabled, which is now true at the packaging tierfullUatSurface(uatSurface === 'full'). The path-bearing DOM render probe (D079) and the retention-interval override are both keyed off it, keeping them Development-onlyuat-commands.test.tsuat-surface-tier.invariant.test.tsrequires every declared command to be bucketed deliberatelyfullchecksqlite-only-activation.test.tspinned the old call signatureliveUatEnableddeliberately staysuatSurface !== 'none'— narrowing it tofullwould have broken M022's packaging gate, which needsbridgeHealth/runDeactivatefrom a Production install.Verification
CI is green on
1ec4b47(run 30683259259) — all six jobs pass:compile, Packaging gate (Extension Host), Packaging install gate (real install), and SQLite Extension Host on 1.100.0 / 1.101.0 / stable.Local gates, run against the merge commit:
npx tsc -p . --noEmitnpm test -- --runnpm run compilenpm run check:sveltenpm run test:webviewnpm run test:m023-evidence-gatetest:source-boundary,test:source-boundary:fixtures,test:evidencetest:settings-docs,test:settings-live-evidencetest:m022-s02…test:m022-s05The current 2598/201 figure includes the post-review storage lifecycle coverage; no test was dropped or newly skipped. The later flake fix touches only an
e2e/spec, which is outside vitest'sinclude.Post-review live UAT rerun (2026-08-02): all packaged Electron runners were re-executed after the storage fixes:
test:m023-s05-storage-lifecycle-live-uatpassed scenarios A–I;test:m023-s07-truncated-render-live-uatpassed; and the S08 orphan ledger was emitted by the same two-window lifecycle run. The three tracked ledgers are schema-validated,ok: true, and pin theircommitShato03e6e84fad4faf44d2874214efa5fb3e51ed6151, the exact source candidate packaged for those runs.npm run test:m023-evidence-gatepasses.The one CI failure, and why the fix is a test fix
The first CI run on the merge commit failed on exactly one test —
M020 S03 collapse— whereexpect(expandedBox!.height).toBeGreaterThan(1)received0. Every assertion around it passed:aria-expandedwastrue,data-collapsedwasfalse, and the added diff line was visible. That combination rules out a rendering regression and points at timing.The panel expands through a
grid-template-rows: 0fr → 1frtransition. Playwright's attribute and visibility assertions auto-retry, so they settle the moment the class flips — butboundingBox()is a single sample with no retry, so it can be taken while the row is still animating. A loaded Linux runner is simply likelier to land inside that window than a local machine.Established by controlled experiment rather than inference:
height 0.046875— mid-animation.0.2s; only the assertion changed.999999the test fails and reports the real settled height of 21.33px, so the assertion still has teeth rather than passing vacuously.Backend / area
Checklist
npm run compilepasses locallydocs/(docs/SQLITE-STORAGE.md, plus three tracked evidence ledgers and the requirement-evidence map)Known limitations and follow-ups
Blocking before the first published release (pre-existing, not introduced here)
K001, storage is clean-break reset-only atSQLITE_SCHEMA_VERSION = 2;connection.tsrejects every otheruser_version. Free today at v0.1.0 with no published users, but after the first release any schema bump silently erases task and chat history. M023 shipped zero schema change and did not worsen this.Verifier hardening
scripts/verify-m023-requirement-evidence.test.mjspinsrequiredMappingsto R040–R045 — its own test name readsmaps R040 through R045. That is precisely why R046 satactivefor days after shipping in S04: no gate ever observed it. Extending the range would close the blind spot.docs/plans/m023-requirement-evidence.mdare not gated, so quoted ordinals can drift from a regenerated ledger without failing CI.npm run test:file-drop-docsfails ondocs/WEBVIEW.md missing contract marker: ## 12. Workspace file-drop mentions. It fails identically with this branch stashed, none of the files it checks differ fromorigin/main, and it is not wired intoci.yml— which is why it has gone unnoticed. Worth either fixing or wiring in, but out of scope here.Needs a human at a real host (5 items, none touching data safety)
Command Palette read-throughs for the S01 storage report and S02 compaction output; a genuine partial-removal failure (
chmod 0444does not preventunlinkon Windows — use an exclusive lock oricaclsdeny-delete); visual confirmation of the native modal copy for S06/S08; and the real marketplace uninstall flow, which is unexercised by design since VS Code itself invokes the hook.Cosmetic
removed: .muster-tasks.json (54 bytes)rather than the UAT spec's literalremoved: <basename> bytes: <n>. Content matches intent; either the line or the spec should be aligned.