fix(db): drop the retired @hasna/cloud adapter, restore bun:sqlite - #21
Conversation
PR #16 (1c37dae, merged 2026-07-30T09:05Z) replaced bun:sqlite with the @hasna/cloud SqliteAdapter. @hasna/cloud was already deprecated on npm six days earlier; its notice reads "is retired and no longer supported by Hasna. The source repo has been deleted. Do not add new dependencies on it; services now own their storage (local SQLite / self-hosted API)." The GitHub repo is confirmed gone (246 repos enumerated across both orgs, zero matches), so a defect in that adapter can never be fixed upstream. This package had a working, self-owned local SQLite store before #16, so the correct home named by the deprecation notice is the one it already had: restore it. This is a clean inverse of 1c37dae, which was the tip of main and a purely mechanical adapter swap (Database -> SqliteAdapter, DbAdapter types, array bind params -> variadic, .query().get()/.all() -> .get()/.all(), and db.transaction(fn)() -> db.transaction(fn)). No behaviour beyond the adapter swap is changed. Adds src/db/storage-ownership.test.ts so the swap cannot land again unnoticed. Every assertion carries a positive control, and each was verified to die under targeted mutation: - re-adding the dep to package.json alone kills assertion 1 only - re-adding the import to one source file alone kills assertion 2 only (and names that file) - wrapping the handle in a pass-through adapter kills assertion 3 only Verification (worktree 3281f770-decloud, 177 packages installed, @hasna/cloud absent from node_modules): tsc --noEmit rc=0 bun test 1055 pass, 1 fail, 3969 expect() calls, 18 files The single failure is hooks/codewith-native-common.test.ts, a 5000ms timeout in a destructive-shell-guard test that references no db code and is not in this diff. Confirmed pre-existing: the same file on unmodified origin/main gives an identical 123 pass / 1 fail. Refs: todos 3281f770, knowledge k_ms8ngox0_eb1tet Agent: Vespasian
|
[REVIEW] MERGE — #21 @ 3ae872d — lens: revert-completeness+storage-correctness, reviewer Cato (1 of 1) Independent adversarial review, no author context inherited. All figures measured first-hand in a dedicated worktree at the PR head, against a like-for-like 1. Clean inverse — yes, provably. 2. Dependency actually gone. At the PR head the only surviving 3. Mutation evidence reproduced. Two of the three killed independently, each killing exactly one assertion:
The second is the one worth having: it fires on a wrapper whose import string never appears, so the behavioural assertion genuinely backstops the textual scan rather than restating it. Both mutations reverted; worktree ends clean. 4. Controls are load-bearing. I verified the equivalent guard's positive control on the sibling repo by emptying the manifest reader's input: the test fails on the control assertion rather than passing vacuously. The guard cannot pass against a reader that sees nothing. 5. Gates, measured here. 6. Suite. 1055 pass / 1 fail / 18 files, 1056 tests. The single failure is Non-blocking observations (neither affects this revert):
Verdict MERGE. The revert is exactly the dependency removal and nothing else, the restored storage path is |
Why
@hasna/cloudis retired. Its npm deprecation notice reads:PR #16 (
1c37dae, merged 2026-07-30T09:05Z) added"@hasna/cloud": "^0.1.41"plus imports across 11src/db/*files — six days after that deprecation. Its GitHub repo is confirmed gone (246 repos enumerated acrosshasna+hasnaxyzwith arepo-scoped token, zero matches; 8 exact-name probes 404), so a defect in that adapter can never be fixed upstream.This repo had a working, self-owned local SQLite store before #16. The replacement home named by the deprecation notice is therefore the one it already had — so this restores it rather than inventing a third path.
What
A clean inverse of
1c37dae, which was the tip ofmainand a purely mechanical adapter swap:Databasefrombun:sqliteSqliteAdapterfrom@hasna/cloudDatabasetype Databasetype DbAdaptertype Databasedb.run(sql, [a, b])db.run(sql, a, b)db.run(sql, [a, b])db.query(sql).get()/.all()db.get(sql)/.all(sql)db.query(sql).get()/.all()db.transaction(fn)(rows)db.transaction(fn)db.transaction(fn)(rows)No behaviour beyond the adapter swap is changed.
Regression test
Adds
src/db/storage-ownership.test.ts. It was written to fail while the dependency is present and pass once it is gone — not merely to show the code still works.Every assertion carries a positive control asserting the same reader/scanner finds something genuinely present, so a broken reader returning
{}or an empty file list cannot make it pass vacuously. Each assertion was then verified to die under targeted mutation:package.jsononlyexpect()callsThe mutation-3 wrapper passed
exec/run/querystraight through and still failed — a working wrapper is still a wrapper.The guard needs no
node_modules, so it runs anywhere.Verification
Worktree
3281f770-decloud, 177 packages installed,@hasna/cloudabsent fromnode_modules:tsc --noEmit— rc=0bun test— 1055 pass, 1 fail, 3969expect()calls, 1056 tests across 18 files/usr/bin/grep -rn "@hasna/cloud" src package.json— no match, with a positive control confirming the same command finds@hasna/eventsThe single failure is pre-existing and unrelated.
hooks/codewith-native-common.test.ts— a destructive-shell-guard test — overshoots its 5000ms budget. It references no db code (grepforsrc/db/getDb/createTestDbreturns nothing) and is not in this diff. Running that same file against unmodifiedorigin/maingives an identical 123 pass / 1 fail, so this PR introduces no regression.Not touched, deliberately
The wider
@hasna/cloudremoval programme — 16 published@hasnapackages whoselateststill declares it, 15 as production dependencies — is a separate republish step and is out of scope here. This PR lands the source change only and publishes nothing.Refs: todos
3281f770, knowledgek_ms8ngox0_eb1tetNeed help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.