From 1a2402772301b689186090e948182c84c3b12f2b Mon Sep 17 00:00:00 2001 From: Chili Palmer Date: Thu, 2 Apr 2026 18:59:18 +0200 Subject: [PATCH] chore: more validation of plan vs spec --- RUST_EXECUTION_BACKLOG.md | 18 +++++++---- RUST_PLAN_CORE.md | 63 +++++++++++++++++++++++++------------- RUST_PLAN_EXTENSION.md | 2 +- specs/ai.allium | 52 +++++++++++++++++++------------ specs/bds.allium | 6 ++++ specs/cli_sync.allium | 1 + specs/embedding.allium | 1 + specs/generation.allium | 1 + specs/git.allium | 1 + specs/i18n.allium | 1 + specs/mcp.allium | 1 + specs/media.allium | 1 + specs/menu.allium | 1 + specs/metadata.allium | 1 + specs/metadata_diff.allium | 1 + specs/post.allium | 1 + specs/preview.allium | 1 + specs/project.allium | 1 + specs/publishing.allium | 1 + specs/script.allium | 1 + specs/search.allium | 1 + specs/tag.allium | 1 + specs/task.allium | 1 + specs/template.allium | 1 + specs/translation.allium | 1 + 25 files changed, 112 insertions(+), 49 deletions(-) diff --git a/RUST_EXECUTION_BACKLOG.md b/RUST_EXECUTION_BACKLOG.md index 6565fe8..4753943 100644 --- a/RUST_EXECUTION_BACKLOG.md +++ b/RUST_EXECUTION_BACKLOG.md @@ -194,10 +194,15 @@ Rules: ### `bds-core/ai` - one-shot AI client: `reqwest` + `serde_json` against OpenAI-compatible Chat Completions endpoint -- AI-assisted translation operation (translate field content to target language) +- two-endpoint configuration: online endpoint (URL, API key, model) + airplane mode endpoint (URL, model) +- AI translate post operation (title, excerpt, content to target language) +- AI translate media metadata operation (title, alt, caption to target language) - AI image description / alt text generation operation -- AI title suggestion operation -- AI endpoint configuration model (endpoint URL, API key, model name) +- AI post analysis operation (title, excerpt, slug suggestion) +- AI taxonomy analysis operation (tag, category suggestions) +- AI language detection operation +- API key storage via OS keychain (macOS Keychain, Windows DPAPI, Linux libsecret) +- airplane mode gating: block online endpoint, use airplane endpoint or show toast - error handling: surface failures as user-visible feedback, never silent ### `bds-core/engine` @@ -213,16 +218,17 @@ Rules: - preview controls - generation progress display - render errors and diagnostics -- AI operation triggers in post editor (title suggestion), translation editor (translate), and media editor (alt text generation) -- AI endpoint configuration in settings view +- AI operation triggers in post editor (analysis, taxonomy), translation editor (translate), and media editor (alt text, translate) +- AI endpoint configuration in settings view (online + airplane mode endpoints) ### Validation - golden generated-site comparisons - preview route coverage - template compatibility suite -- one-shot AI client tests (mocked endpoint: translation, alt text, title suggestion) +- one-shot AI client tests (mocked endpoint: all 6 operations) - AI endpoint configuration persistence tests +- AI airplane mode gating tests ## Milestone M5: Operate And Ship diff --git a/RUST_PLAN_CORE.md b/RUST_PLAN_CORE.md index 0647f0f..f492f55 100644 --- a/RUST_PLAN_CORE.md +++ b/RUST_PLAN_CORE.md @@ -31,10 +31,11 @@ Core is not a toy MVP. Core must already be a production-capable replacement for - media translation records - post-link tracking records - template file formats and lookup rules -- menu document read format for rendering +- menu document format (OPML at `meta/menu.opml`) — both read and write - generated routes, feeds, sitemaps, and local preview behavior +- metadata JSON file layout: `meta/project.json`, `meta/categories.json`, `meta/category-meta.json`, `meta/publishing.json` - metadata diff and rebuild-from-filesystem behavior -- full-text search behavior (SQLite FTS5 virtual tables for posts and media) +- full-text search behavior (SQLite FTS5 virtual tables for posts and media, with Snowball stemmers for 24 languages via custom tokenizer) - slug generation behavior (verify `deunicode` output matches current `transliteration` output for the project's content corpus) ### May change intentionally @@ -63,7 +64,7 @@ User-authored Python scripts are not compatible and are treated as legacy artifa - **tokio as the async runtime**: preview server (axum), SSH publishing, file watching, and rfd async dialogs all require an async executor. tokio is the standard choice and is used workspace-wide. Synchronous engine code in bds-core does not use tokio directly — it remains callable from both async (bds-ui) and sync (bds-cli) contexts. - **Plain-text markdown editor first**: no WYSIWYG in core. Live preview is required. This is an intentional regression from the current app's Milkdown WYSIWYG editor. A rich editor can be added as an extension bucket after core ships — and the bds-editor widget provides a natural foundation for it. - **Lua for user-authored scripting**: `mlua` with Lua 5.4. Only user-authored macros, transforms, and utility scripts run through Lua. Built-in macros are native Rust — see the macro architecture section below. -- **One-shot AI operations are core scope**: translation, image description / alt text generation, and title suggestion use a simple OpenAI-compatible HTTP client (`reqwest` + `serde_json`). The endpoint is user-configurable (OpenAI, Anthropic-via-proxy, local Ollama, etc.). These are fire-and-forget request/response calls — no streaming, no tool use, no chat history. The AI chat UI, streaming responses, and tool execution remain in Extension Bucket C. +- **One-shot AI operations are core scope**: six operations use a simple OpenAI-compatible HTTP client (`reqwest` + `serde_json`): (1) translate post, (2) translate media metadata, (3) image description / alt text, (4) post analysis (title + excerpt + slug suggestion), (5) taxonomy analysis (tag + category suggestions), (6) language detection. Two configurable endpoints: one for online use, one for airplane/offline mode (local model). These are fire-and-forget request/response calls — no streaming, no tool use, no chat history. The AI chat UI, streaming responses, and tool execution remain in Extension Bucket C. ## Iced Architecture Patterns @@ -159,7 +160,7 @@ bds-rust/ - Lua runtime for user-authored macros, transforms, and utility scripts - generated Lua scripting API docs - FTS5 virtual tables for in-app post and media search -- one-shot AI operations: translation, image description / alt text generation, title suggestion (configurable OpenAI-compatible endpoint via `reqwest`) +- one-shot AI operations: translate post, translate media, image alt text, post analysis, taxonomy analysis, language detection (two configurable OpenAI-compatible endpoints: online + airplane mode, via `reqwest`) ### Deferred to extensions @@ -244,9 +245,10 @@ This matrix is a release artifact, not a temporary note. The current default templates use a small subset of the Liquid specification. Before implementing the Liquid render pipeline, inventory the exact features used. The current templates (12 files: 3 main templates, 5 macro templates, 4 partials in `src/main/engine/templates/`) use only: - **Tags:** `if`/`elsif`/`else`, `for`, `assign`, `render` (partials), whitespace stripping (`{%- -%}`) -- **Filters (built-in):** `default`, `escape`, `url_encode`, `append`, `size` +- **Filters (built-in):** `default`, `escape`, `url_encode`, `append` - **Filters (custom, must be re-implemented in Rust):** `i18n` (translation lookup by key and language), `markdown` (markdown-to-HTML with macro expansion, URL rewriting, and media path canonicalization) -- **Not used:** `unless`, `case/when`, `capture`, `layout`, `include`, `comment`, `raw`, `date`, `truncate`, `split`, `join`, `where`, `group_by`, `map`, `sort`, `reverse`, `cycle`, `tablerow`, `increment`/`decrement`, and most other standard filters +- **Operators and access:** `==`, `>`, `or`, `and`, bare truthiness, `blank` (nil/empty). Property access via dot notation (`object.property`), `.size` on arrays (this is property access, **not** a pipe filter), bracket notation for map lookups (`map[key]`). +- **Not used:** `unless`, `case/when`, `capture`, `layout`, `include`, `comment`, `raw`, `date`, `truncate`, `split`, `join`, `where`, `group_by`, `map`, `sort`, `reverse`, `cycle`, `tablerow`, `increment`/`decrement`, `size` (as a pipe filter), and most other standard filters This means the Rust Liquid implementation only needs roughly 35% of the full specification. Use `liquid-rust` or a minimal custom engine scoped to just the features above. User templates may use additional features, but parity with the current default templates is the release gate. @@ -268,6 +270,14 @@ Macro invocation syntax in content: `[[macro_name param1="value1" param2="value2 The current app uses the `transliteration` npm package for Unicode-to-ASCII conversion in slugs. The plan specifies `deunicode` for Rust. These libraries may produce different output for edge cases (CJK characters, Cyrillic, accented Latin, etc.). Add a slug compatibility test suite to M0 fixtures that runs both libraries against the project's actual content corpus and documents any divergences. +### Two search systems + +The app has two independent search systems — do not conflate them: + +1. **FTS5 (in-app search)**: SQLite FTS5 virtual tables (`posts_fts`, `media_fts`) power the desktop app's search UI. These require custom Snowball tokenizers registered via `rusqlite`'s `fts5_tokenizer` API (using the `rust-stemmers` crate) for 24-language stemmed search. Both indexing and query-time stemming must match the content language. This is Wave 1 scope. + +2. **Pagefind (generated site search)**: a client-side search index bundled with the generated static site. Pagefind indexes the generated HTML files and produces JavaScript/WASM artifacts that power search on the published website. This is Wave 4 scope, added to the generation pipeline via the `pagefind` crate's Rust library API. + ### Client-side search index (Pagefind) If the current TypeScript app generates a Pagefind search index as part of site generation, the Rust app must produce the same artifact. Pagefind publishes a Rust library (`pagefind` crate) with a programmatic API (`pagefind::api::PagefindIndex`). The generation pipeline feeds rendered HTML to `PagefindIndex::add_html_file()` and writes the resulting index files via `PagefindIndex::get_files()`. No external binary, no npm — this is a pure Rust library dependency, fully compatible with the no-JavaScript constraint. @@ -297,6 +307,7 @@ All crate choices for core scope, organized by subsystem. This prevents ad-hoc t | `thiserror` | Typed error definitions in library crates | bds-core, bds-editor | | `anyhow` | Ergonomic error handling in application crates | bds-ui, bds-cli | | `tokio` | Async runtime | Preview server, publish, file watching, async dialogs | +| `rust-stemmers` | Snowball stemming for FTS5 | Custom FTS5 tokenizer for 24-language stemmed search | ### UI Framework (Wave 0 onward) @@ -345,7 +356,7 @@ All crate choices for core scope, organized by subsystem. This prevents ad-hoc t | Crate | Purpose | Notes | |---|---|---| -| `ssh2` | SSH/SCP file upload | For publish-via-SSH targets | +| `ssh2` | SSH/SCP file upload | For publish-via-SSH targets. Authentication via SSH agent (`SSH_AUTH_SOCK`) only — no password auth, no interactive prompts. | | (shell out) | rsync invocation | rsync ships with macOS/Linux; invoke as child process | ### Client-Side Search (Wave 4) @@ -358,7 +369,7 @@ All crate choices for core scope, organized by subsystem. This prevents ad-hoc t | Crate | Purpose | Notes | |---|---|---| -| `reqwest` | HTTP client for AI endpoints | OpenAI-compatible Chat Completions API. Used for translation, alt text, title suggestion. | +| `reqwest` | HTTP client for AI endpoints | OpenAI-compatible Chat Completions API. Two endpoints: online + airplane mode (local). Used for translation, alt text, taxonomy, post analysis, language detection. | ### Scripting (Wave 6) @@ -384,7 +395,7 @@ The hard sequence is: 4. editor widget MVP (ropey + syntect + cosmic-text proof of concept) 5. editors for posts, media, templates, scripts, and settings 6. preview and generation parity -7. one-shot AI operations (translation, alt text, title suggestion) +7. one-shot AI operations (translate post, translate media, image alt text, post analysis, taxonomy analysis, language detection) 8. publish and integrity tooling 9. Lua built-ins plus generated script API docs @@ -425,7 +436,7 @@ Anything outside that path is noise until the previous step is stable. - preview is trustworthy - generation matches golden output - route, feed, and sitemap parity is acceptable -- one-shot AI operations work (translation, image alt text, title suggestion) with a configurable OpenAI-compatible endpoint +- one-shot AI operations work (all 6 operations) with two configurable OpenAI-compatible endpoints (online + airplane mode) ### Milestone M5: Operate And Ship @@ -529,7 +540,7 @@ Not all of these are needed in Wave 0 — this is the full foundation set. Wave- - `PostMediaEngine` - `TagEngine` - `MetaEngine` -- `TaskManager` +- `TaskManager` — max 3 concurrent tasks, FIFO queue, 250ms progress throttle, cancellation support - `MetadataDiffEngine` - `RebuildEngine` or equivalent rebuild services @@ -688,7 +699,7 @@ By Wave 3, bds-editor must support the full feature set documented in the editor - `rayon` for parallel page rendering during generation - `axum` for the preview HTTP server (runs on tokio) - `pagefind` for client-side search index generation (Rust library API, not CLI binary) -- `reqwest` for one-shot AI operations (translation, alt text, title suggestion) against an OpenAI-compatible endpoint +- `reqwest` for one-shot AI operations (all 6 operations: translate post/media, image alt text, post analysis, taxonomy analysis, language detection) against two configurable OpenAI-compatible endpoints (online + airplane mode) ### Rendering pipeline @@ -706,7 +717,7 @@ By Wave 3, bds-editor must support the full feature set documented in the editor ### Preview rules -- preview binds only to localhost +- preview server binds to `127.0.0.1:4123` (localhost only, fixed port) - preview and generated HTML use local assets only - preview must support drafts and language-prefixed routes - rendered language is controlled by project settings, not by UI locale @@ -715,24 +726,30 @@ By Wave 3, bds-editor must support the full feature set documented in the editor Wave 4 introduces the one-shot AI client in `bds-core`. This is a minimal `reqwest`-based HTTP client that sends single request/response calls to an OpenAI-compatible Chat Completions endpoint. No streaming, no tool use, no chat history. -**Operations:** +**Operations (all 6 are core scope):** -- **Translation**: translate a post or media metadata field to a target language. Used from the translation editor and media editor. -- **Image description / alt text**: generate an alt text description for a media item. Used from the media editor. -- **Title suggestion**: suggest a title from post content. Used from the post editor. +- **Translate post**: translate title, excerpt, and content to a target language. Used from the translation editor. +- **Translate media metadata**: translate title, alt, and caption to a target language. Used from the media editor. +- **Image description / alt text**: generate alt text and caption for a media item. Used from the media editor. +- **Post analysis**: suggest title, excerpt, and slug from post content. Used from the post editor. +- **Taxonomy analysis**: suggest tags and categories for a post. Used from the post editor. +- **Language detection**: detect the language of a text fragment. Used internally by other operations. **Configuration:** -- endpoint URL (default: none — AI features are opt-in) -- API key (stored securely, not in project files) -- model name (configurable per operation or globally) +- **Online endpoint**: URL, API key, model name — for cloud AI providers (OpenAI, Anthropic-via-proxy, etc.) +- **Airplane mode endpoint**: URL, model name — for local models (Ollama, LM Studio, etc.) — no API key needed +- When airplane mode is active, only the airplane mode endpoint is used. Cloud endpoint calls are blocked. +- Default: no endpoints configured — AI features are opt-in. +- API keys stored securely via OS keychain (macOS Keychain, Windows DPAPI, Linux libsecret), never in project files. **Constraints:** - AI operations are entirely optional. The app is fully functional without any AI endpoint configured. - When no endpoint is configured, AI-related UI elements are disabled or hidden. +- When airplane mode is active, the online endpoint is disabled. If no airplane mode endpoint is configured, AI is unavailable with a user-visible toast. - Error responses produce user-visible feedback (toast or inline error), never silent failures. -- Request/response payloads use the OpenAI Chat Completions wire format. This works with OpenAI, Anthropic-via-proxy, local Ollama, or any compatible endpoint. +- Request/response payloads use the OpenAI Chat Completions wire format. ### Tests @@ -765,7 +782,9 @@ Wave 4 introduces the one-shot AI client in `bds-core`. This is a minimal `reqwe - upload generated site via SCP or rsync - upload media and thumbnails correctly -- exclude metadata-only files from deploy targets where appropriate +- SSH authentication via SSH agent (`SSH_AUTH_SOCK`) only — no password auth, no interactive prompts +- three upload targets (html, thumbnails, media) run as parallel tasks +- exclude `.meta` sidecar files from media uploads - surface publish progress and failures in the UI - detect and surface external file changes that affect open editors or preview accuracy diff --git a/RUST_PLAN_EXTENSION.md b/RUST_PLAN_EXTENSION.md index 55e0a19..e474e2a 100644 --- a/RUST_PLAN_EXTENSION.md +++ b/RUST_PLAN_EXTENSION.md @@ -11,7 +11,7 @@ Extensions begin only after the core plan is already usable end to end. 1. No extension may break the core compatibility contract. 2. Extensions must reuse core models, engines, and persistence rules rather than invent parallel formats. 3. UI features must still be tied to underlying functionality; no placeholder shells. -4. AI features remain gated by offline mode and must prefer local models or provide explicit user feedback when unavailable. One-shot AI operations (translation, alt text, title suggestion) are part of core but respect the same offline gating. +4. AI features remain gated by offline mode and must prefer local models or provide explicit user feedback when unavailable. One-shot AI operations (6 operations: translate post/media, image alt text, post analysis, taxonomy analysis, language detection) are part of core with two configurable OpenAI-compatible endpoints (online + airplane mode), and respect the same offline gating. 5. Extensions use the same Iced + muda + rfd platform stack as core. No additional UI frameworks. ## Extension Buckets diff --git a/specs/ai.allium b/specs/ai.allium index d2f4dba..182f708 100644 --- a/specs/ai.allium +++ b/specs/ai.allium @@ -1,24 +1,22 @@ -- allium: 1 -- bDS AI Integration +-- Scope: core (one-shot operations), extension Bucket C (chat + streaming) -- Distilled from: src/main/engine/ChatEngine.ts, ai/providers.ts, -- ai/chat.ts, ai/tasks.ts, SecureKeyStore.ts +-- Note: Rust rewrite simplifies providers to two configurable +-- OpenAI-compatible endpoints (online + airplane mode), +-- replacing the TypeScript app's 4 named providers. use "./post.allium" as post use "./media.allium" as media -value AiProvider { - kind: opencode_zen | mistral | ollama | lm_studio - -- OpenCode Zen: routes claude* to Anthropic Messages API, - -- everything else to OpenAI Chat Completions - -- Mistral: native Mistral API - -- Ollama: localhost:11434, local models - -- LM Studio: localhost:1234, local models -} - -value AiModel { - provider: AiProvider - name: String - modalities: Set -- text, vision, etc. +entity AiEndpoint { + kind: online | airplane + url: String + api_key: String? -- encrypted via SecureKeyStore; null for local models + model: String + -- online: cloud provider (OpenAI, Anthropic-via-proxy, etc.) + -- airplane: local model (Ollama, LM Studio, etc.) } entity SecureKeyStore { @@ -30,7 +28,7 @@ entity SecureKeyStore { entity ChatConversation { title: String - model: String -- default: claude-sonnet-4-5 + model: String created_at: Timestamp updated_at: Timestamp @@ -47,6 +45,9 @@ entity ChatMessage { } -- One-shot AI tasks (core scope, no streaming) +-- All use OpenAI Chat Completions wire format. +-- When airplane_mode: use airplane endpoint. When online: use online endpoint. +-- When no endpoint configured for current mode: disable AI, show toast. rule AnalyzeTaxonomy { when: AnalyzeTaxonomyRequested(post) @@ -92,11 +93,11 @@ rule TranslateMedia { ensures: MediaTranslationResult(title, alt, caption) } --- Chat (extension scope, with streaming and tool use) +-- Chat (extension Bucket C scope, with streaming and tool use) rule StartChat { when: StartChatRequested(model) - ensures: ChatConversation.created(model: model ?? "claude-sonnet-4-5") + ensures: ChatConversation.created(model: model) } rule SendChatMessage { @@ -112,15 +113,26 @@ rule SendChatMessage { -- Model catalog rule RefreshModelCatalog { - when: RefreshModelCatalogRequested(provider) + when: RefreshModelCatalogRequested(endpoint) + -- Queries the endpoint's model list API -- 5-minute cache TTL - ensures: ModelCatalogUpdated(provider) + ensures: ModelCatalogUpdated(endpoint) } invariant AirplaneModeGating { -- All AI activities must be gated by airplane (offline) mode - -- When offline: either use local model (Ollama/LM Studio) or - -- inform the user via toast notification + -- When airplane_mode = true: only the airplane endpoint is used + -- When airplane_mode = false: the online endpoint is used + -- If the active endpoint is not configured: AI is unavailable, + -- show toast notification to user +} + +invariant TwoEndpointModel { + -- Two configurable OpenAI-compatible endpoints: + -- online: for cloud providers (requires API key) + -- airplane: for local models (no API key required) + -- Both use the OpenAI Chat Completions wire format. + -- This replaces the TypeScript app's 4 named provider model. } invariant SecureKeyStorage { diff --git a/specs/bds.allium b/specs/bds.allium index d9584c9..d7aaabd 100644 --- a/specs/bds.allium +++ b/specs/bds.allium @@ -54,6 +54,12 @@ use "./metadata_diff.allium" as metadata_diff -- DB/filesystem diff and rebuil -- -- 2. Liquid subset: see template.allium for the exact subset. -- Only 5 tags, 4 standard filters, 2 custom filters, 5 operators. +-- .size is property access on arrays, NOT a pipe filter. -- -- 3. Macro calling convention: [[macroslug param1=value1 ...]] -- Double-bracket syntax, not Liquid tags. Identical to current app. +-- +-- 4. AI provider model: Rust rewrite uses two configurable OpenAI-compatible +-- endpoints (online + airplane mode) instead of the TypeScript app's +-- 4 named providers (OpenCode Zen, Mistral, Ollama, LM Studio). +-- See ai.allium for details. diff --git a/specs/cli_sync.allium b/specs/cli_sync.allium index 544db80..6390a14 100644 --- a/specs/cli_sync.allium +++ b/specs/cli_sync.allium @@ -1,5 +1,6 @@ -- allium: 1 -- bDS CLI / App Notification Sync +-- Scope: extension (Bucket G — MCP + Automation) -- Distilled from: src/main/engine/CliNotifier.ts, NotificationWatcher.ts entity DbNotification { diff --git a/specs/embedding.allium b/specs/embedding.allium index 15b4490..c23d30f 100644 --- a/specs/embedding.allium +++ b/specs/embedding.allium @@ -1,5 +1,6 @@ -- allium: 1 -- bDS Semantic Similarity / Embeddings +-- Scope: extension (Bucket D — Embeddings + Duplicate Detection) -- Distilled from: src/main/engine/EmbeddingEngine.ts use "./post.allium" as post diff --git a/specs/generation.allium b/specs/generation.allium index 0c021b9..2b44af0 100644 --- a/specs/generation.allium +++ b/specs/generation.allium @@ -1,5 +1,6 @@ -- allium: 1 -- bDS Static Site Generation +-- Scope: core (Wave 4) -- Distilled from: src/main/engine/BlogGenerationEngine.ts, -- PageRenderer.ts, GenerationWorkerPool, RoutePageGenerationService diff --git a/specs/git.allium b/specs/git.allium index e248b31..f488f7b 100644 --- a/specs/git.allium +++ b/specs/git.allium @@ -1,5 +1,6 @@ -- allium: 1 -- bDS Git Integration +-- Scope: extension (Bucket A — Git + Validation) -- Distilled from: src/main/engine/GitEngine.ts use "./post.allium" as post diff --git a/specs/i18n.allium b/specs/i18n.allium index a4d1759..8dfbe1d 100644 --- a/specs/i18n.allium +++ b/specs/i18n.allium @@ -1,5 +1,6 @@ -- allium: 1 -- bDS Internationalization +-- Scope: core (Wave 0 onward — split localization is mandatory) -- Distilled from: src/main/shared/i18n.ts, i18n/locales/*.json value SupportedLanguage { diff --git a/specs/mcp.allium b/specs/mcp.allium index ebc88d0..00ccff1 100644 --- a/specs/mcp.allium +++ b/specs/mcp.allium @@ -1,5 +1,6 @@ -- allium: 1 -- bDS MCP Server (Model Context Protocol) +-- Scope: extension (Bucket G — MCP + Automation) -- Distilled from: src/main/engine/MCPServer.ts, ProposalStore, MCPAgentConfigEngine.ts use "./post.allium" as post diff --git a/specs/media.allium b/specs/media.allium index 30bd500..58d60a6 100644 --- a/specs/media.allium +++ b/specs/media.allium @@ -1,5 +1,6 @@ -- allium: 1 -- bDS Media Lifecycle +-- Scope: core (Wave 1) -- Distilled from: src/main/engine/MediaEngine.ts, schema.ts use "./project.allium" as project diff --git a/specs/menu.allium b/specs/menu.allium index e1cd1b8..70c225c 100644 --- a/specs/menu.allium +++ b/specs/menu.allium @@ -1,5 +1,6 @@ -- allium: 1 -- bDS Navigation Menu +-- Scope: core (read for rendering), extension Bucket F (menu editor UI) -- Distilled from: src/main/engine/MenuEngine.ts value MenuItem { diff --git a/specs/metadata.allium b/specs/metadata.allium index 702ff5c..1e875ba 100644 --- a/specs/metadata.allium +++ b/specs/metadata.allium @@ -1,5 +1,6 @@ -- allium: 1 -- bDS Project Metadata, Categories, Publishing Preferences +-- Scope: core (Wave 1) -- Distilled from: src/main/engine/MetaEngine.ts, schema.ts use "./project.allium" as project diff --git a/specs/metadata_diff.allium b/specs/metadata_diff.allium index 961cac3..333065c 100644 --- a/specs/metadata_diff.allium +++ b/specs/metadata_diff.allium @@ -1,5 +1,6 @@ -- allium: 1 -- bDS Metadata Diff and Rebuild +-- Scope: core (Wave 1) -- Distilled from: src/main/engine/MetadataDiffEngine.ts use "./post.allium" as post diff --git a/specs/post.allium b/specs/post.allium index 8918170..95b814c 100644 --- a/specs/post.allium +++ b/specs/post.allium @@ -1,5 +1,6 @@ -- allium: 1 -- bDS Post Lifecycle +-- Scope: core (Wave 1) -- Distilled from: src/main/engine/PostEngine.ts, postFileUtils.ts, schema.ts use "./project.allium" as project diff --git a/specs/preview.allium b/specs/preview.allium index 8ab5cf7..b3e6072 100644 --- a/specs/preview.allium +++ b/specs/preview.allium @@ -1,5 +1,6 @@ -- allium: 1 -- bDS Local Preview Server +-- Scope: core (Wave 4) -- Distilled from: src/main/engine/PreviewServer.ts, PageRenderer.ts use "./template.allium" as template diff --git a/specs/project.allium b/specs/project.allium index ea5cdf0..f03f063 100644 --- a/specs/project.allium +++ b/specs/project.allium @@ -1,5 +1,6 @@ -- allium: 1 -- bDS Project Management +-- Scope: core (Wave 1) -- Distilled from: src/main/engine/ProjectEngine.ts, schema.ts entity Project { diff --git a/specs/publishing.allium b/specs/publishing.allium index caa2f05..ee7cbfe 100644 --- a/specs/publishing.allium +++ b/specs/publishing.allium @@ -1,5 +1,6 @@ -- allium: 1 -- bDS SSH Publishing +-- Scope: core (Wave 5) -- Distilled from: src/main/engine/PublishEngine.ts use "./metadata.allium" as meta diff --git a/specs/script.allium b/specs/script.allium index 7bde1cf..30aea14 100644 --- a/specs/script.allium +++ b/specs/script.allium @@ -1,5 +1,6 @@ -- allium: 1 -- bDS Scripting System +-- Scope: core (Wave 6 — Lua runtime and scripting docs) -- Distilled from: src/main/engine/ScriptEngine.ts, schema.ts -- Note: TypeScript app uses Python/Pyodide. Rust rewrite uses Lua. -- Behavioural contract is identical; only runtime changes. diff --git a/specs/search.allium b/specs/search.allium index ef30ede..35d89d5 100644 --- a/specs/search.allium +++ b/specs/search.allium @@ -1,5 +1,6 @@ -- allium: 1 -- bDS Full-Text Search +-- Scope: core (Wave 1 — FTS5 in-app search with Snowball stemmers) -- Distilled from: src/main/engine/PostEngine.ts (FTS methods), -- MediaEngine.ts (FTS methods), stemmer.ts diff --git a/specs/tag.allium b/specs/tag.allium index f93cb2e..f391bb9 100644 --- a/specs/tag.allium +++ b/specs/tag.allium @@ -1,5 +1,6 @@ -- allium: 1 -- bDS Tag System +-- Scope: core (Wave 1) -- Distilled from: src/main/engine/TagEngine.ts, schema.ts use "./project.allium" as project diff --git a/specs/task.allium b/specs/task.allium index 2b54408..6bfcfa6 100644 --- a/specs/task.allium +++ b/specs/task.allium @@ -1,5 +1,6 @@ -- allium: 1 -- bDS Background Task Manager +-- Scope: core (Wave 1) -- Distilled from: src/main/engine/TaskManager.ts entity Task { diff --git a/specs/template.allium b/specs/template.allium index 82a6413..d2bb620 100644 --- a/specs/template.allium +++ b/specs/template.allium @@ -1,5 +1,6 @@ -- allium: 1 -- bDS Liquid Template System +-- Scope: core (Wave 1 data, Wave 4 rendering) -- Distilled from: src/main/engine/TemplateEngine.ts, PageRenderer.ts, schema.ts, -- bundled starter templates in src/main/engine/templates/ diff --git a/specs/translation.allium b/specs/translation.allium index 11aa605..c4f4095 100644 --- a/specs/translation.allium +++ b/specs/translation.allium @@ -1,5 +1,6 @@ -- allium: 1 -- bDS Translation System +-- Scope: core (Wave 1) -- Distilled from: src/main/engine/PostEngine.ts (translation methods), -- postTranslationFileUtils.ts, MediaEngine.ts