diff --git a/folders/folders.go b/folders/folders.go
index ed5cae86fc1f0cd53066f06394cef3e6d0e8e625..d05a5e6c46e918c6fc43dbf546f5eaf06bbbbd33 100644
--- a/folders/folders.go
+++ b/folders/folders.go
@@ -104,6 +104,10 @@ func IsFolderAccess(name, login string) bool {
 // IsFolderOwner checks if a user is a folder owner.
 func IsFolderOwner(folder, login string) bool {
 	ctx := storage.Context()
+	admin, _ := this.Q.IsUserAdmin(ctx, login)
+	if admin == 1 {
+		return true
+	}
 	found, _ := this.Q.IsFolderOwner(ctx, storage.IsFolderOwnerParams{
 		Folder: folder,
 		Login:  login,
diff --git a/repl/command.go b/repl/command.go
index e6c448805cbe187606b2efe4a712b843a36ff329..e4b9031651650138a684cf00af0b863d8c8f8058 100644
--- a/repl/command.go
+++ b/repl/command.go
@@ -270,14 +270,6 @@ BULLCOM.CLD.`,
 				OptArg:  true,
 				Default: "14",
 			},
-			"/ID": {
-				Description: `  Designates  that the  name specified  as the  owner name  is a  rights
-  identifier. The  creator's process must have  the identifier presently
-  assigned to it.  Any process which has that identifier  assigned to it
-  will be able to  control the folder as if it  were the folder's owner.
-  This is used to allow more than one use to control a folder.`,
-				OptArg: true,
-			},
 			"/NOTIFY": {
 				Description: `  Specifies  that  all users  automatically  have  NOTIFY set  for  this
   folder. Only a  privileged user can use this qualifier.  (See HELP SET
@@ -286,8 +278,7 @@ BULLCOM.CLD.`,
 			"/OWNER": {
 				Description: `/OWNER=username
 
-  Specifies the owner of the folder.  This is a privileged command.  See
-  also /ID.`,
+  Specifies the owner of the folder.  This is a privileged command.`,
 				OptArg: true,
 			},
 			"/PRIVATE": {
@@ -602,15 +593,6 @@ of the folder or a user with privileges can use this command.
 			"/DESCRIPTION": {
 				Description: `  Specifies a new  description for the folder. You will  be prompted for
   the text of the description.`,
-			},
-			"/ID": {
-				Description: `  Designates  that the  name specified  as the  owner name  is a  rights
-  identifier. The  creator's process must have  the identifier presently
-  assigned to it.  Any process which has that identifier  assigned to it
-  will be able to  control the folder as if it  were the folder's owner.
-  This is used to allow more than one use to control a folder.
-
-  Note: This feature will not work during remote access to the folder.`,
 			},
 			"/NAME": {
 				Description: `/NAME=foldername
@@ -623,7 +605,7 @@ of the folder or a user with privileges can use this command.
 
   Specifies  a new  owner for  the folder.  If the  owner does  not have
   privileges, BULLETIN  will prompt  for the password  of the  new owner
-  account in order to okay the modification. See also /ID.`,
+  account in order to okay the modification.`,
 				OptArg: true,
 			},
 		},
@@ -1196,11 +1178,11 @@ READNEW setting (and visa versa).
 						Description: `  Specifies that the  SET BRIEF option is the default  for all users for
   the specified folder. This is a privileged qualifier.`,
 					},
-					"/DEFAULT": {
-						Description: `  Specifies  that the  BRIEF option  is  the default  for the  specified
-  folder. This is a privileged qualifier.  It will only affect brand new
-  users (or  those that have  never logged in).  Use /ALL to  modify all
-  users.`,
+					"/FOLDER": {
+						Description: `/FOLDER=foldername
+
+  Specifies the folder for which the option is to modified.  If not
+  specified, the selected folder is modified.`,
 					},
 					"/PERMANENT": {
 						Description: `/[NO]PERMANENT
@@ -1221,12 +1203,6 @@ privileged qualifier.`,
 					"/ALL": {
 						Description: `  Specifies that the SET NOBRIEF option is the default for all users for
   the specified folder. This is a privileged qualifier.`,
-					},
-					"/DEFAULT": {
-						Description: `  Specifies that  the NOBRIEF  option is the  default for  the specified
-  folder. This is a privileged qualifier.  It will only affect brand new
-  users (or  those that have  never logged in).  Use /ALL to  modify all
-  users.`,
 					},
 					"/FOLDER": {
 						Description: `/FOLDER=foldername
@@ -1337,6 +1313,7 @@ PROMPT_EXPIRE is the default.
 
   Format:
     SET PROMPT_EXPIRE`,
+				Action: ActionSetPromptExpire,
 			},
 			"NOPROMPT_EXPIRE": {
 				Description: `The user will not be prompted,  and the default expiration (which is set
@@ -1344,6 +1321,7 @@ by SET DEFAULT_EXPIRE) will be used.
 
   Format:
     SET NOPROMPT_EXPIRE`,
+				Action: ActionSetNoPromptExpire,
 			},
 			"READNEW": {
 				Description: `Controls whether you will be prompted upon logging in  if  you  wish  to
@@ -1367,10 +1345,17 @@ present in those other folders.  Also, it is not possible  to  EXIT  the
 READNEW mode if there are SYSTEM folders which have new messages. Typing
 the EXIT command will cause you to skip to those folders.  (See HELP SET
 SYSTEM for a description of a SYSTEM folder).`,
+				Action: ActionSetReadNew,
 				Flags: dclish.Flags{
 					"/ALL": {
 						Description: `  Specifies that the SET READNEW option is the default for all users for
   the specified folder.  This is a privileged  qualifier.`,
+					},
+					"/FOLDER": {
+						Description: `/FOLDER=foldername
+
+  Specifies  the folder  for which  the option  is to  modified. If  not
+  specified, the selected folder is modified.`,
 					},
 					"/PERMANENT": {
 						Description: `/[NO]PERMANENT
@@ -1384,6 +1369,7 @@ SYSTEM for a description of a SYSTEM folder).`,
 				Description: `Turns off READNEW.
   Format:
     SET NOREADNEW`,
+				Action: ActionSetNoReadNew,
 				Flags: dclish.Flags{
 					"/ALL": {
 						Description: `  Specifies that the  SET NOREADNEW option is the default  for all users
@@ -1414,6 +1400,12 @@ In order to apply this to a specific folder,  first  select  the  folder
 					"/ALL": {
 						Description: `  Specifies that the SET SHOWNEW option is the default for all users for
   the specified folder.  This is a privileged  qualifier.`,
+					},
+					"/FOLDER": {
+						Description: `/FOLDER=foldername
+
+  Specifies  the folder  for which  the option  is to  modified. If  not
+  specified, the selected folder is modified.`,
 					},
 					"/PERMANENT": {
 						Description: `/[NO]PERMANENT
diff --git a/repl/folders.go b/repl/folders.go
index dc67560d00bf770bbf4b735a2de45aeb09b4356d..c8c1e5b509931f9cf920e7668ea4f01675795b20 100644
--- a/repl/folders.go
+++ b/repl/folders.go
@@ -38,7 +38,7 @@ func ActionCreate(cmd *dclish.Command) error {
 		options.Always = 1
 	}
 	if cmd.Flags["/BRIEF"].Value == "true" {
-		options.Brief = 1
+		options.Alert = 1
 	}
 	if cmd.Flags["/DESCRIPTION"].Value != "" {
 		options.Description = cmd.Flags["/DESCRIPTION"].Value
@@ -47,10 +47,10 @@ func ActionCreate(cmd *dclish.Command) error {
 		options.Notify = 1
 	}
 	if cmd.Flags["/READNEW"].Value == "true" {
-		options.Readnew = 1
+		options.Alert = 2
 	}
 	if cmd.Flags["/SHOWNEW"].Value == "true" {
-		options.Shownew = 1
+		options.Alert = 3
 	}
 	if cmd.Flags["/SYSTEM"].Value == "true" {
 		options.System = 1
@@ -62,6 +62,11 @@ func ActionCreate(cmd *dclish.Command) error {
 		}
 		options.Expire = int64(expire)
 	}
+	if (cmd.Flags["/BRIEF"].Set && cmd.Flags["/READNEW"].Set) ||
+		(cmd.Flags["/BRIEF"].Set && cmd.Flags["/SHOWNEW"].Set) ||
+		(cmd.Flags["/READNEW"].Set && cmd.Flags["/SHOWNEW"].Set) {
+		return errors.New("Can only set one of /BRIEF, /READNEW and /SHOWNEW")
+	}
 	options.Visibility = folders.FolderPublic
 	if cmd.Flags["/PRIVATE"].Value == "true" && cmd.Flags["/SEMIPRIVATE"].Value == "true" {
 		return errors.New("Private or semi-private - pick one")
@@ -92,7 +97,6 @@ func ActionCreate(cmd *dclish.Command) error {
 		return errors.New("Description must exist and be under 53 characters")
 	}
 	err := folders.CreateFolder(owner, options)
-	// TODO: handle the /ID flag.
 	return err
 }
 
diff --git a/repl/set.go b/repl/set.go
index b41e963ac23063c024828bce5dbb416afd6af0fc..3cd9b8a78f7c6fa9961960cdbdcfda6160505730 100644
--- a/repl/set.go
+++ b/repl/set.go
@@ -13,6 +13,47 @@ import (
 	"git.lyda.ie/kevin/bulletin/this"
 )
 
+func setAlert(cmd *dclish.Command, alert int64) error {
+	optAll := cmd.Flags["/ALL"].Value == "true"
+
+	optPerm := false
+	if f, ok := cmd.Flags["/PERMANENT"]; ok {
+		optPerm = f.Value == "true"
+	}
+
+	folder := this.Folder
+	if cmd.Flags["/FOLDER"].Value != "" {
+		folder = folders.FindFolder(cmd.Flags["/FOLDER"].Value)
+	}
+	if folder.Name == "" {
+		return errors.New("Folder does not exist")
+	}
+
+	if optAll || optPerm {
+		if !folders.IsFolderOwner(folder.Name, this.User.Login) {
+			return errors.New("Not an admin or folder owner")
+		}
+	}
+
+	ctx := storage.Context()
+	if optAll && optPerm {
+		return this.Q.UpdateFolderAlert(ctx, storage.UpdateFolderAlertParams{
+			Alert: alert + 3,
+			Name:  folder.Name,
+		})
+	}
+	if optAll {
+		return this.Q.UpdateFolderAlert(ctx, storage.UpdateFolderAlertParams{
+			Alert: alert,
+			Name:  folder.Name,
+		})
+	}
+	return this.Q.UpdateUserAlert(ctx, storage.UpdateUserAlertParams{
+		Alert: alert,
+		Login: this.User.Login,
+	})
+}
+
 // ActionSet handles the `SET` command.
 func ActionSet(cmd *dclish.Command) error {
 	fmt.Println(cmd.Description)
@@ -46,25 +87,13 @@ func ActionSetNoalways(_ *dclish.Command) error {
 }
 
 // ActionSetBrief handles the `SET BRIEF` command.
-func ActionSetBrief(_ *dclish.Command) error {
-	// TODO: parse flags.
-	ctx := storage.Context()
-	this.Q.UpdateFolderBrief(ctx, storage.UpdateFolderBriefParams{
-		Brief: 1,
-		Name:  this.Folder.Name,
-	})
-	return nil
+func ActionSetBrief(cmd *dclish.Command) error {
+	return setAlert(cmd, storage.AlertBrief)
 }
 
 // ActionSetNobrief handles the `SET NOBRIEF` command.
-func ActionSetNobrief(_ *dclish.Command) error {
-	// TODO: parse flags.
-	ctx := storage.Context()
-	this.Q.UpdateFolderBrief(ctx, storage.UpdateFolderBriefParams{
-		Brief: 1,
-		Name:  this.Folder.Name,
-	})
-	return nil
+func ActionSetNobrief(cmd *dclish.Command) error {
+	return setAlert(cmd, storage.AlertNone)
 }
 
 // ActionSetDefaultExpire handles the `SET DEFAULT_EXPIRE` command.
@@ -140,76 +169,44 @@ func ActionSetNonotify(_ *dclish.Command) error {
 	return nil
 }
 
-// ActionSetPrivileges handles the `SET PRIVILEGES` command.
-func ActionSetPrivileges(cmd *dclish.Command) error {
-	// TODO: OK, need a better parser.
-	switch cmd.Args[0] {
-	case "CREATE":
-		if len(cmd.Args) != 2 {
-			fmt.Println("ERROR: Must pass single login.")
-			return nil
-		}
-		fmt.Println("TODO: Create user creation routine - see repl/repl.go.")
-	case "DELETE":
-		if len(cmd.Args) != 2 {
-			fmt.Println("ERROR: Must pass single login.")
-			return nil
-		}
-		fmt.Println("TODO: Create user delete routine - see repl/repl.go.")
-	case "SSH":
-		fmt.Println("TODO: Create ssh routine.")
-	case "ADMIN":
-		fmt.Println("TODO: Create an admin bit set/unset routine.")
-	case "NOADMIN":
-		fmt.Println("TODO: Create an admin bit set/unset routine.")
-	case "MOD":
-		fmt.Println("TODO: Create a mod bit set/unset routine.")
-	case "NOMOD":
-		fmt.Println("TODO: Create a mod bit set/unset routine.")
-	case "ENABLE":
-		fmt.Println("TODO: Create a disable bit set/unset routine.")
-	case "DISABLE":
-		fmt.Println("TODO: Create a disable bit set/unset routine.")
-	default:
-		fmt.Println("ERROR: Command not understood.")
-	}
-	return nil
-}
-
 // ActionSetPromptExpire handles the `SET PROMPT_EXPIRE` command.
 func ActionSetPromptExpire(_ *dclish.Command) error {
-	fmt.Println("TODO: implement ActionSetPromptExpire.")
+	ctx := storage.Context()
+	this.Q.UpdateUserPrompt(ctx, storage.UpdateUserPromptParams{
+		Login:  this.User.Login,
+		Prompt: 1,
+	})
 	return nil
 }
 
 // ActionSetNoPromptExpire handles the `SET NOPROMPT_EXPIRE` command.
 func ActionSetNoPromptExpire(_ *dclish.Command) error {
-	fmt.Println("TODO: implement ActionSetNopromptExpire.")
+	ctx := storage.Context()
+	this.Q.UpdateUserPrompt(ctx, storage.UpdateUserPromptParams{
+		Login:  this.User.Login,
+		Prompt: 0,
+	})
 	return nil
 }
 
 // ActionSetReadNew handles the `SET READNEW` command.
-func ActionSetReadNew(_ *dclish.Command) error {
-	fmt.Println("TODO: implement ActionSetReadNew.")
-	return nil
+func ActionSetReadNew(cmd *dclish.Command) error {
+	return setAlert(cmd, storage.AlertReadNew)
 }
 
 // ActionSetNoReadNew handles the `SET READNEW` command.
-func ActionSetNoReadNew(_ *dclish.Command) error {
-	fmt.Println("TODO: implement ActionSetNoReadNew.")
-	return nil
+func ActionSetNoReadNew(cmd *dclish.Command) error {
+	return setAlert(cmd, storage.AlertNone)
 }
 
 // ActionSetShowNew handles the `SET SHOWNEW` command.
-func ActionSetShowNew(_ *dclish.Command) error {
-	fmt.Println("TODO: implement ActionSetShowNew.")
-	return nil
+func ActionSetShowNew(cmd *dclish.Command) error {
+	return setAlert(cmd, storage.AlertShowNew)
 }
 
 // ActionSetNoShowNew handles the `SET SHOWNEW` command.
-func ActionSetNoShowNew(_ *dclish.Command) error {
-	fmt.Println("TODO: implement ActionSetNoShowNew.")
-	return nil
+func ActionSetNoShowNew(cmd *dclish.Command) error {
+	return setAlert(cmd, storage.AlertNone)
 }
 
 // ActionSetSystem handles the `SET SYSTEM` command.
diff --git a/repl/show.go b/repl/show.go
index e4c090e92b04f4e87d4858c0a4a9b7aad3c3528b..fdcd1c049d061b934e3a7779f0394a84e023fc11 100644
--- a/repl/show.go
+++ b/repl/show.go
@@ -28,16 +28,9 @@ func ActionShowFlags(_ *dclish.Command) error {
 		fmt.Println("  NOTIFY is set.")
 		flagset = true
 	}
-	if this.Folder.Readnew != 0 {
-		fmt.Println("  READNEW is set.")
-		flagset = true
-	}
-	if this.Folder.Brief != 0 {
-		fmt.Println("  BRIEF is set.")
-		flagset = true
-	}
-	if this.Folder.Shownew != 0 {
-		fmt.Println("  SHOWNEW is set.")
+	if this.Folder.Alert != 0 {
+		fmt.Printf("  %s is set.\n",
+			strings.ToUpper(storage.AlertString(this.Folder.Alert)))
 		flagset = true
 	}
 	if !flagset {
@@ -100,14 +93,9 @@ func ActionShowFolder(cmd *dclish.Command) error {
 	if this.Folder.Notify != 0 {
 		fmt.Println("  Default is NOTIFY.")
 	}
-	if this.Folder.Readnew != 0 {
-		fmt.Println("  Default is READNEW.")
-	}
-	if this.Folder.Brief != 0 {
-		fmt.Println("  Default is BRIEF.")
-	}
-	if this.Folder.Shownew != 0 {
-		fmt.Println("  Default is SHOWNEW.")
+	if this.Folder.Alert != 0 {
+		fmt.Printf("  %s is set.\n",
+			strings.ToUpper(storage.AlertString(this.Folder.Alert)))
 	}
 
 	return nil
diff --git a/storage/display.go b/storage/display.go
index b995426bb3c58a04078b96ca9a57dbeab80ae0b6..607b781412ff7bac94c0a38b88eefdf481203f94 100644
--- a/storage/display.go
+++ b/storage/display.go
@@ -6,6 +6,48 @@ import (
 	"time"
 )
 
+// Alert values.
+const (
+	AlertNone int64 = iota
+	AlertBrief
+	AlertReadNew
+	AlertShowNew
+	AlertBriefPerm
+	AlertReadNewPerm
+	AlertShowNewPerm
+)
+
+// AlertString translates an alert number to a string.
+func AlertString(alert int64) string {
+	var as = []string{
+		"None",
+		"Brief",
+		"ReadNew",
+		"ShowNew",
+	}
+	if alert < 0 || alert >= int64(len(as)) {
+		return "Unknown"
+	}
+	return as[alert]
+}
+
+// FolderAlertString translates an alert number to a string.
+func FolderAlertString(alert int64) string {
+	var as = []string{
+		"None",
+		"Brief",
+		"ReadNew",
+		"ShowNew",
+		"Brief (permanent)",
+		"ReadNew (permanent)",
+		"ShowNew (permanent)",
+	}
+	if alert < 0 || alert >= int64(len(as)) {
+		return "Unknown"
+	}
+	return as[alert]
+}
+
 // String renders a message.
 func (m *Message) String() string {
 	buf := &strings.Builder{}
@@ -37,26 +79,25 @@ func (m *Message) OneLine(expire bool) string {
 
 // String displays a user (mainly used for debugging).
 func (u User) String() string {
-	return fmt.Sprintf("%-12s %-25.25s [a%d, m%d, !%d, d%d] [%s]",
+	return fmt.Sprintf("%-12s %-25.25s [a%d, m%d, !%d, d%d, p%d] [%s]",
 		u.Login,
 		u.Name,
 		u.Admin,
 		u.Moderator,
 		u.Alert,
 		u.Disabled,
+		u.Prompt,
 		u.LastLogin.Format("06-01-02 15:04:05"))
 }
 
 // String displays a folder (mainly used for debugging).
 func (f Folder) String() string {
-	return fmt.Sprintf("Folder %s (%s) [a%d, b%d, n%d, rn%d, sn%d, sys%d, exp%d, v%d]",
+	return fmt.Sprintf("Folder %s (%s) [a%d, !<%s>, n%d, sys%d, exp%d, v%d]",
 		f.Name,
 		f.Description,
 		f.Always,
-		f.Brief,
+		FolderAlertString(f.Alert),
 		f.Notify,
-		f.Readnew,
-		f.Shownew,
 		f.System,
 		f.Expire,
 		f.Visibility)
diff --git a/storage/folders.sql.go b/storage/folders.sql.go
index 7476fc84eb5a23ee0deaccb009f5d4abaf003895..c24ab006ce87366837486ab4533af63127163386 100644
--- a/storage/folders.sql.go
+++ b/storage/folders.sql.go
@@ -24,22 +24,18 @@ func (q *Queries) AddFolderOwner(ctx context.Context, arg AddFolderOwnerParams)
 }
 
 const createFolder = `-- name: CreateFolder :exec
-INSERT INTO folders (
-  name, always, brief, description, notify, readnew, shownew, system,
-  expire, visibility
-) VALUES (
-  ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
-)
+INSERT INTO folders
+    (name, always, alert, description, notify, system, expire, visibility)
+  VALUES
+    (?, ?, ?, ?, ?, ?, ?, ?)
 `
 
 type CreateFolderParams struct {
 	Name        string
 	Always      int64
-	Brief       int64
+	Alert       int64
 	Description string
 	Notify      int64
-	Readnew     int64
-	Shownew     int64
 	System      int64
 	Expire      int64
 	Visibility  int64
@@ -49,11 +45,9 @@ func (q *Queries) CreateFolder(ctx context.Context, arg CreateFolderParams) erro
 	_, err := q.db.ExecContext(ctx, createFolder,
 		arg.Name,
 		arg.Always,
-		arg.Brief,
+		arg.Alert,
 		arg.Description,
 		arg.Notify,
-		arg.Readnew,
-		arg.Shownew,
 		arg.System,
 		arg.Expire,
 		arg.Visibility,
@@ -62,7 +56,7 @@ func (q *Queries) CreateFolder(ctx context.Context, arg CreateFolderParams) erro
 }
 
 const findFolderExact = `-- name: FindFolderExact :one
-SELECT name, "always", brief, description, notify, readnew, shownew, system, expire, visibility, create_at, update_at FROM folders where name = ?
+SELECT name, "always", alert, description, notify, system, expire, visibility, create_at, update_at FROM folders where name = ?
 `
 
 func (q *Queries) FindFolderExact(ctx context.Context, name string) (Folder, error) {
@@ -71,11 +65,9 @@ func (q *Queries) FindFolderExact(ctx context.Context, name string) (Folder, err
 	err := row.Scan(
 		&i.Name,
 		&i.Always,
-		&i.Brief,
+		&i.Alert,
 		&i.Description,
 		&i.Notify,
-		&i.Readnew,
-		&i.Shownew,
 		&i.System,
 		&i.Expire,
 		&i.Visibility,
@@ -86,7 +78,7 @@ func (q *Queries) FindFolderExact(ctx context.Context, name string) (Folder, err
 }
 
 const findFolderPrefix = `-- name: FindFolderPrefix :one
-SELECT name, "always", brief, description, notify, readnew, shownew, system, expire, visibility, create_at, update_at FROM folders where name LIKE ?
+SELECT name, "always", alert, description, notify, system, expire, visibility, create_at, update_at FROM folders where name LIKE ?
 ORDER BY name
 LIMIT 1
 `
@@ -97,11 +89,9 @@ func (q *Queries) FindFolderPrefix(ctx context.Context, name string) (Folder, er
 	err := row.Scan(
 		&i.Name,
 		&i.Always,
-		&i.Brief,
+		&i.Alert,
 		&i.Description,
 		&i.Notify,
-		&i.Readnew,
-		&i.Shownew,
 		&i.System,
 		&i.Expire,
 		&i.Visibility,
@@ -227,31 +217,31 @@ func (q *Queries) ListFolderForAdmin(ctx context.Context) ([]ListFolderForAdminR
 	return items, nil
 }
 
-const updateFolderAlways = `-- name: UpdateFolderAlways :exec
-UPDATE folders SET always = ? WHERE name = ?
+const updateFolderAlert = `-- name: UpdateFolderAlert :exec
+UPDATE folders SET alert = ? WHERE name = ?
 `
 
-type UpdateFolderAlwaysParams struct {
-	Always int64
-	Name   string
+type UpdateFolderAlertParams struct {
+	Alert int64
+	Name  string
 }
 
-func (q *Queries) UpdateFolderAlways(ctx context.Context, arg UpdateFolderAlwaysParams) error {
-	_, err := q.db.ExecContext(ctx, updateFolderAlways, arg.Always, arg.Name)
+func (q *Queries) UpdateFolderAlert(ctx context.Context, arg UpdateFolderAlertParams) error {
+	_, err := q.db.ExecContext(ctx, updateFolderAlert, arg.Alert, arg.Name)
 	return err
 }
 
-const updateFolderBrief = `-- name: UpdateFolderBrief :exec
-UPDATE folders SET brief = ? WHERE name = ?
+const updateFolderAlways = `-- name: UpdateFolderAlways :exec
+UPDATE folders SET always = ? WHERE name = ?
 `
 
-type UpdateFolderBriefParams struct {
-	Brief int64
-	Name  string
+type UpdateFolderAlwaysParams struct {
+	Always int64
+	Name   string
 }
 
-func (q *Queries) UpdateFolderBrief(ctx context.Context, arg UpdateFolderBriefParams) error {
-	_, err := q.db.ExecContext(ctx, updateFolderBrief, arg.Brief, arg.Name)
+func (q *Queries) UpdateFolderAlways(ctx context.Context, arg UpdateFolderAlwaysParams) error {
+	_, err := q.db.ExecContext(ctx, updateFolderAlways, arg.Always, arg.Name)
 	return err
 }
 
@@ -283,34 +273,6 @@ func (q *Queries) UpdateFolderNotify(ctx context.Context, arg UpdateFolderNotify
 	return err
 }
 
-const updateFolderReadnew = `-- name: UpdateFolderReadnew :exec
-UPDATE folders SET readnew = ? WHERE name = ?
-`
-
-type UpdateFolderReadnewParams struct {
-	Readnew int64
-	Name    string
-}
-
-func (q *Queries) UpdateFolderReadnew(ctx context.Context, arg UpdateFolderReadnewParams) error {
-	_, err := q.db.ExecContext(ctx, updateFolderReadnew, arg.Readnew, arg.Name)
-	return err
-}
-
-const updateFolderShownew = `-- name: UpdateFolderShownew :exec
-UPDATE folders SET shownew = ? WHERE name = ?
-`
-
-type UpdateFolderShownewParams struct {
-	Shownew int64
-	Name    string
-}
-
-func (q *Queries) UpdateFolderShownew(ctx context.Context, arg UpdateFolderShownewParams) error {
-	_, err := q.db.ExecContext(ctx, updateFolderShownew, arg.Shownew, arg.Name)
-	return err
-}
-
 const updateFolderSystem = `-- name: UpdateFolderSystem :exec
 UPDATE folders SET system = ? WHERE name = ?
 `
diff --git a/storage/migrations/1_create_table.up.sql b/storage/migrations/1_create_table.up.sql
index 690387f3681729ea3eee826d5ea6c1fbe6f86f6c..9ce50b932e9b810659a5c7e2b840074270bc8800 100644
--- a/storage/migrations/1_create_table.up.sql
+++ b/storage/migrations/1_create_table.up.sql
@@ -3,8 +3,10 @@ CREATE TABLE users (
   name           VARCHAR(53)  NOT NULL,
   admin          INT          DEFAULT 0 NOT NULL,
   moderator      INT          DEFAULT 0 NOT NULL,
-  alert          INT          DEFAULT 0 NOT NULL,  --- 0=no, 1=brief, 2=readnew
+  --- 0=no, 1=brief, 2=readnew, 3=shownew
+  alert          INT          DEFAULT 0 NOT NULL,
   disabled       INT          DEFAULT 0 NOT NULL,
+  prompt         INT          DEFAULT 0 NOT NULL,
   last_broadcast TIMESTAMP    DEFAULT CURRENT_TIMESTAMP NOT NULL,
   last_login     TIMESTAMP    DEFAULT CURRENT_TIMESTAMP NOT NULL,
   create_at      TIMESTAMP    DEFAULT CURRENT_TIMESTAMP NOT NULL,
@@ -35,11 +37,10 @@ END;
 CREATE TABLE folders (
   name        VARCHAR(25)  PRIMARY KEY NOT NULL,
   always      INT          DEFAULT 0 NOT NULL,
-  brief       INT          DEFAULT 0 NOT NULL,
+  --- 0=no, 1(4)=brief(p), 2(5)=readnew(p), 3(6)=shownew(p)
+  alert       INT          DEFAULT 0 NOT NULL,
   description VARCHAR(53)  DEFAULT 0 NOT NULL,
   notify      INT          DEFAULT 0 NOT NULL,
-  readnew     INT          DEFAULT 0 NOT NULL,
-  shownew     INT          DEFAULT 0 NOT NULL,
   system      INT          DEFAULT 0 NOT NULL,
   expire      INT          DEFAULT 14 NOT NULL,
   --- public=0, semiprivate=1, private=2
@@ -174,7 +175,8 @@ CREATE TABLE folder_configs (
   folder      VARCHAR(25) REFERENCES folders(name)
               ON DELETE CASCADE ON UPDATE CASCADE NOT NULL,
   always      INT     DEFAULT 0 NOT NULL,
-  alert       INT     DEFAULT 0 NOT NULL,  --- 0=no, 1=brief, 2=readnew
+  --- 0=no, 1=brief, 2=readnew, 3=shownew
+  alert       INT     DEFAULT 0 NOT NULL,
   PRIMARY KEY (login, folder)
 ) WITHOUT ROWID;
 
diff --git a/storage/models.go b/storage/models.go
index 98bbe360c232fa796eb495e419b8b6b4c34d8542..2c0d9c0cc6a133dc1a5c05aa0591475ccf321951 100644
--- a/storage/models.go
+++ b/storage/models.go
@@ -18,11 +18,9 @@ type Broadcast struct {
 type Folder struct {
 	Name        string
 	Always      int64
-	Brief       int64
+	Alert       int64
 	Description string
 	Notify      int64
-	Readnew     int64
-	Shownew     int64
 	System      int64
 	Expire      int64
 	Visibility  int64
@@ -89,6 +87,7 @@ type User struct {
 	Moderator     int64
 	Alert         int64
 	Disabled      int64
+	Prompt        int64
 	LastBroadcast time.Time
 	LastLogin     time.Time
 	CreateAt      time.Time
diff --git a/storage/queries/folders.sql b/storage/queries/folders.sql
index 3c5f8a26b8c9ebb4304d3eb55853e83e25d793f9..9f7e956081ec075a796dd9782864ff069265ad4a 100644
--- a/storage/queries/folders.sql
+++ b/storage/queries/folders.sql
@@ -1,10 +1,8 @@
 -- name: CreateFolder :exec
-INSERT INTO folders (
-  name, always, brief, description, notify, readnew, shownew, system,
-  expire, visibility
-) VALUES (
-  ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
-);
+INSERT INTO folders
+    (name, always, alert, description, notify, system, expire, visibility)
+  VALUES
+    (?, ?, ?, ?, ?, ?, ?, ?);
 
 -- name: AddFolderOwner :exec
 INSERT INTO owners (folder, login) VALUES (?, ?);
@@ -45,18 +43,12 @@ UPDATE folders SET always = ? WHERE name = ?;
 -- name: UpdateFolderSystem :exec
 UPDATE folders SET system = ? WHERE name = ?;
 
--- name: UpdateFolderBrief :exec
-UPDATE folders SET brief = ? WHERE name = ?;
+-- name: UpdateFolderAlert :exec
+UPDATE folders SET alert = ? WHERE name = ?;
 
 -- name: UpdateFolderNotify :exec
 UPDATE folders SET notify = ? WHERE name = ?;
 
--- name: UpdateFolderReadnew :exec
-UPDATE folders SET readnew = ? WHERE name = ?;
-
--- name: UpdateFolderShownew :exec
-UPDATE folders SET shownew = ? WHERE name = ?;
-
 -- name: UpdateFolderVisibility :exec
 UPDATE folders SET visibility = ? WHERE name = ?;
 
diff --git a/storage/queries/seed.sql b/storage/queries/seed.sql
index 5772eb0de26d41dd8ac541482fa5e0d8927afa0d..8d765435fe9e9f04912a94d338f1a366ac94c16d 100644
--- a/storage/queries/seed.sql
+++ b/storage/queries/seed.sql
@@ -1,18 +1,17 @@
 -- name: SeedUserSystem :exec
-  INSERT INTO users (login, name, admin, moderator)
-         VALUES ('SYSTEM', 'System User', 1, 1);
+INSERT INTO users (login, name, admin, moderator)
+  VALUES ('SYSTEM', 'System User', 1, 1);
 
 -- name: SeedFolderGeneral :exec
-  INSERT INTO folders (name, description, system, shownew)
-         VALUES ('GENERAL', 'Default general bulletin folder.', 1, 1);
+INSERT INTO folders (name, description, system, alert)
+  VALUES ('GENERAL', 'Default general bulletin folder.', 1, 1);
 
 -- name: SeedGeneralOwner :exec
-  INSERT INTO owners (folder, login) VALUES ('GENERAL', 'SYSTEM');
+INSERT INTO owners (folder, login) VALUES ('GENERAL', 'SYSTEM');
 
 -- name: SeedCreateMessage :exec
-INSERT INTO messages (
-  id,
-  folder, author, subject, message, permanent, create_at, update_at, expiration
-) VALUES (
-  (SELECT COALESCE(MAX(id), 0) + 1 FROM messages AS m WHERE m.folder = ?1),
-  ?1, ?2, ?3, ?4, 1, ?5, ?5, ?6);
+INSERT INTO messages
+    (id, folder, author, subject, message, permanent, create_at, update_at, expiration)
+  VALUES
+    ((SELECT COALESCE(MAX(id), 0) + 1 FROM messages AS m WHERE m.folder = ?1),
+     ?1, ?2, ?3, ?4, 1, ?5, ?5, ?6);
diff --git a/storage/queries/users.sql b/storage/queries/users.sql
index d87b01581a25271c33d11dd8a5e0146593dcd12c..ad343c7fb00d5c1d505fdffa7410dc19cac90d29 100644
--- a/storage/queries/users.sql
+++ b/storage/queries/users.sql
@@ -23,6 +23,9 @@ UPDATE users SET name = ? WHERE login = ? AND login != 'SYSTEM';
 -- name: UpdateUserMod :exec
 UPDATE users SET moderator = ? WHERE login = ? AND login != 'SYSTEM';
 
+-- name: UpdateUserPrompt :exec
+UPDATE users SET prompt = ? WHERE login = ? AND login != 'SYSTEM';
+
 -- name: UpdateUserLastLogin :one
 UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE login = ? AND login != 'SYSTEM'
 RETURNING last_login;
diff --git a/storage/seed.sql.go b/storage/seed.sql.go
index 0f21d68ea537349116887b5424832bb4378128d2..e33741e616e5f530fd041938e36f4fd25e47494c 100644
--- a/storage/seed.sql.go
+++ b/storage/seed.sql.go
@@ -11,12 +11,11 @@ import (
 )
 
 const seedCreateMessage = `-- name: SeedCreateMessage :exec
-INSERT INTO messages (
-  id,
-  folder, author, subject, message, permanent, create_at, update_at, expiration
-) VALUES (
-  (SELECT COALESCE(MAX(id), 0) + 1 FROM messages AS m WHERE m.folder = ?1),
-  ?1, ?2, ?3, ?4, 1, ?5, ?5, ?6)
+INSERT INTO messages
+    (id, folder, author, subject, message, permanent, create_at, update_at, expiration)
+  VALUES
+    ((SELECT COALESCE(MAX(id), 0) + 1 FROM messages AS m WHERE m.folder = ?1),
+     ?1, ?2, ?3, ?4, 1, ?5, ?5, ?6)
 `
 
 type SeedCreateMessageParams struct {
@@ -41,8 +40,8 @@ func (q *Queries) SeedCreateMessage(ctx context.Context, arg SeedCreateMessagePa
 }
 
 const seedFolderGeneral = `-- name: SeedFolderGeneral :exec
-  INSERT INTO folders (name, description, system, shownew)
-         VALUES ('GENERAL', 'Default general bulletin folder.', 1, 1)
+INSERT INTO folders (name, description, system, alert)
+  VALUES ('GENERAL', 'Default general bulletin folder.', 1, 1)
 `
 
 func (q *Queries) SeedFolderGeneral(ctx context.Context) error {
@@ -51,7 +50,7 @@ func (q *Queries) SeedFolderGeneral(ctx context.Context) error {
 }
 
 const seedGeneralOwner = `-- name: SeedGeneralOwner :exec
-  INSERT INTO owners (folder, login) VALUES ('GENERAL', 'SYSTEM')
+INSERT INTO owners (folder, login) VALUES ('GENERAL', 'SYSTEM')
 `
 
 func (q *Queries) SeedGeneralOwner(ctx context.Context) error {
@@ -60,8 +59,8 @@ func (q *Queries) SeedGeneralOwner(ctx context.Context) error {
 }
 
 const seedUserSystem = `-- name: SeedUserSystem :exec
-  INSERT INTO users (login, name, admin, moderator)
-         VALUES ('SYSTEM', 'System User', 1, 1)
+INSERT INTO users (login, name, admin, moderator)
+  VALUES ('SYSTEM', 'System User', 1, 1)
 `
 
 func (q *Queries) SeedUserSystem(ctx context.Context) error {
diff --git a/storage/standard.sql.go b/storage/standard.sql.go
index be420e6a039caaa49d4dc16689a8bf454050a882..ea36c688a1a1f2d19e1a6104269888325e5dcd07 100644
--- a/storage/standard.sql.go
+++ b/storage/standard.sql.go
@@ -209,7 +209,7 @@ func (q *Queries) DeleteUser(ctx context.Context, login string) error {
 }
 
 const getFolder = `-- name: GetFolder :one
-SELECT name, "always", brief, description, notify, readnew, shownew, system, expire, visibility, create_at, update_at FROM folders WHERE name = ?
+SELECT name, "always", alert, description, notify, system, expire, visibility, create_at, update_at FROM folders WHERE name = ?
 `
 
 func (q *Queries) GetFolder(ctx context.Context, name string) (Folder, error) {
@@ -218,11 +218,9 @@ func (q *Queries) GetFolder(ctx context.Context, name string) (Folder, error) {
 	err := row.Scan(
 		&i.Name,
 		&i.Always,
-		&i.Brief,
+		&i.Alert,
 		&i.Description,
 		&i.Notify,
-		&i.Readnew,
-		&i.Shownew,
 		&i.System,
 		&i.Expire,
 		&i.Visibility,
@@ -460,7 +458,7 @@ func (q *Queries) ListFolderConfig(ctx context.Context) ([]FolderConfig, error)
 }
 
 const listFolders = `-- name: ListFolders :many
-SELECT name, "always", brief, description, notify, readnew, shownew, system, expire, visibility, create_at, update_at FROM folders
+SELECT name, "always", alert, description, notify, system, expire, visibility, create_at, update_at FROM folders
 `
 
 func (q *Queries) ListFolders(ctx context.Context) ([]Folder, error) {
@@ -475,11 +473,9 @@ func (q *Queries) ListFolders(ctx context.Context) ([]Folder, error) {
 		if err := rows.Scan(
 			&i.Name,
 			&i.Always,
-			&i.Brief,
+			&i.Alert,
 			&i.Description,
 			&i.Notify,
-			&i.Readnew,
-			&i.Shownew,
 			&i.System,
 			&i.Expire,
 			&i.Visibility,
@@ -662,7 +658,7 @@ func (q *Queries) ListSeen(ctx context.Context) ([]Seen, error) {
 }
 
 const listUsers = `-- name: ListUsers :many
-SELECT login, name, admin, moderator, alert, disabled, last_broadcast, last_login, create_at, update_at FROM users
+SELECT login, name, admin, moderator, alert, disabled, prompt, last_broadcast, last_login, create_at, update_at FROM users
 `
 
 func (q *Queries) ListUsers(ctx context.Context) ([]User, error) {
@@ -681,6 +677,7 @@ func (q *Queries) ListUsers(ctx context.Context) ([]User, error) {
 			&i.Moderator,
 			&i.Alert,
 			&i.Disabled,
+			&i.Prompt,
 			&i.LastBroadcast,
 			&i.LastLogin,
 			&i.CreateAt,
diff --git a/storage/users.sql.go b/storage/users.sql.go
index 613b4c13abc8ecd3ccfa6ad4efe0c7b1ca8a7996..b80de521290a6b25f3c341e952782c6556ff7004 100644
--- a/storage/users.sql.go
+++ b/storage/users.sql.go
@@ -12,7 +12,7 @@ import (
 
 const addUser = `-- name: AddUser :one
 INSERT INTO users (login, name, admin, disabled, last_login) VALUES (?, ?, ?, ?, ?)
-RETURNING login, name, admin, moderator, alert, disabled, last_broadcast, last_login, create_at, update_at
+RETURNING login, name, admin, moderator, alert, disabled, prompt, last_broadcast, last_login, create_at, update_at
 `
 
 type AddUserParams struct {
@@ -39,6 +39,7 @@ func (q *Queries) AddUser(ctx context.Context, arg AddUserParams) (User, error)
 		&i.Moderator,
 		&i.Alert,
 		&i.Disabled,
+		&i.Prompt,
 		&i.LastBroadcast,
 		&i.LastLogin,
 		&i.CreateAt,
@@ -128,7 +129,7 @@ func (q *Queries) GetLastLoginByLogin(ctx context.Context, login string) (GetLas
 }
 
 const getUser = `-- name: GetUser :one
-SELECT login, name, admin, moderator, alert, disabled, last_broadcast, last_login, create_at, update_at FROM users WHERE login = ?
+SELECT login, name, admin, moderator, alert, disabled, prompt, last_broadcast, last_login, create_at, update_at FROM users WHERE login = ?
 `
 
 func (q *Queries) GetUser(ctx context.Context, login string) (User, error) {
@@ -141,6 +142,7 @@ func (q *Queries) GetUser(ctx context.Context, login string) (User, error) {
 		&i.Moderator,
 		&i.Alert,
 		&i.Disabled,
+		&i.Prompt,
 		&i.LastBroadcast,
 		&i.LastLogin,
 		&i.CreateAt,
@@ -241,3 +243,17 @@ func (q *Queries) UpdateUserName(ctx context.Context, arg UpdateUserNameParams)
 	_, err := q.db.ExecContext(ctx, updateUserName, arg.Name, arg.Login)
 	return err
 }
+
+const updateUserPrompt = `-- name: UpdateUserPrompt :exec
+UPDATE users SET prompt = ? WHERE login = ? AND login != 'SYSTEM'
+`
+
+type UpdateUserPromptParams struct {
+	Prompt int64
+	Login  string
+}
+
+func (q *Queries) UpdateUserPrompt(ctx context.Context, arg UpdateUserPromptParams) error {
+	_, err := q.db.ExecContext(ctx, updateUserPrompt, arg.Prompt, arg.Login)
+	return err
+}