chore: cleaned up trigger problems in allium specs

This commit is contained in:
Bauer, Georg
2026-07-22 14:33:42 +02:00
parent 2fc683d513
commit 1dd8194fa8
5 changed files with 66 additions and 32 deletions

View File

@@ -68,7 +68,8 @@ rule AirplaneGate {
} }
rule RebuildFull { rule RebuildFull {
when: CliCommandExecuted(command: rebuild) when: CliCommandExecuted(command)
requires: command = rebuild
requires: not CliInvocation.incremental requires: not CliInvocation.incremental
-- The same step sequence as the GUI "Rebuild Database" -- The same step sequence as the GUI "Rebuild Database"
-- (BDS.Maintenance.full_rebuild_steps — posts, media, scripts, -- (BDS.Maintenance.full_rebuild_steps — posts, media, scripts,
@@ -78,7 +79,8 @@ rule RebuildFull {
} }
rule RebuildIncremental { rule RebuildIncremental {
when: CliCommandExecuted(command: rebuild) when: CliCommandExecuted(command)
requires: command = rebuild
requires: CliInvocation.incremental requires: CliInvocation.incremental
-- Metadata diff, then auto-apply file→db for every difference and -- Metadata diff, then auto-apply file→db for every difference and
-- import every orphan file. -- import every orphan file.
@@ -86,7 +88,8 @@ rule RebuildIncremental {
} }
rule Repair { rule Repair {
when: CliCommandExecuted(command: repair) when: CliCommandExecuted(command)
requires: command = repair
-- Subcommand argument selects the repair part: post-links, -- Subcommand argument selects the repair part: post-links,
-- media-links, thumbnails, embeddings, or search — the standard -- media-links, thumbnails, embeddings, or search — the standard
-- rebuild tasks outside the full rebuild. -- rebuild tasks outside the full rebuild.
@@ -94,7 +97,8 @@ rule Repair {
} }
rule Render { rule Render {
when: CliCommandExecuted(command: render) when: CliCommandExecuted(command)
requires: command = render
-- Default: render all site sections plus the search index. -- Default: render all site sections plus the search index.
-- --incremental: validate the generated output and apply only the -- --incremental: validate the generated output and apply only the
-- differences (targeted render + extra-file deletion + calendar). -- differences (targeted render + extra-file deletion + calendar).
@@ -104,14 +108,16 @@ rule Render {
} }
rule Upload { rule Upload {
when: CliCommandExecuted(command: upload) when: CliCommandExecuted(command)
requires: command = upload
-- Uses the project publishing preferences (ssh host/user/path/mode) -- Uses the project publishing preferences (ssh host/user/path/mode)
-- exactly like the app's upload, and waits for the publish job. -- exactly like the app's upload, and waits for the publish job.
ensures: SiteUploaded() ensures: SiteUploaded()
} }
rule GitSync { rule GitSync {
when: CliCommandExecuted(command: push | pull) when: CliCommandExecuted(command)
requires: command = push or command = pull
-- push: git push of the project repository to origin. -- push: git push of the project repository to origin.
-- pull: git pull --ff-only, then the incremental cache update -- pull: git pull --ff-only, then the incremental cache update
-- (metadata diff auto-apply + orphan import) so the database -- (metadata diff auto-apply + orphan import) so the database
@@ -120,7 +126,8 @@ rule GitSync {
} }
rule CreatePost { rule CreatePost {
when: CliCommandExecuted(command: post) when: CliCommandExecuted(command)
requires: command = post
-- Post data from parameters or JSON on stdin (LLM-friendly). -- Post data from parameters or JSON on stdin (LLM-friendly).
-- Language is auto-detected when missing: the configured AI -- Language is auto-detected when missing: the configured AI
-- endpoint (airplane mode routes to the local model), falling back -- endpoint (airplane mode routes to the local model), falling back
@@ -132,7 +139,8 @@ rule CreatePost {
} }
rule CreateMedia { rule CreateMedia {
when: CliCommandExecuted(command: media) when: CliCommandExecuted(command)
requires: command = media
-- Imports the image, then best-effort AI enrichment: generated -- Imports the image, then best-effort AI enrichment: generated
-- title, alt text, caption, and translations to all configured -- title, alt text, caption, and translations to all configured
-- blog languages (the gallery pipeline without post linking). -- blog languages (the gallery pipeline without post linking).
@@ -140,7 +148,8 @@ rule CreateMedia {
} }
rule CreateGallery { rule CreateGallery {
when: CliCommandExecuted(command: gallery) when: CliCommandExecuted(command)
requires: command = gallery
-- Creates the post, then runs the shared gallery import pipeline -- Creates the post, then runs the shared gallery import pipeline
-- for every referenced image: import, mandatory post link, AI -- for every referenced image: import, mandatory post link, AI
-- enrichment, translations; finally the post auto-translation. -- enrichment, translations; finally the post auto-translation.
@@ -149,7 +158,8 @@ rule CreateGallery {
} }
rule Preferences { rule Preferences {
when: CliCommandExecuted(command: config) when: CliCommandExecuted(command)
requires: command = config
-- get/list expose effective global preferences shared with the app: -- get/list expose effective global preferences shared with the app:
-- canonical defaults overlaid by persisted values. Project-file settings and -- canonical defaults overlaid by persisted values. Project-file settings and
-- internal maintenance state are outside this list. Secret-backed keys remain -- internal maintenance state are outside this list. Secret-backed keys remain
@@ -159,21 +169,24 @@ rule Preferences {
} }
rule Projects { rule Projects {
when: CliCommandExecuted(command: project) when: CliCommandExecuted(command)
requires: command = project
-- list, add <path> (register a folder in the cache database), and -- list, add <path> (register a folder in the cache database), and
-- switch <id|slug|name> (change the active project). -- switch <id|slug|name> (change the active project).
ensures: ProjectRegistryUpdated() ensures: ProjectRegistryUpdated()
} }
rule Tui { rule Tui {
when: CliCommandExecuted(command: tui) when: CliCommandExecuted(command)
requires: command = tui
-- The native CLI enters TUI boot mode so the interactive terminal UI owns -- The native CLI enters TUI boot mode so the interactive terminal UI owns
-- the terminal. -- the terminal.
ensures: TuiStarted() ensures: TuiStarted()
} }
rule Server { rule Server {
when: CliCommandExecuted(command: server) when: CliCommandExecuted(command)
requires: command = server
-- Starts the dedicated headless SSH host with optional bind address, port, -- Starts the dedicated headless SSH host with optional bind address, port,
-- database path, and data-directory overrides. The standalone bds-server -- database path, and data-directory overrides. The standalone bds-server
-- executable is not distributed. -- executable is not distributed.
@@ -181,7 +194,8 @@ rule Server {
} }
rule RunLuaTask { rule RunLuaTask {
when: CliCommandExecuted(command: lua) when: CliCommandExecuted(command)
requires: command = lua
-- Runs a utility ("task", long-running) script from the database by -- Runs a utility ("task", long-running) script from the database by
-- slug in the active project, with the managed-job execution budget -- slug in the active project, with the managed-job execution budget
-- (unlimited time/reductions) but synchronously. Macro and -- (unlimited time/reductions) but synchronously. Macro and
@@ -190,7 +204,8 @@ rule RunLuaTask {
} }
rule InstallLauncher { rule InstallLauncher {
when: CliInstallRequested() or CliCommandExecuted(command: install) when: CliInstallRequested() or CliCommandExecuted(command)
requires: command = install
-- Settings/Data, the future TUI settings action, and `bds-cli install` -- Settings/Data, the future TUI settings action, and `bds-cli install`
-- share one guarded installer. A forwarding launcher written to -- share one guarded installer. A forwarding launcher written to
-- ~/.local/bin/bds-cli executes the packaged native CLI in place, so it -- ~/.local/bin/bds-cli executes the packaged native CLI in place, so it

View File

@@ -60,7 +60,8 @@ rule ClientUnsubscription {
} }
rule ServerSideUiLanguage { rule ServerSideUiLanguage {
when: GlobalSettingWritten(key: "ui.language") when: GlobalSettingWritten(key)
requires: key = "ui.language"
-- The UI language is a single server-side setting: changing it in any -- The UI language is a single server-side setting: changing it in any
-- client persists it and re-renders every connected client. The OS -- client persists it and re-renders every connected client. The OS
-- locale is only the fallback when the setting is unset. -- locale is only the fallback when the setting is unset.

View File

@@ -384,7 +384,7 @@ config {
-- ============================================================================ -- ============================================================================
rule IndexMediaForSearch { rule IndexMediaForSearch {
when: SearchIndexUpdated(media: media/Media) when: SearchIndexUpdated(media)
-- Index fields: title, alt, caption, original_name, tags -- Index fields: title, alt, caption, original_name, tags
-- Plus all translation titles, alts, and captions -- Plus all translation titles, alts, and captions
let all_text = concat( let all_text = concat(

View File

@@ -52,13 +52,15 @@ rule ModeResolution {
} }
rule DesktopBoot { rule DesktopBoot {
when: ApplicationStarted(mode: desktop) when: ApplicationStarted(mode)
requires: mode = desktop
-- Unchanged behavior: wx window shell, loopback HTTP endpoint. -- Unchanged behavior: wx window shell, loopback HTTP endpoint.
ensures: DesktopWindowStarted() ensures: DesktopWindowStarted()
} }
rule ServerBoot { rule ServerBoot {
when: ApplicationStarted(mode: server) when: ApplicationStarted(mode)
requires: mode = server
-- Started by `bds-cli server` or explicit desktop boot mode. Headless: no -- Started by `bds-cli server` or explicit desktop boot mode. Headless: no
-- desktop UI children at all. Works on macOS, Windows, Linux. -- desktop UI children at all. Works on macOS, Windows, Linux.
ensures: LoopbackEndpointStarted() ensures: LoopbackEndpointStarted()

View File

@@ -24,7 +24,8 @@ surface TuiSurface {
} }
rule SidebarNavigation { rule SidebarNavigation {
when: TuiKeyPressed(code: "up" | "down" | "j" | "k") when: TuiKeyPressed(code, _)
requires: code = "up" or code = "down" or code = "j" or code = "k"
-- Selection moves over the flattened sidebar items and skips -- Selection moves over the flattened sidebar items and skips
-- section headers; data comes from BDS.UI.Sidebar.view, identical -- section headers; data comes from BDS.UI.Sidebar.view, identical
-- to the GUI sidebar content. -- to the GUI sidebar content.
@@ -32,7 +33,8 @@ rule SidebarNavigation {
} }
rule OpenEntry { rule OpenEntry {
when: TuiKeyPressed(code: "enter") when: TuiKeyPressed(code, _)
requires: code = "enter"
-- Posts open in the editor by default (title + textarea seeded from -- Posts open in the editor by default (title + textarea seeded from
-- the persisted form; syntax highlighting and word wrap on; ctrl+e -- the persisted form; syntax highlighting and word wrap on; ctrl+e
-- switches to the rendered preview). New empty posts created with -- switches to the rendered preview). New empty posts created with
@@ -43,7 +45,9 @@ rule OpenEntry {
} }
rule SaveAndPublish { rule SaveAndPublish {
when: TuiKeyPressed(code: "s" | "p", modifiers: "ctrl") when: TuiKeyPressed(code, modifiers)
requires: code = "s" or code = "p"
requires: modifiers = "ctrl"
-- ctrl+s saves the draft, ctrl+p saves and publishes — both through -- ctrl+s saves the draft, ctrl+p saves and publishes — both through
-- BDS.UI.PostEditor.Persistence, so files, embeddings, search, and -- BDS.UI.PostEditor.Persistence, so files, embeddings, search, and
-- the event bus behave exactly as a GUI save. -- the event bus behave exactly as a GUI save.
@@ -51,7 +55,9 @@ rule SaveAndPublish {
} }
rule EditorMode { rule EditorMode {
when: TuiKeyPressed(code: "e", modifiers: "ctrl") when: TuiKeyPressed(code, modifiers)
requires: code = "e"
requires: modifiers = "ctrl"
-- ctrl+e toggles between the syntax-highlighted editor (the default -- ctrl+e toggles between the syntax-highlighted editor (the default
-- mode when opening a post) and the read-only rendered-Markdown -- mode when opening a post) and the read-only rendered-Markdown
-- preview (rendered through tui-markdown so headings/emphasis/lists -- preview (rendered through tui-markdown so headings/emphasis/lists
@@ -72,7 +78,9 @@ rule CodeEditorWrapping {
} }
rule AiQuickAction { rule AiQuickAction {
when: TuiKeyPressed(code: "g", modifiers: "ctrl") when: TuiKeyPressed(code, modifiers)
requires: code = "g"
requires: modifiers = "ctrl"
-- One-shot AI post analysis (title/excerpt suggestions). Gated by -- One-shot AI post analysis (title/excerpt suggestions). Gated by
-- airplane mode: without a local endpoint the TUI shows a status -- airplane mode: without a local endpoint the TUI shows a status
-- message instead of calling out. -- message instead of calling out.
@@ -80,7 +88,8 @@ rule AiQuickAction {
} }
rule ProjectSwitcher { rule ProjectSwitcher {
when: TuiKeyPressed(code: "p") when: TuiKeyPressed(code, _)
requires: code = "p"
-- "p" opens the projects overlay: all projects from the caching -- "p" opens the projects overlay: all projects from the caching
-- database with the active one marked; enter activates the selected -- database with the active one marked; enter activates the selected
-- project (BDS.Projects.set_active_project) and reloads the sidebar. -- project (BDS.Projects.set_active_project) and reloads the sidebar.
@@ -100,7 +109,8 @@ rule ProjectSwitcher {
} }
rule SidebarSearch { rule SidebarSearch {
when: TuiKeyPressed(code: "/") when: TuiKeyPressed(code, _)
requires: code = "/"
-- "/" in sidebar focus opens a vi-style search prompt in the status -- "/" in sidebar focus opens a vi-style search prompt in the status
-- line that live-filters the current view through the same -- line that live-filters the current view through the same
-- BDS.UI.Sidebar filter params the GUI sidebar uses (posts, pages, -- BDS.UI.Sidebar filter params the GUI sidebar uses (posts, pages,
@@ -113,7 +123,8 @@ rule SidebarSearch {
} }
rule CommandPrompt { rule CommandPrompt {
when: TuiKeyPressed(code: ":") when: TuiKeyPressed(code, _)
requires: code = ":"
-- Vi-style prompt: ":" opens a filterable list of the parameterless -- Vi-style prompt: ":" opens a filterable list of the parameterless
-- Blog-menu shell commands (metadata diff, validate site, force -- Blog-menu shell commands (metadata diff, validate site, force
-- render, rebuilds, reindex, translations, duplicates, upload, -- render, rebuilds, reindex, translations, duplicates, upload,
@@ -127,7 +138,8 @@ rule CommandPrompt {
} }
rule SettingsPanel { rule SettingsPanel {
when: TuiKeyPressed(code: "6") when: TuiKeyPressed(code, _)
requires: code = "6"
-- "6" opens the settings panel (issue #29), matching the GUI panel -- "6" opens the settings panel (issue #29), matching the GUI panel
-- numbering: the sidebar lists the same preference sections as the -- numbering: the sidebar lists the same preference sections as the
-- settings backends (Project, Editor, Content, AI, Technology, -- settings backends (Project, Editor, Content, AI, Technology,
@@ -145,7 +157,8 @@ rule SettingsPanel {
} }
rule TagsPanel { rule TagsPanel {
when: TuiKeyPressed(code: "5") when: TuiKeyPressed(code, _)
requires: code = "5"
-- "5" opens the tags view (issue #34), matching the GUI panel -- "5" opens the tags view (issue #34), matching the GUI panel
-- numbering. The sidebar lists the same three sections as the GUI -- numbering. The sidebar lists the same three sections as the GUI
-- tags editor (Tag Cloud, Create / Edit, Merge Tags — from -- tags editor (Tag Cloud, Create / Edit, Merge Tags — from
@@ -165,7 +178,8 @@ rule TagsPanel {
} }
rule GitPanel { rule GitPanel {
when: TuiKeyPressed(code: "7") when: TuiKeyPressed(code, _)
requires: code = "7"
-- "7" opens the git panel (issue #30) for content sync: the sidebar -- "7" opens the git panel (issue #30) for content sync: the sidebar
-- lists the changed files from git status (code + path, branch with -- lists the changed files from git status (code + path, branch with
-- ahead/behind counts in the title) with the commit history in its -- ahead/behind counts in the title) with the commit history in its
@@ -183,7 +197,8 @@ rule GitPanel {
} }
rule ReportPanels { rule ReportPanels {
when: ShellTaskCompleted(route: "metadata_diff" | "site_validation") when: ShellTaskCompleted(route)
requires: route = "metadata_diff" or route = "site_validation"
-- Completed metadata diff and site validation tasks open a -- Completed metadata diff and site validation tasks open a
-- scrollable report panel showing the differences. Enter applies -- scrollable report panel showing the differences. Enter applies
-- the whole report — metadata diff repairs all items from the -- the whole report — metadata diff repairs all items from the
@@ -204,7 +219,8 @@ rule MultiClientSync {
} }
rule ServerSideLocale { rule ServerSideLocale {
when: TuiSettingsChanged(key: "ui.language") when: TuiSettingsChanged(key)
requires: key = "ui.language"
-- The TUI re-reads the server-side UI language and re-renders; all -- The TUI re-reads the server-side UI language and re-renders; all
-- clients always share one language. -- clients always share one language.
ensures: TuiRelocalized() ensures: TuiRelocalized()