Refuse a second SQLite service before migration #183

Closed
weichen wants to merge 5 commits from feature/u8-sqlite-instance-guard into main
Owner

Why: Two processes opening the same SQLite file both migrate and reconcile, so the second one seals the first one's live runs.

Evidence: SELF tests are recorded on the Dev task card .task/feature-u8-sqlite-instance-guard.md. PG durability readback is NOT_RUN locally; Dev CI make test-backend-pg is the GATE. Backend CI on this HEAD is the GATE for go test.

Impact: SQLite serve and migrate share one non-blocking flock taken before open. A replaced database or rebuilt lock refuses start unless --adopt-instance-guard. A missing database is not recreated. The lock file cannot alias the database. PostgreSQL refuses when fsync, full_page_writes, or synchronous_commit is off.

Refs: Dev docs/recovery/u8-sqlite-instance-guard.md. Merge this PR before the Dev pin PR.

Why: Two processes opening the same SQLite file both migrate and reconcile, so the second one seals the first one's live runs. Evidence: SELF tests are recorded on the Dev task card `.task/feature-u8-sqlite-instance-guard.md`. PG durability readback is NOT_RUN locally; Dev CI `make test-backend-pg` is the GATE. Backend CI on this HEAD is the GATE for `go test`. Impact: SQLite serve and migrate share one non-blocking flock taken before open. A replaced database or rebuilt lock refuses start unless `--adopt-instance-guard`. A missing database is not recreated. The lock file cannot alias the database. PostgreSQL refuses when fsync, full_page_writes, or synchronous_commit is off. Refs: Dev docs/recovery/u8-sqlite-instance-guard.md. Merge this PR before the Dev pin PR.
weichen added 2 commits 2026-10-12 14:21:24 +00:00
Why: Two processes opening the same SQLite file both migrate and reconcile, so the second one seals the first one's live runs. The activity lock is taken before open, and durability settings are read back on the application connection.
Evidence: SELF go test ./internal/instanceguard ./internal/store ./internal/app (filtered T8 cases) on feature/u8-sqlite-instance-guard. PG durability readback is NOT_RUN locally; Dev CI test-backend-pg is the GATE.
Impact: SQLite serve and migrate share one non-blocking flock. A replaced database or rebuilt lock file refuses start unless --adopt-instance-guard. PostgreSQL serve refuses when fsync, full_page_writes, or synchronous_commit is off.
Refs: docs/recovery/u8-sqlite-instance-guard.md
Co-authored-by: Cursor <cursoragent@cursor.com>
Keep the activity lock from creating or aliasing the database
ci / vet-and-test (pull_request) Failing after 44s
1f7bcac6e0
Why: Review found that a missing data directory failed before open, adopt recreated a missing database, a lock symlink could be written as the database, and a failed identity check stored the wrong instance id.
Evidence: SELF go test TestMissingDataDirIsCreatedBeforeLock, TestLockSymlinkCannotAliasDatabase, TestAdoptDoesNotCreateMissingDatabase, TestIdentityFailureDoesNotStick.
Impact: First start creates the data directory before taking the lock. Adopt still refuses a missing database. The lock file is opened with O_NOFOLLOW and rejected when it is the database. Identity is checked before the guard row is written.
Refs: docs/recovery/u8-sqlite-instance-guard.md
Co-authored-by: Cursor <cursoragent@cursor.com>
weichen added 1 commit 2026-10-12 14:57:05 +00:00
Register instance_guard for copy and avoid recycled inodes
ci / vet-and-test (pull_request) Failing after 54s
15e7ec5f1f
Why: CI rejected the new table as missing from the storage-migrate copy list, and the replacement test passed on filesystems that reused the deleted inode.
Evidence: SELF go test TestCopyOrderCoversAllFixtureTables and TestDatabaseReplacementRefusedBeforeOpen.
Impact: SQLite to PostgreSQL copy keeps the guard row. The replacement test burns inodes until the new file is distinct.
Refs: docs/recovery/u8-sqlite-instance-guard.md
Co-authored-by: Cursor <cursoragent@cursor.com>
weichen added 1 commit 2026-10-12 15:07:31 +00:00
Reject a rebuilt lock even when its inode is reused
ci / vet-and-test (pull_request) Successful in 51s
ef66bfb331
Why: deleting the lock and creating a new file can recycle the same inode, so an inode-only check treated the rebuilt lock as the original.
Evidence: SELF go test ./internal/instanceguard ./internal/store ./internal/app, including TestClearedLockRecordRefusedWhenInodeStays.
Impact: instance_guard and the lock file now share a random lock_gen. A missing or different generation refuses Bind unless adopt.
Refs: docs/recovery/u8-sqlite-instance-guard.md
Co-authored-by: Cursor <cursoragent@cursor.com>
weichen added 1 commit 2026-10-12 15:46:24 +00:00
Merge origin/main into the SQLite instance guard
ci / vet-and-test (pull_request) Successful in 44s
167609b3db
Why: main now rejects unknown subcommands and registers schema compatibility, so the guard branch could not merge until migrate stayed in that switch and v28 was registered.
Evidence: go test ./internal/instanceguard ./internal/app ./internal/store ./cmd/agent-system ./cmd/storage-migrate passed locally after the merge.
Impact: the activity lock and durability checks stay in front of open. v28 does not raise the old-reader floor because instance_guard is a new table.
Refs: cmd/agent-system/main.go, internal/store/migrate_compat.go
Co-authored-by: Cursor <cursoragent@cursor.com>
Author
Owner

Superseded by #210: the same U8 change ported onto current main by a fresh agent-exec worker (migration renumbered to v36, main.go merged with capabilities/env/extension). Closing without merge; branch kept for reference.

Superseded by #210: the same U8 change ported onto current main by a fresh agent-exec worker (migration renumbered to v36, main.go merged with capabilities/env/extension). Closing without merge; branch kept for reference.
weichen closed this pull request 2026-10-18 09:21:21 +00:00

Pull request closed

This pull request cannot be reopened because the branch was deleted.
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: weichen/Agent-System-Backend#183