store, web: cite the source of what they rely on (assumptions part D)

Comments only, no behaviour changed. modernc.org/sqlite v1.60.1 (the
_pragma list on every connection, busy_timeout first; extended result
codes; a deferred BEGIN; multi-statement Exec) and SQLite 3.53.4's
documentation (transactions, WAL, foreign keys, NOCASE, upsert, julianday,
partial indexes); htmx 2.0.4 src/htmx.js; the Fetch and HTML standards for
Sec-Fetch-Site, Origin, SameSite, __Host-, CSP and defer order; Go's
html/template. Comments the source contradicts are corrected - the driver
does not serialise writes (SetMaxOpenConns(1) does), htmx:load fires per
swapped element, no-store does not keep a page out of history.

Left for their own commits: D-S3 a migration two processes can both run,
D-S20 recipient case, D-B3 Origin: null under Referrer-Policy: no-referrer,
D-H5/H6/H7/H9 (audit M11, stage 4).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mix
2026-10-14 19:36:26 +03:00
co-authored by Claude Opus 5.5
parent b113e72c71
commit ad3d834392
25 changed files with 243 additions and 38 deletions
+18 -3
View File
@@ -83,6 +83,10 @@ func (s *Store) UserExists() (bool, error) {
// CreateGlobalUser inserts the first global user during setup. The check that
// no user exists yet and the insert are one statement, so two setup requests
// at once cannot both create one (audit 2026-10-12, M7).
// SQLite 3.53.4, https://sqlite.org/lang_transaction.html § 2.1: an INSERT
// starts a write transaction, one at a time, so its SELECT reads what is
// committed; an insert of no row leaves sqlite3_changes() at 0
// (https://sqlite.org/c3ref/changes.html).
func (s *Store) CreateGlobalUser(username, passwordHash string) error {
now := time.Now().UTC().Format(time.RFC3339)
res, err := s.db.Exec(
@@ -249,6 +253,7 @@ func (s *Store) AddUser(c UserChange) (int64, error) {
if c.Role == RoleDomain && c.Reach.Empty() {
return 0, ErrEmptyReach
}
// The first statement is a write (see UpdateStatus).
tx, err := s.db.Begin()
if err != nil {
return 0, fmt.Errorf("create user: %w", err)
@@ -302,7 +307,12 @@ func (s *Store) SaveUser(c UserChange) error {
}
defer tx.Rollback()
// A write first: it takes the write lock, so what is counted below is
// what is committed.
// what is committed. SQLite 3.53.4, https://sqlite.org/lang_transaction.html
// § 2.2: after a deferred BEGIN, a first statement that writes starts a
// write transaction, and § 2.1: there is one at a time. RowsAffected counts
// the row its WHERE found even when no value changes: update.c
// sqlite3Update() writes every such row through sqlite3CompleteInsertion(),
// which marks it counted (OPFLAG_NCHANGE).
// An empty hash keeps the stored one: the form read it when it was
// opened, and the user may have changed it on Account since.
res, err := tx.Exec(
@@ -403,7 +413,9 @@ func (s *Store) SetUserReach(userID int64, reach Reach) error {
// DeleteUser removes a panel user. ErrLastGlobal when deleting the only global
// user: the delete and the count are one transaction, so two administrators
// deleting each other at once cannot both succeed (audit 2026-10-12, M7).
// deleting each other at once cannot both succeed (audit 2026-10-12, M7). The
// DELETE comes first and so takes the write lock (see SaveUser); the rows its
// cascade removes are not in RowsAffected (https://sqlite.org/c3ref/changes.html).
func (s *Store) DeleteUser(id int64) error {
tx, err := s.db.Begin()
if err != nil {
@@ -517,7 +529,10 @@ func (s *Store) setUserReach(userID int64, reach Reach) error {
// writeUserReach writes a user's reach inside tx. With an All flag set the
// rows of that direction are dropped rather than stored: the flag already
// covers them, and stale rows would come back to life the day the flag is
// cleared.
// cleared. Its first statement is a write (see UpdateStatus). A domain deleted
// meanwhile fails its INSERT at once: SQLite 3.53.4's foreign keys are
// immediate unless declared deferred (https://sqlite.org/foreignkeys.html § 4.2),
// and the code is SQLITE_CONSTRAINT_FOREIGNKEY (isForeignKeyViolation).
func writeUserReach(tx *sql.Tx, userID int64, reach Reach) error {
if _, err := tx.Exec("UPDATE users SET all_domains = ?, all_inbound_domains = ? WHERE id = ?",
reach.AllDomains, reach.AllInbound, userID); err != nil {