# The botwork place > A collection of programs to use as daily drivers Language: en URL: https://botwork.se/ All pages on this site are available as clean Markdown by adding the header `Accept: text/markdown` to any HTTP request. REST API: https://botwork.se/wp-json/mescio-for-agents/v1/markdown?url={page_url} ## Pages - [Privacy Policy](https://botwork.se/about/privacy-policy/): Who we are We are a service provider based in Europe. And our website is located at: https://botwork.se. Cookies If you leave a comment on our site, you will opt-in to save your name. You will also save your email - [Cart](https://botwork.se/cart/): 🛒 Your cart is empty Read up on our services before you buy - [Checkout](https://botwork.se/checkout/) - [Account management](https://botwork.se/my-account/) - [Return Policy](https://botwork.se/about/return-policy/): General policy Our policy is valid for 30 calendar days from the date of the buy. If you are not satisfied with the service or product, you can ask for a refund. If 30 days have passed since the buy - [Terms of service](https://botwork.se/about/terms-of-service/): Welcome to botwork, here follow our terms! We are a provider of email and cloud services (the "Service"). By using the Service, you agree to these terms and conditions (the "Terms"). If you do not agree to these Terms, please - [The Botwork News](https://botwork.se/news/): The Botwork News is just the place to go for your coffee break or just to learn some new things. We post content 2-3 times a week. In The Spotlight - [Contact](https://botwork.se/about/contact/): When sending email to us, we will keep the email in our registry for about 6 months. If that's not acceptable, please prefix the text "" in the topic (not the message). Alice will just toss it in the trash - [Shop](https://botwork.se/home/shop/): Shop How we fund open source Your subscription does not just pay for servers. It funds development of free, open source software. Git hosting funds development - Every personal subscription helps us maintain and improve the tools we open-source Free - [About Botwork](https://botwork.se/about/): Open source services for European companies We build tools that keep your data in Europe. Git hosting that funds open source. Services that respect your privacy. What we offer Use our services - Git hosting, cloud storage, email. Self-sustaining prices. - [The Botwork Place](https://botwork.se/): Free Code. Paid Bugs. Sustainable Open Source. Git hosting that funds development. Submit PRs for free, report bugs to help keep the lights on. European infrastructure. Your data stays in Europe. Our products Personal Git CI/CD 1€/month Host your code ## Blog Posts - [Package Manager with SQLite](https://botwork.se/2026/04/09/package-manager-with-sqlite/) (2026-04-09): Prove v1.4 ships a package manager. Packages are distributed as .prvpkg files — SQLite databases containing pre-checked AST, type signatures, and comptime-resolved assets. The entire implementation uses only Python's standard library: sqlite3, urllib, hashlib, struct. No git, pip or pesky - [Building GUI Apps in Prove](https://botwork.se/2026/04/06/building-gui-apps-in-prove/) (2026-04-06): Most programming tutorials jump straight to web apps or REST APIs. But there's something deeply satisfying about a small, self-contained desktop tool — a thing you build in an afternoon that just works, no browser required, no server to deploy. - [One Parser to Rule Them All](https://botwork.se/2026/04/03/prove-v1-3-0-one-parser-to-rule-them-all/) (2026-04-03): April 2026 Prove v1.3.0 ships a major architectural milestone: the legacy recursive-descent parser is gone.Tree-sitter is now the sole parser for every stage of the compiler — syntax checking, linting,code generation, and the LSP. Alongside that migration come new verbs, - [Why Intent Matters](https://botwork.se/2026/03/30/compiler-optimization-through-verbs/) (2026-03-30): Compiler Optimization Through Verbs: Why Intent Matters What if the compiler knew exactly what your function was supposed to do — before it even saw the implementation? That's the core idea behind Prove's verb system. And it changes everything for - [Prove v1.1.0](https://botwork.se/2026/03/23/prove-v1-1-0/) (2026-03-23): Prove v1.1.0 is here, and it's a significant leap forward for the Prove programming language. This release introduces structured concurrency as a first-class language feature, adds three powerful stdlib modules for building interactive applications, and ships the proof CLI as - [Python to Prove](https://botwork.se/2026/03/21/python-to-prove/) (2026-03-21): From Python-CLI to Pure Prove: Our FFI Migration Story *How we moved from a Python bootstrap compiler to native Prove binaries without losing access to the Python ecosystem* Presenting proof V1.1.0! This is the start of our road to a - [Prove Getting Started](https://botwork.se/2026/03/20/getting-started-with-prove-intent-first-programming/) (2026-03-20): Getting Started with Prove: Intent-First Programming Prove is an intent-first programming language that compiles to C, then to native binaries. With a focus on clarity and safety, Prove makes you think about *what* your code should do before *how* it - [The Acceleration Loop](https://botwork.se/2026/03/18/the-acceleration-loop/) (2026-03-18): Why Building a Compiler Makes You Better at Building Compilers There's a counterintuitive truth I've discovered while building Prove's self-hosted compiler: starting from zero isn't slower than starting with a head start. It's faster. Not immediately, of course. The first - [AI Can’t Generate Code](https://botwork.se/2026/03/17/ai-cant-generate-code/) (2026-03-17): I ran an experiment last week. I took a real task — a small order validation function — and asked a capable AI assistant to write it in Prove. It failed. Repeatedly. I fixed one error, gave it back the - [Human-Written Code](https://botwork.se/2026/03/16/the-case-for-100-human-written-code/) (2026-03-16): We've been told for years that AI will write our code. That developers should embrace AI assistants, accept AI-generated PRs, and trust that the machine knows better. The narrative is seductive: why spend hours writing something a machine can generate - [Why My Own Language](https://botwork.se/2026/03/04/why-my-own-language/) (2026-03-04): Why I Built My Own Programming Language Most programming languages weren't built for humans. They were built with computers on center stage — every decision optimized for what machines can parse, not what developers can think. We're forced to translate - [Setting up CI and CD](https://botwork.se/2025/06/07/setting-up-ci-and-cd/) (2025-06-07): I have spent a lot of time working on setting up CI and CD. And all around robustness of the setup. Alongside of that I also evaluate some new tools that might end up in the stack. While I'd like - [The rude people in open-source](https://botwork.se/2025/05/22/the-rude-people-in-open-source/) (2025-05-22): Everything of a open source approach is great but one thing! But when it comes to feedback and feature request the rude people in open-source comes to life. From a developer point of view there is a very interesting and - [Tying the OAUTH2 knot](https://botwork.se/2025/05/16/tying-the-oauth2-knot/) (2025-05-16): This is a long, and casual post/rant. I hope it will amuse! While I explain what I mean with "Tying the OAUTH2 knot" Setting up services is fun and games until we get to the fragmented end result. While we - [Bloat free privacy browser](https://botwork.se/2025/05/16/bloat-free-privacy-browser/) (2025-05-16): Tech-nerd alert This browser is like no other you tried! We can promise you a clean/slick look when all of a sudden need to do a browser related task. As a programmer you fight with the mouse! Moving all these - [Big IT steal our children’s data!](https://botwork.se/2025/05/13/it-companies-are-stealing-our-childrens-data/) (2025-05-13): We have to talk about European data sovereignty. Big IT steal our children's data! I have first hand seen that schools in Sweden use big IT-companies services for online meetings, classroom and email services. This is among other services and - [Local AI to Streamline Workflow](https://botwork.se/2025/05/11/local-ai-to-streamline-workflow/) (2025-05-11): In the modern workplace, finding the right information quickly and efficiently can significantly impact productivity and collaboration. Local AI streamline this workflow and offer a practical and effective approach for your organization. Improved Efficiency Integrating AI technologies tailored to your - [Efficient workflow; Retry to perfection!](https://botwork.se/2025/05/08/retry-to-perfection/) (2025-05-08): Spending time on things that have 0 value at the end of the day? Test the method retry to perfection! This is my daily struggle to be honest. I give myself 30 minutes every every day to reflect on things - [DNS settings to pay attention to when hosting email](https://botwork.se/2025/05/06/dns-settings-to-pay-attention-to-when-hosting-email/) (2025-05-06): Tech-nerd alert ⚠️ issued for this post! Back in the days, if someone asked me to set up an email service. My response was: "Thanks, but no thank you." I preferred not to take on the task. I'm good. And - [Casual friday and more: when you always work ;)](https://botwork.se/2025/05/03/casual-weekend/) (2025-05-03): The post reflects on work-life balance, emphasizing the importance of reflection during weekends. It discusses the origins and challenges of botwork, the desire for monetization through WordPress, and the shift of responsibilities to Alice. Finally, it highlights the significance of fun and play in the workplace to boost morale and creativity. - [Safeguarding your data from AI](https://botwork.se/2025/04/30/safeguarding-your-data-from-ai/) (2025-04-30): In today's digital age, AI is increasingly shaping our lives. It is crucial to understand the importance of safeguarding private data from AI. As we embrace this new tech and its countless benefits, we must protect our personal information. we - [Alice is getting ready for work!](https://botwork.se/2025/04/28/alice-is-getting-ready-for-work/) (2025-04-28): Your personal assistant, Alice, learns from your data within the offline cloud environment of botwork. Interact like a human, customize tasks, and filter workflow while ensuring privacy and security. - [Upcoming features May 2025](https://botwork.se/2025/04/25/upcoming-features-may/) (2025-04-25): Upcoming features Maj 2025; We are just starting up and there are a lot of things we need to build/finish! That said, we did not want you to miss out on what we have in the works. Many interesting services - [Cloud Storage in Europe](https://botwork.se/2025/04/24/cloud-storage-in-europe/) (2025-04-24): Briefly Moving to an open-source cloud storage in Europe ensures data sovereignty, transparency, control over data, cost savings, and supports European tech communities. Open-source solutions prioritize privacy, GDPR compliance, and foster collaboration while allowing flexibility and knowledge sharing. Make the switch today and take charge of your digital life! ## Products ### Tools - [Botwork Browser with vim-motions](https://botwork.se/product/botwork-browser-with-vim-motions/) — 1,00 € / Month and 14 Days free trial [in stock]: Tech-nerd alert ⚠️ This is NOT a browser for everyone, but if you are brave you can give it a try! Read all of the description before ordering, and remember that this is a work in progress. You will get ### Cloud - [Enterprise Cloud Europe](https://botwork.se/product/enterprise-cloud-europe/) — 100,00 € / Month and 14 Days free trial [in stock]: Enterprise cloud service based in Europe with all the apps you need for a full move. - [Personal Cloud Europe 100GB](https://botwork.se/product/personal-cloud-europe-100gb/) — 10,00 € Original price was: 10,00 €.5,00 €Current price is: 5,00 €. / Month and 14 Days free trial [in stock]: Personal cloud services based in Europe with all the apps you need for a full move. ### Code - [Personal Git CI/CD](https://botwork.se/product/personal-git-ci-cd/) — 3,00 € Original price was: 3,00 €.1,00 €Current price is: 1,00 €. / Month [in stock]: With Personal Git CI/CD based on European servers you can be sure that your code stays close to you and wont be used in any general AI training. Speed I am a frequent user of many (almost all) other code-versioning - [Enterprise Git CI/CD](https://botwork.se/product/european-git-hosting/) — 30,00 € / Month and 14 Days free trial [in stock]: With Corporate Git CI/CD based on European servers you can be sure that your code stays close to you and wont be used in any general AI training. Carl the developer Opt in for your own AI-developer (Carl) he is ### Email - [Enterprise email](https://botwork.se/product/enterprise-email/) — 20,00 € / Month and 14 Days free trial [in stock]: With our Enterprise email you do not have to install any proprietary apps. We will help you setup everything, use your company domain while having a secure and privacy focused setup. With this email setup you get 5 email accounts - [Personal email](https://botwork.se/product/personal-email/) — 2,00 € Original price was: 2,00 €.1,00 €Current price is: 1,00 €. / Month and 14 Days free trial [in stock]: A personal email is a great option if you do not want to install any proprietary apps. "But what about my gmail" you might ask?! Don't worry, we will help you setup and your gmail is easy to deliver directly --- # Full Content --- title: "Package Manager with SQLite" url: "https://botwork.se/2026/04/09/package-manager-with-sqlite/" lang: "en-GB" type: "post" description: "Prove v1.4 ships a package manager. Packages are distributed as .prvpkg files — SQLite databases containing pre-checked AST, type signatures, and comptime-resolved assets. The entire implementation uses only Python's standard library: sqlite3, urllib, hashlib, struct. No git, pip or pesky" last_modified: "2026-04-09T11:23:38+00:00" categories: [Efficiency, Package Manager, prove, Security, Technical] --- # Package Manager with SQLite Prove v1.4 ships a package manager. Packages are distributed as `.prvpkg` files — SQLite databases containing pre-checked AST, type signatures, and comptime-resolved assets. The entire implementation uses only Python’s standard library: `sqlite3`, `urllib`, `hashlib`, `struct`. No git, pip or pesky node_modules. This post covers _why_ we made the choices we did and _how_ the pieces fit together. ## The Problem Prove is a compiled language with [strong contracts](https://prove.botwork.se/prove/contracts/), a [verb system](https://prove.botwork.se/prove/verbs/), and comptime evaluation. Sharing code between projects meant copying `.prv` files around. That works for a while — until you want versioning, dependency resolution, or the ability to share a library that uses comptime-loaded CSV data. The constraint was clear: whatever we built needed to feel native to Prove’s existing [toolchain](https://prove.botwork.se/prove/cli/). No shelling out to git. No requiring users to install extra tools. Just `proof package add math-helpers` and build. ## Why SQLite as the Package Format Most package managers use tarballs. We chose [SQLite](https://sqlite.org/) databases for three reasons: **1. Queryable without full deserialization.** The checker needs type signatures to validate imports from packages. With SQLite, we read the `exports` table — a few rows of function names, parameter types, and return types — without ever touching the AST blobs. This is the “fast path”: the checker sees a package import the same way it sees a stdlib import, backed by a SQL query instead of parsing source. **2. Migratable across compiler versions.** Prove’s AST changes between releases. With a tarball, you’d need to re-serialize the entire package. With SQLite, we ship SQL migration files that `ALTER TABLE` or `UPDATE` the schema in place. When you upgrade your compiler, your cached packages upgrade themselves. **3. Inspectable.** Anyone can open a `.prvpkg` with `sqlite3` and poke around. What modules does this package export? What version of Prove compiled it? It’s all right there in the `meta` table. The schema: ``` CREATE TABLE meta (key TEXT PRIMARY KEY, value TEXT); CREATE TABLE exports ( module TEXT, kind TEXT, name TEXT, verb TEXT, params TEXT, return_type TEXT, can_fail INTEGER, doc TEXT ); CREATE TABLE strings (id INTEGER PRIMARY KEY, value TEXT); CREATE TABLE module_ast (module TEXT PRIMARY KEY, data BLOB); CREATE TABLE dependencies (name TEXT, version_constraint TEXT); CREATE TABLE assets (key TEXT PRIMARY KEY, data BLOB); ``` Six tables. That’s the entire package format. ## String-Interned Binary AST Prove’s AST has ~50 concrete node types ([functions](https://prove.botwork.se/prove/functions/), [types](https://prove.botwork.se/prove/types/), match arms, lookup entries, [contracts](https://prove.botwork.se/prove/contracts/), etc.). Serializing them as JSON would work but would be massive — every field name repeated on every node. Instead, we built a tagged-tuple binary format with [string interning](https://en.wikipedia.org/wiki/String_interning). Each AST node is encoded as: - A `uint8` tag identifying the node type - Fields written inline via `struct.pack` - Strings stored once in a `StringIntern` table, referenced by `uint32` ID Lists are a `uint32` count followed by elements. `None` is `0xFF`. Bools are `uint8`. The result is roughly 50% smaller than keyed JSON before any compression, and it serializes/deserializes in a single recursive walk — the same pattern we already use for AST dumping in the CLI. The string table is stored in SQLite’s `strings` table, and the binary blob goes into `module_ast`. The key insight: strings dominate Prove AST size (identifiers, type names, doc comments, contract texts), so interning them once gives us most of the compression benefit with zero algorithmic complexity. ## Two-Speed Loading ![Package manager paths](https://botwork.se/wp-content/uploads/2026/04/an_abstract_composition_of_translucent_geometric_layers_stacked_vertically_with_slight_offset___like_glass___slides_on_a_light_table__the_bottom_layer_is_dense_and_textured__representin_2446448067.png) The package loader has two modes, and this split is the architectural decision that makes the whole system feel fast: **Fast path (checker):** Read the `exports` table. Build `FunctionSignature` and `Type` objects from the tabular data. No binary deserialization at all. This is what happens on every `proof check` and every keystroke in the LSP server. It’s a few SQL queries per package. **Slow path (emitter):** Deserialize the full AST from `module_ast` blobs, reconstruct the string table, run the checker on the reconstituted AST to build a symbol table, then hand it to the C emitter. This only happens during `proof build`, and only for packages the project actually uses. ``` # Fast path — checker just needs signatures info = read_package(pkg_path) # reads meta + exports tables for exp in info.exports: # Already has: name, verb, params, return_type, can_fail # Slow path — emitter needs full AST module = load_package_module(pkg_path, "MathHelpers") # deserializes binary AST ``` This means `prove check` on a project with 10 package dependencies does essentially zero extra work — it’s reading pre-computed signatures from SQLite. ## Flat Dependency Resolution For v1, we chose flat resolution: each dependency name resolves to exactly one version across the entire tree. No diamond dependencies. If package A needs `json-utils 0.3.0` and package B needs `json-utils 0.4.0`, that’s a conflict and the resolver tells you. This is intentionally simple. Prove packages can’t contain native code (no `foreign` blocks allowed), so there’s no ABI compatibility concern that would push us toward allowing multiple versions. And for a language where the [verb system](https://prove.botwork.se/prove/verbs/) makes function roles explicit (`creates`, `transforms`, `inputs`), having two versions of the same function with the same verb in scope would be confusing, not helpful. The resolver supports version constraints: exact (`0.3.0`), minimum (`>=0.2.0`), range (`>=0.1.0, --- --- title: "Building GUI Apps in Prove" url: "https://botwork.se/2026/04/06/building-gui-apps-in-prove/" lang: "en-GB" type: "post" description: "Most programming tutorials jump straight to web apps or REST APIs. But there's something deeply satisfying about a small, self-contained desktop tool — a thing you build in an afternoon that just works, no browser required, no server to deploy." last_modified: "2026-04-06T08:52:51+00:00" categories: [Efficiency, prove, Technical] --- # Building GUI Apps in Prove Most programming tutorials jump straight to web apps or REST APIs. But there’s something deeply satisfying about a small, self-contained desktop tool — a thing you build in an afternoon that just _works_, no browser required, no server to deploy. Prove’s `Graphic` module makes this easy. This post walks through building GUI apps in Prove, from a minimal counter to a functional todo list, and makes the case for why small desktop tools deserve a comeback. ## The Graphic module Prove ships two UI backends: `Terminal` for text-based interfaces and `Graphic` for windowed GUI apps. Both share the same event-driven architecture — you write a `renders` verb that receives events and returns the next event to process. The compiler picks the right backend based on which event type you extend. Under the hood, `Graphic` uses SDL2 and Nuklear (an immediate-mode UI library). SDL2 is the only external dependency — install it with `brew install sdl2` on macOS or `apt install libsdl2-dev` on Linux, and you’re ready to go. The widget set is intentionally small: `window`, `button`, `label`, `text_input`, `checkbox`, `slider`, `progress`, and `quit`. No layout managers, no CSS, no build step. You call widgets in order and they stack vertically. It’s the GUI equivalent of `printf` debugging — simple, direct, effective. ## A counter in 30 lines Let’s start with the smallest possible GUI app: a button that increments a number. ```prove module Counter narrative: """ GUI counter with increment button. renders app """ Graphic types GraphicAppEvent outputs window button label Types creates string type CounterState is count Integer type CounterApp is GraphicAppEvent renders app(registered_attached_verbs List- ) event_type CounterApp state_init CounterState(0) from Draw(state) => window("Counter", 400, 300) label(f"Count: {string(state.count)}") match button("Increment") true => state.count = state.count + 1 Draw(state) false => Draw(state) Tick(state) => Draw(state) Exit(state) => Unit main() from app([])& ``` The entire app is one `renders` verb. The `state_init` clause sets the starting state. On each `Draw`, we create a window, show a label with the current count, and render a button. When the button returns `true` (it was clicked), we increment and redraw. That’s it. A few things to notice: **No widget tree to manage.** Widgets are function calls, not objects. Call them in order, top to bottom. - **State is explicit.** `CounterState` is a plain record. The `renders` verb owns it. No hidden mutable globals. - **The event loop is a pattern match.** Every event gets handled. The compiler ensures you don’t forget one. Build and run: ``` prove build ./build/counter ``` You get a 400×300 window with a label and a button. Click the button, the number goes up. Close the window, the process exits cleanly. ## Adding widgets: sliders and progress bars The widget demo shows more of the palette: ```prove module Widgets narrative: """ GUI widget demo: slider, progress, quit. renders app """ Graphic types GraphicAppEvent outputs window slider progress quit label Types creates float string type WidgetState is volume Float type WidgetApp is GraphicAppEvent renders app(registered_attached_verbs List- ) event_type WidgetApp state_init WidgetState(float(5)) from Draw(state) => window("Widgets", 400, 300) label(f"Vol: {string(state.volume)}") vol as Float = slider("Vol", float(0), float(100), state.volume) state.volume = vol progress(50, 100) Draw(state) Tick(state) => Draw(state) Exit(state) => quit() ``` The `slider` call returns the current value each frame — you capture it and feed it back next frame. This is the immediate-mode pattern: no bindings, no observers, no two-way data flow. Just pass the value in, get the (possibly changed) value out. `progress` shows a non-interactive progress bar. `quit()` programmatically closes the window when the user hits the close button. ## A real app: the todo list Here’s where Prove’s verb system shines. A todo list needs text input, dynamic lists, custom events, and keyboard shortcuts. Let’s build one: ```prove module TodoApp narrative: """ GUI todo list with add, toggle, and delete. renders a todo app GUI interface listens for key events outputs check items and a button to add new """ Graphic types GraphicAppEvent outputs window button checkbox text_input UI types Key Sequence derives set remove creates length type TodoItem is text String done Boolean idx Integer type TodoState is items List type TodoApp is GraphicAppEvent | AddItem(text String) | RemoveItem(index Integer) ``` First, the setup. We import Graphic widgets, the `Key` type for keyboard handling, and `Sequence` operations for list manipulation. Our state is a list of `TodoItem` records. The event type extends `GraphicAppEvent` with two app-specific variants: `AddItem` and `RemoveItem`. ```prove outputs check(item TodoItem) TodoApp from checkbox(item.idx, item.text, item.done) match button(f"{item.text}") true => RemoveItem(item.idx) false => Tick(Unit) ``` The `check` function is an `outputs` verb — it produces GUI output and returns an event. Each todo item gets a checkbox and a delete button. Clicking the button emits `RemoveItem`. ```prove renders interface(registered_attached_verbs List) event_type TodoApp state_init TodoState([]) from Draw(state) => window("Todo List", 400, 500) text as String = match text_input("Todo", "") Some(text) => text _ => "New item" match button("Add") true => AddItem(text) false => each(state.items, |item| check(item)) Draw(state) AddItem(text) => items as List = state.items state.items = set(items, length(state.items), TodoItem(text, false, length(items))) Draw(state) RemoveItem(index) => state.items = remove(state.items, index) Draw(state) Tick(state) => Draw(state) Exit(state) => Unit ``` The render loop handles three things: drawing the UI, adding items, and removing items. The `text_input` widget returns `Some(text)` with the current input value. The `each` builtin iterates over items, calling `check` for each one — which renders the checkbox and delete button. ```prove listens on_key() TodoApp event_type KeyDown state_type TodoState from Key:Escape => Exit(state) Key:Enter => AddItem("new item") _ => Tick(state) main() from interface([on_key])& ``` The `listens` verb translates raw keyboard events into app events. Escape quits, Enter adds an item. The `main` function wires everything together — the render loop receives the list of listeners. This is the Prove pattern: **verbs compose.** The renderer owns the loop. Listeners translate events. Output functions encapsulate widget groups. Each piece declares what it does and the compiler enforces the boundaries. ## What are small GUI apps good for? ![Slop-generated widgets as small GUI apps](https://botwork.se/wp-content/uploads/2026/04/a_clean__minimal_illustration_showing_three_small_gui_windows_arranged_in_a_slight_cascade___a_counter_with_an____increment__button__a_slider_labeled__vol___and_a_todo_list_with_checkbo_1809047914.png) We live in a world of Electron apps and cloud dashboards. Why build a 400×300 SDL window? **Internal tools.** Every team has spreadsheets and scripts that should be small apps. A log viewer that filters by severity. A config editor that validates before saving. A test runner with a progress bar. These don’t need a web framework — they need a window, a few buttons, and an afternoon. **Data entry.** When you need a human to classify, label, or review data, a small GUI app with checkboxes and text fields is faster than a web form. No auth, no deployment, no latency. Just compile and hand someone the binary. **Prototyping.** Before you build the real UI, build a tiny one. A slider that controls a parameter, a button that triggers a pipeline, a label that shows the result. Prove compiles to native C — these tools start instantly and use minimal resources. **Learning.** GUI programming teaches state management, event handling, and the rendering loop — core concepts that transfer everywhere. Prove’s explicit state and pattern-matched events make these concepts visible instead of hiding them behind framework magic. **Personal tools.** A Pomodoro timer. A color picker. A quick calculator with domain-specific buttons. The kind of thing you build for yourself because the existing options have too many features or too few. ## The immediate-mode advantage Prove’s Graphic module uses immediate-mode rendering: you describe the UI every frame, and the library figures out what changed. There’s no widget tree to build, no state to synchronize, no lifecycle hooks. This maps naturally to Prove’s functional style. Your render function is a pure transformation from state to UI. The `renders` verb receives an event, updates state, calls widgets, and returns the next event. The runtime handles the frame loop, vsync, and input polling. For small apps, this is ideal. You don’t need the overhead of a retained-mode framework when your UI fits in 50 lines. And because Prove compiles to C with SDL2, your app is a single native binary — no runtime, no garbage collector, no JVM startup time. ## Getting started Install SDL2: ``` # macOS brew install sdl2 # Linux apt install libsdl2-dev ``` - Create a new Prove project: ``` prove new my_app ``` - Import the Graphic module and start building: ```prove Graphic types GraphicAppEvent outputs window button label ``` - Build and run: ``` prove build && ./dist/my_app ``` The examples shown in this post are available in the `examples/` directory of the Prove repository: `gui_counter`, `gui_widgets_demo`, and `gui_todo`. Small apps deserve good tools. Prove gives you native compilation, explicit state management, and a widget set that fits in your head. Go build something small and useful. Join [#prove on Libera.Chat](https://web.libera.chat/) (just do a [/knock](https://gist.github.com/xero/2d6e4b061b4ecbeb9f99#knock) and you will be let in ASAP) --- --- title: "One Parser to Rule Them All" url: "https://botwork.se/2026/04/03/prove-v1-3-0-one-parser-to-rule-them-all/" lang: "en-GB" type: "post" description: "April 2026 Prove v1.3.0 ships a major architectural milestone: the legacy recursive-descent parser is gone.Tree-sitter is now the sole parser for every stage of the compiler — syntax checking, linting,code generation, and the LSP. Alongside that migration come new verbs," last_modified: "2026-04-06T08:03:34+00:00" categories: [Compiler, Efficiency, prove, Technical] --- # One Parser to Rule Them All **April 2026** [Prove](https://prove.botwork.se) v1.3.0 ships a major architectural milestone: the legacy recursive-descent parser is gone. [Tree-sitter](https://tree-sitter.github.io/tree-sitter/) is now the sole parser for every stage of the compiler — syntax checking, linting, code generation, and the LSP. Alongside that migration come new [verbs](https://prove.botwork.se/verbs/), better [diagnostics](https://prove.botwork.se/diagnostics/), and the foundation for lint-driven code quality. ## Tree-sitter as the only parser Since [v1.2.0](https://prove.botwork.se/releases/#v120-march-2026) the [tree-sitter-prove](https://code.botwork.se/Botwork/tree-sitter-prove) grammar has been the source of truth for Prove syntax, but the old hand-written parser still ran in parallel as a fallback. That dual-parser setup is over. The recursive-descent parser has been removed entirely. Tree-sitter now drives: - **Syntax checking** — parse errors come directly from the tree-sitter CST, with precise span information and AST error origin tracking. - **Lint checking** — a new lint pass runs in the same `check` pipeline, so [`proof check`](https://prove.botwork.se/cli/) now catches both syntax and style issues in a single invocation. - **Code generation** — the [C emitter](https://prove.botwork.se/compiler/#c-code-generation) reads from the tree-sitter AST, removing an entire class of “parser A sees it differently from parser B” bugs. This is a big simplification. One grammar, one parser, one source of truth. ## `reads` becomes `derives` The `reads` verb never quite said what it meant. A function that `reads` a Text to produce an Integer isn’t really _reading_ — it’s _deriving_ a new value from existing data. In v1.3.0 the verb is renamed to `derives` across the language, [standard library](https://prove.botwork.se/stdlib/), and documentation. The [semantic contract](https://prove.botwork.se/verbs/) is unchanged: same-type or narrowing transformation, no allocation, no failure. The name just fits better. ## New verb: `dispatches` v1.3.0 introduces `dispatches` for functions that route to different implementations based on their input. Where [`derives` transforms and `creates` constructs](https://prove.botwork.se/verbs/), `dispatches` selects. Verb names are also now mangled in the generated C output, producing cleaner symbol names in debuggers and profilers. ## Native binary catches errors before Python The [`proof`](https://prove.botwork.se/cli/) CLI is the native compiler tool. Until now it delegated all checking to the Python compiler via FFI. In v1.3.0 the native binary runs its own [tree-sitter](https://tree-sitter.github.io/tree-sitter/)-based check pass _before_ invoking Python — catching errors instantly. The native check currently catches three [diagnostic](https://prove.botwork.se/diagnostics/) classes: - **[E100](https://prove.botwork.se/diagnostics/) — Syntax errors** — tree-sitter `ERROR` nodes are matched and narrowed by parent context (root, module, lookup) to produce targeted messages. - **[E210](https://prove.botwork.se/diagnostics/#e210-expected-token) — Missing type or module** — detects undeclared modules and types at the declaration level before the full type checker runs. - **[E379](https://prove.botwork.se/diagnostics/?h=e379#e379-lookup-column-count-mismatch) — Malformed lookup rows** — each row in a [`Lookup`](https://prove.botwork.se/types/#lookup) table is statically validated against the type declaration’s column types. If the native pass finds errors, it reports them immediately and never starts Python. If it passes, the full [compiler pipeline](https://prove.botwork.se/compiler/#pipeline) runs as before. This is the first step toward a fully native `proof check` and `proof build` — more diagnostics will move into the native binary in future releases. ### Linting infrastructure The compiler now has a dedicated lint pass integrated into the check pipeline. This is the scaffolding for future code-quality rules — currently focused on structural checks, with more rules planned for upcoming releases. The infrastructure to code analysis is in place and that means we can now start moving the python linter into the native `proof` binary and the first steps towards the bootstrap is on the way! ![Search for the structure](https://botwork.se/wp-content/uploads/2026/04/a_single_lighthouse_beam_from_the_top_of_the_lighthouse_cutting_through_fog__illuminating_scattered_code_fragments_that_align_into_a_clean_tree____structure__dark_blue_and_gold_palette__1619743420.png) ## Implemented diagnostics Beyond the three native-pass errors above, the Python compiler also gained diagnostic improvements: - **[`Option`](https://prove.botwork.se/types/#option-and-result) match arms** — match expressions mixing Unit and value returns now correctly produce `Option` instead of a confusing type error. - **IO requires guards** — `inputs`/`outputs`/`dispatches` functions with [`requires`](https://prove.botwork.se/contracts/) contracts now emit runtime guard checks, catching contract violations at the boundary. ## Upgrading ``` curl -sSf https://code.botwork.se/Botwork/prove/raw/branch/main/install.sh | sh ``` Or if you already have Prove installed: ``` pip install --upgrade prove-lang ``` The `reads` → `derives` rename is a breaking change for user code. Update your [verb declarations](https://prove.botwork.se/verbs/) — the compiler will tell you exactly which lines need attention. Full changelog on the [releases page](https://code.botwork.se/Botwork/prove/releases). Browse the [source code](https://code.botwork.se/Botwork/prove), read the [documentation](https://prove.botwork.se), or follow the [tutorial](https://prove.botwork.se/tutorial/) to get started. You can also join the chat [#prove](https://web.libera.chat/) (just do a [/knock](https://gist.github.com/xero/2d6e4b061b4ecbeb9f99#knock) and you will be let in ASAP) --- --- title: "Why Intent Matters" url: "https://botwork.se/2026/03/30/compiler-optimization-through-verbs/" lang: "en-GB" type: "post" description: "Compiler Optimization Through Verbs: Why Intent Matters What if the compiler knew exactly what your function was supposed to do — before it even saw the implementation? That's the core idea behind Prove's verb system. And it changes everything for" last_modified: "2026-03-30T05:11:04+00:00" categories: [Compiler, Efficiency, prove, Technical] --- # Why Intent Matters # Compiler Optimization Through Verbs: Why Intent Matters What if the compiler knew exactly what your function was supposed to do — before it even saw the implementation? That’s the core idea behind [Prove’s verb system](https://prove.botwork.se/verbs/). And it changes everything for optimization. ## The Problem with Traditional Compilers Most compilers work from the inside out. They analyze your code, apply optimizations, and hope to infer what each function is supposed to accomplish. But they can’t be certain. A function might mutate global state, read files, throw exceptions, or launch threads — the compiler can’t know without running it. This is the [side effect problem](https://en.wikipedia.org/wiki/Side_effect_(computer_science)) — and it’s one of the oldest challenges in compiler design. This uncertainty forces compilers to be conservative. They can’t eliminate dead code, specialize implementations, or inline aggressively because they can’t prove those transformations are safe. LLVM’s [alias analysis](https://llvm.org/docs/AliasAnalysis.html) and GCC’s [`-fipa-pure-const`](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html) pass spend significant effort trying to _infer_ function purity after the fact — with limited success across module boundaries. ![Structured compiler](https://botwork.se/wp-content/uploads/2026/03/abstract_geometric_composition__complex_scattered_shapes_on_left__clean_crystalline_geometric_forms_on_right__minimalist__clean_lines__monochrome_with_single_accent_color__technical_dia_2144721401.png) ## Verbs as Intent Declarations In [Prove](https://prove.botwork.se/), every function begins with a verb that declares its purpose: ```prove transforms parse_email(email String) Email! derives user_count() Integer outputs log_message(String) inputs fetch_user(id Integer) User! ``` These aren’t comments or documentation. They’re **compiler-enforced [contracts](https://prove.botwork.se/contracts/)**. The compiler verifies that your implementation matches what the verb promises. A `transforms` function cannot do IO. A `derives` function cannot allocate new values. The compiler _knows_. ## What the Compiler Knows When it sees a [`transforms`](https://prove.botwork.se/verbs/#pure-verbs) verb, the compiler knows: - **No side effects** — the function is pure - **No IO** — no file access, network calls, or console output - **Deterministic** — same inputs always produce same outputs - **Optionally failable** — may be declared with `!` to return an error, but doesn’t have to This is a _lot_ of information. And it enables optimizations that traditional compilers can only dream about. ## Exact Outlines, Minimal Runtime When you define a function’s boundaries through its verb, the compiler can generate an exact outline. Consider this: ```prove transforms calculate_total(items List) Decimal from reduce(items, 0, |acc, item| acc + item.cents / 100) ``` The compiler knows this function: - Will never allocate file handles - Will never spawn threads - Will never perform IO - Has no observable side effects So it can compile this down to bare metal. No safety nets for “what if this does IO” — because the verb guarantees it won’t. The runtime footprint shrinks to exactly what’s needed. ## Concrete Optimization Examples ### 1. Zero-Cost Error Handling Traditional languages carry error-handling overhead everywhere — even for functions that never fail. C++ compilers must generate [exception handling tables](https://itanium-cxx-abi.github.io/cxx-abi/exceptions.pdf) for any function that _might_ throw, and even “[zero-cost exceptions](https://mortoray.com/the-true-cost-of-zero-cost-exceptions/)” add binary size overhead. But `transforms` is the only [pure verb](https://prove.botwork.se/verbs/#pure-verbs) that _can_ fail, and only when explicitly marked: transforms double(n Integer) Integer from n * 2 This _cannot_ fail — there’s no `!` in its signature. The compiler can omit all error-handling code paths. No Option wrapping, no Result types, no null checks — just the math. ### 2. Aggressive Inlining Pure functions (those using `transforms`, `validates`, `derives`, `creates`, `matches`) are safe to inline. Traditional compilers use [heuristic-based inlining](https://gcc.gnu.org/onlinedocs/gcc/Inline.html) that must conservatively account for possible side effects — LLVM’s inliner [weighs call-site cost against potential side effects](https://llvm.org/docs/Passes.html#inline-function-integration-inlining) before committing. The [compiler](https://prove.botwork.se/compiler/) targets small pure functions — single-expression bodies for most pure verbs, up to three statements for non-allocating verbs like `derives` and `validates`. It can: - Inline at call sites - Constant-propagate through the body - Evaluate pure calls at compile time - Eliminate the function entirely if its result is unused ```prove transforms square(n Integer) Integer from n * n transforms area(r Integer) Integer from square(r) * 314159 ``` The compiler can collapse this to `r * r * 314159` — no function calls at all. ### 3. Iterator Fusion Since `transforms` functions are pure, the compiler can fuse chained iterator operations — combining multiple passes over data into a single pass. This is similar to [stream fusion](https://wiki.haskell.org/GHC/Stream_fusion) in Haskell's GHC, but where GHC must _prove_ purity through its type system, Prove gets it directly from the verb declaration: ```prove transforms calculate(prices List) Decimal from reduce(map(prices, |p| p.discount), 0, |acc, d| acc + d) ``` The compiler knows this is safe to fuse because there’s no shared mutable state. No intermediate allocations — just a single traversal. ### 4. Escape Analysis and Copy Elision When the compiler knows a function creates a new value ([`creates`](https://prove.botwork.se/verbs/#pure-verbs)) versus derives from existing data ([`derives`](https://prove.botwork.se/verbs/#pure-verbs)), it can: - Elide unnecessary copies when values don’t escape — similar to C++’s [copy elision](https://en.cppreference.com/w/cpp/language/copy_elision.html), but informed by verb semantics - Use region allocation for non-escaping values — related to the [escape analysis](https://en.wikipedia.org/wiki/Escape_analysis) used in Go and Java’s HotSpot JVM - Eliminate intermediate allocations in chains ``` ``` creates build_report(users List) Report from Report(name: "Summary", count: length(users), items: map(users, |u| u.name)) The compiler’s escape analysis tracks whether the Report leaves the calling scope, enabling allocation optimizations. ## IO Verbs: Controlled Boundaries [IO verbs](https://prove.botwork.se/verbs/) (`inputs`, `outputs`, `streams`, `dispatches`) define clear boundaries between pure and impure code. The compiler knows exactly which functions can perform IO and which cannot: inputs fetch_users() List! from query(db, "SELECT * FROM users")! Because verbs classify entire functions, the compiler can freely optimize any pure function in the call graph without worrying about hidden IO. The boundary is explicit and enforced. ## Async Verbs: Structured Concurrency With [async verbs](https://prove.botwork.se/async/), the compiler understands concurrency boundaries: - `detached` — fire and forget, cannot declare a return type - `attached` — callback handler, must declare a return type - `listens` — event listener within an event loop - `renders` — coordinates the event loop, manages state and listeners This lets the compiler generate minimal async infrastructure. Compare with Rust’s `async fn`, which always generates a [state machine](https://rust-lang.github.io/async-book/01_getting_started/04_async_await_primer.html) regardless of how the coroutine is used — Prove only emits what the verb requires. ## The Bottom Line Traditional compilers work with uncertainty. They analyze code and make educated guesses about what functions do. Sometimes they’re right. Often they’re conservative — a problem well-documented in compiler literature as the [phase-ordering problem](https://en.wikipedia.org/wiki/Phase-ordering_problem). Prove’s verb system removes the guesswork. When you declare intent upfront, the compiler doesn’t have to infer boundaries — it _knows_ them. And that knowledge translates directly to: - **Smaller binaries** — no code for “what if” - **Faster execution** — no safety overhead for guaranteed-safe operations - **Better inlining** — pure functions are safe to inline - **Compile-time evaluation** — pure calls can be evaluated before runtime The code you write is the code you get — but the compiler makes it lean. We are still working on the optimization and more will come in the future, but we are sure that this approach will be super-charged in the end! _Ready to try it? Check the [tutorial](https://prove.botwork.se/tutorial/) to get started, see [performance benchmarks](https://prove.botwork.se/performance/) against C, Rust, and Zig, or read the full [verb reference](https://prove.botwork.se/verbs/) and [compiler documentation](https://prove.botwork.se/compiler/). More posts on [the blog](https://botwork.se)._ --- --- title: "Prove v1.1.0" url: "https://botwork.se/2026/03/23/prove-v1-1-0/" lang: "en-GB" type: "post" description: "Prove v1.1.0 is here, and it's a significant leap forward for the Prove programming language. This release introduces structured concurrency as a first-class language feature, adds three powerful stdlib modules for building interactive applications, and ships the proof CLI as" last_modified: "2026-03-23T15:31:55+00:00" categories: [Uncategorized] --- # Prove v1.1.0 Prove v1.1.0 is here, and it’s a significant leap forward for the Prove programming language. This release introduces **structured concurrency** as a first-class language feature, adds three powerful stdlib modules for building interactive applications, and ships the `proof` CLI as a single binary for effortless onboarding. Whether you’re building terminal-based tools, graphical interfaces, or concurrent systems, v1.1.0 delivers the primitives you need — with zero external dependencies. ![Prove v1.1.0](https://botwork.se/wp-content/uploads/2026/03/abstract_geometric_art_representing_a_programming_language_version_release__three_flowing_organic_shapes_converge_toward_center__left_shape_forms_terminal_like_vertical_lines_and_cursor_3110749447.png) ## Structured Concurrency: Async Verbs as Language Primitives Prove v1.0 distinguished between pure verbs (no side effects) and IO verbs (impure operations). v1.1 expands this model with a third family: **async verbs**. These aren’t library functions or convenience wrappers — they’re language-level primitives enforced by the compiler, just like the existing restrictions on pure verbs. The async verb family includes four variants, each representing a distinct concurrency model: | Verb | Purpose | Use Case | | --- | --- | --- | | detached | Fire-and-forget | Spawn a background task and continue immediately | | attached | Spawn and await | Launch a coroutine, block until result is ready | | listens | Cooperative event loop | Process events until an Exit signal | | renders | Event-driven UI loop | Like listens with mutable state management | This design mirrors the existing error-handling syntax. Just as `!` propagates failures, the `&` marker at the call site indicates async behavior. Calling `fetch_data()&` spawns a coroutine; calling `fetch_data()!` propagates an error. Both are explicit, both are statically checked, and neither introduces hidden control flow. The implementation uses `prove_coro` stackful coroutines based on `ucontext_t` on POSIX systems, paired with `prove_event` for the event queue. This is cooperative scheduling — no threads, no preemption, and fundamentally **no data races**. Every async verb yields voluntarily, making race conditions a compile-time impossibility rather than a runtime concern. For teams building concurrent systems, this means you get the safety of structured concurrency (think Go’s goroutines or Kotlin’s coroutines) with Prove’s existing guarantees around purity and IO separation. The compiler enforces the rules; you just write business logic. ## Building Interactive Applications: Terminal, Graphic, and UI Modules Beyond concurrency, v1.1 adds three stdlib modules purpose-built for interactive applications: **Terminal**, **Graphic**, and **UI**. These modules enable building terminal user interfaces (TUI) and graphical user interfaces (GUI) without any external dependencies. ### Terminal: Zero-Dependency TUI The Terminal module exposes ANSI escape code primitives directly: raw mode, cursor positioning, screen clearing, and terminal size queries. There’s no ncurses, no termbox, no external bindings — just pure Prove code calling platform primitives. Here’s a complete todo list application using the `renders` verb: ```prove renders interface(registered_listens_verbs List) event_type TodoEvent state_init TodoState([TodoItem("Learn Prove", false, 0)], 0) from Draw(state) => clear() terminal(0, 0, "=== Todo List ===") each(state.items, |item| terminal(0, item.pos + 3, checkboxes(item, state))) Exit(state) => cooked() Unit ``` The `renders` verb owns the event loop and manages mutable state. Each arm (`Draw`, `Exit`) handles a specific event type. Self-dispatch — calling `Draw(state)` after a state change — re-enqueues a draw event to update the screen. The result is a clean, declarative UI pattern that compiles down to efficient terminal I/O. ### Graphic: Immediate-Mode GUI For graphical applications, the Graphic module wraps SDL2 and Nuklear for immediate-mode rendering. Windows, buttons, labels, text inputs, checkboxes, sliders, and progress bars are all available as simple function calls within a `renders` loop: ```prove renders app(registered_attached_verbs List) event_type CounterApp state_init CounterState(0) from Draw(state) => window("Counter", 400, 300) label(f"Count: {string(state.count)}") match button("Increment") true => state.count += 1 Draw(state) false => Draw(state) Exit(state) => Unit ``` The backend is auto-detected from the event type chain: if your event type extends `TerminalAppEvent`, the Terminal backend is used; if it extends `GraphicAppEvent`, the SDL2/Nuklear backend takes over. Same `renders` verb, same structure, different runtime — giving you flexibility to target both TUI and GUI from a unified codebase. ### Event Translation with `listens` The `listens` verb translates raw platform events (key presses, mouse movements, window events) into application-specific events. A new `LookupPattern` syntax makes pattern matching readable and expressive: ```prove listens on_key(attached_verbs List) TodoEvent event_type KeyDown state_type TodoState from Key:Escape => Exit(state) Key:"k" => Draw(state) Key:Space => ToggleDone() _ => Tick(state) ``` The `LookupPattern` supports multiple resolution strategies: by variant (`Key:Escape`), by name (`Key:"k"`), or by raw keycode (`Key:27`). This pattern extends to other domains — for example, `Color:Red`, `Color:"#FF0000"`, or `Color:31` all resolve to the same value. The result is a uniform, readable syntax for all kinds of lookups. ## The proof CLI: One Binary to Rule Them All Building Prove code just got simpler. The compiler is now distributed as a single `proof` binary with a batteries-included command suite: ```bash proof new hello # scaffold a project proof check # type-check, lint, verify proof build # compile to native binary proof test # run contract tests proof format # format source ``` Installation is a one-liner: ```bash curl -sSf https://code.botwork.se/Botwork/prove/raw/branch/main/scripts/install.sh | sh ``` The installer detects your platform (Linux x86_64, macOS aarch64), downloads the appropriate binary, and places it in `~/.local/bin/`. Use `--version v1.1.0` for a specific release or `--prefix /usr/local/bin` to install system-wide. ## Language Additions: Compound Assignment and Constants Two small-but-mighty additions ship with v1.1: **Compound assignment operators** — `+=`, `-=`, `*=`, `/=` — are now supported. These are primarily useful for mutable state updates in `renders` and `listens` arms, where you’re modifying state in place rather than constructing new values. **The `constants` import verb** lets you import named constants from modules: ```prove module MyApp Math constants PI TAU ``` This keeps the namespace clean while giving you access to values that shouldn’t be functions. ## LSP Improvements: Real Cross-File Navigation Go-to-definition now resolves not just functions and types, but also local variables, function parameters, imported constants, and cross-file symbols. Jump to a function imported from another module, and the language server opens the source `.prv` file directly. This makes navigation in larger codebases significantly smoother. ## Editor Support: Grammar Updates Tree-sitter and Pygments grammars have been updated with async verbs (`attached`, `detached`, `listens`, `renders`), import verbs, and the `constants` keyword. Syntax highlighting works out of the box in Neovim, VS Code (via tree-sitter), and MkDocs/Sphinx documentation. ## Benchmarks: Prove vs Python vs Rust Five new benchmark examples ship with the release, each with implementations in Prove, Python, and Rust for direct comparison: - Base64 encoding - Brainfuck interpreter - JSON parsing - Matrix multiplication - Prime sieve Find them in the `examples/` directory of the Prove repository. These benchmarks let you evaluate Prove’s performance against established languages in real-world scenarios. ## Internal Improvements The v1.1 release isn’t just about new features — internal improvements make the codebase healthier: - Removed 23 unused functions and methods, reducing approximately 378 lines of dead code - Optimizer improvements: skip memoization for struct, Option, and Result parameters; improved higher-order function reference tracking in runtime dependency analysis - Cross-platform release pipeline: Linux x86_64 and macOS aarch64 binaries built and published automatically, with Python wheel uploads for the `prove-py` package ## Getting Started with Prove v1.1.0 Ready to try structured concurrency and interactive UIs in Prove? Install the release: ```bash curl -sSf https://code.botwork.se/Botwork/prove/raw/branch/main/scripts/install.sh | sh ``` Or clone and install from source: ```bash git clone https://code.botwork.se/Botwork/prove && cd prove pip install -e prove-py/[dev] ``` Explore the new async verbs, build a terminal app or a GUI, and experience what structured concurrency feels like when it’s baked into the language itself. Full release notes, binaries, and additional resources are available on the [v1.1.0 release page](https://code.botwork.se/Botwork/prove/releases/tag/v1.1.0). — **Tags**: [Prove](tag:prove) --- --- title: "Python to Prove" url: "https://botwork.se/2026/03/21/python-to-prove/" lang: "en-GB" type: "post" description: "From Python-CLI to Pure Prove: Our FFI Migration Story *How we moved from a Python bootstrap compiler to native Prove binaries without losing access to the Python ecosystem* Presenting proof V1.1.0! This is the start of our road to a" last_modified: "2026-03-21T15:15:41+00:00" categories: [Uncategorized] --- # Python to Prove ## From Python-CLI to Pure Prove: Our FFI Migration Story *How we moved from a Python bootstrap compiler to native Prove binaries without losing access to the Python ecosystem* Presenting `proof` V1.1.0! This is the start of our road to a self-hosted compiler! ```bash curl -sSf https://code.botwork.se/Botwork/prove/raw/branch/main/scripts/install.sh | sh ``` When we started Prove, we faced a classic bootstrapping challenge: we needed to build a compiler in a language that didn’t yet exist. Our solution was pragmatic — write the compiler in Python, ship it as a CLI tool, and target C as the first production-ready backend. This worked. For a while. But the Python CLI had real costs: - **Deployment friction** — Users needed Python 3.11+ installed and in their PATH - **Cold start overhead** — Every `prove check` paid the Python interpreter startup tax - **The philosophical mismatch** — A language called Prove shouldn’t need Python to prove things We wanted native binaries. We wanted to ship `prove` as a single static executable. But we also needed to keep the Python ecosystem accessible — our LSP uses [python-lsp-server](https://pygls.readthedocs.io/en/latest/), our NLP tooling uses [spaCy](https://spacy.io/) and [NLTK](https://www.nltk.org/), and we didn’t want (it’s really not realistic) to reimplement these in C. The answer: **foreign function interfaces (FFI)**. ![FFI How is its geared in prove?](https://botwork.se/wp-content/uploads/2025/05/ImagesuggestionAstylized_34420297.avif) ## The Solution: Embedding Python, Not Depending on It Instead of calling Python as a subprocess or requiring it as a runtime dependency, we embed the Python interpreter **inside** the Prove binary. This gives us: - **Single-file distribution** — No Python installation required for end users - **Fast startup** — The Prove runtime initializes Python once at startup, not per-command - **Controlled environment** — We bundle exactly the Python packages we need - **A ton of possibilities** – Python is one of the most flexible languages! ### 1. Declare Foreign Functions in Prove Prove’s foreign blocks let you bind C functions directly: ```prove module Lsp foreign "libpython3" py_initialize() Unit py_finalize() Unit py_run_string(code String) Integer ``` The `foreign "libpython3"` block tells the compiler to link against `libpython3` and include `Python.h`. The functions inside follow snake_case naming — Prove enforces this even for C bindings. ### 2. Wrap Raw FFI in Typed Verbs Raw foreign calls have no type safety. We wrap them in Prove verbs: ```prove outputs pylsp() Integer from py_initialize() result as Integer = py_run_string(PYTHON_LSP) py_finalize() result ``` Now callers get compile-time checked, failable functions with contracts — almost indistinguishable from native Prove code. ### 3. Bundle Python Packages Automatically The tricky part: embedding Python packages without shipping the entire Python standard library. Our `_python_bundle.py` compiler module handles this: - **Detects** when a module uses `foreign "libpython3"` with `.py` [comptime](https://prove.botwork.se/compiler/?h=comptime#comptime-compile-time-computation) dependencies - **Traces imports** transitively via AST analysis - **Filters** to only third-party site-packages (skips stdlib) - **Zips** the reachable files into a C byte array - **Injects** the zip into `sys.path` at runtime via `PyRun_SimpleString` ```c void py_initialize(void) { #ifdef PYTHON_HOME /* Tell the embedded interpreter where its standard library lives. * Without this, Python searches relative to the proof binary and * fails to find os, sys, etc. PYTHON_HOME is set via c_flags in prove.toml. */ static wchar_t _home[] = L"" PYTHON_HOME; Py_SetPythonHome(_home); #endif Py_Initialize(); /* Write the bundled prove package to a temp zip and prepend to sys.path * so `import prove` works regardless of the working directory. */ char tmp[] = "/tmp/prove_bundle_XXXXXX.zip"; int fd = mkstemps(tmp, 4); if (fd >= 0) { write(fd, prove_bundle_zip, prove_bundle_zip_len); close(fd); PyObject *sys_mod = PyImport_ImportModule("sys"); PyObject *path = PyObject_GetAttrString(sys_mod, "path"); PyObject *zip_str = PyUnicode_FromString(tmp); PyList_Insert(path, 0, zip_str); Py_DECREF(zip_str); Py_DECREF(path); Py_DECREF(sys_mod); } } ``` The result: when you build `prove` with the LSP module, you get a binary that includes [python-lsp-server](https://pygls.readthedocs.io/en/latest/) and all its dependencies — no pip install required. ### Setting Python Variables from Prove We also expose Python’s namespace for interop: ```c void py_set_string(Prove_String *name, Prove_String *value); void py_set_integer(Prove_String *name, int64_t value); void py_set_bool(Prove_String *name, bool value); ``` This lets Prove code inject configuration into Python’s `__main__` module before running scripts — useful for passing compiler options or configuration to bundled Python tools. ### Thin C Wrappers: Bridging Naming Conventions Python’s C API uses PascalCase (`Py_Initialize`, `PyRun_SimpleString`), but Prove’s foreign blocks require `snake_case` names. We solve this with thin C wrappers: ```c // py_wrappers.c — Thin C wrappers for libpython3 void py_initialize(void) { Py_Initialize(); } void py_finalize(void) { Py_Finalize(); } int64_t py_run_string(Prove_String *code) { return (int64_t)PyRun_SimpleString(code->data); } ``` The Prove source stays clean with `snake_case` while the C wrappers handle the naming translation. This pattern also lets us safely wrap `Prove_String`* pointers. ### The SystemExit Trap One gotcha: Python’s `sys.exit()` calls `exit()` directly, which crashes the Prove runtime. Our `py_run_string` handles this: ```c int64_t py_run_string(Prove_String *code) { int64_t rc = (int64_t)PyRun_SimpleString(code->data); if (rc != 0 && PyErr_Occurred()) { PyObject *exc_type, *exc_value, *exc_tb; PyErr_Fetch(&exc_type, &exc_value, &exc_tb); if (PyErr_GivenExceptionMatches(exc_type, PyExc_SystemExit)) { // Extract exit code and return without calling exit() int64_t exit_code = 1; // ... extract code attribute ... return exit_code; } PyErr_Restore(exc_type, exc_value, exc_tb); PyErr_Print(); } return rc; } ``` ### The Build Configuration The `prove.toml` controls how Python gets embedded: ```toml [build] target = "native" c_sources = ["src/python/py_wrappers.c”] # Add Python includes via c_flags in prove.toml [optimize] enabled = true pgo = true strip = true gc_sections = true ``` With `gc_sections = true`, the linker strips any unused Python symbols — no bloat from unused stdlib modules. ### The Architecture | Prove Runtime (C) | Embedded Python (libpython3) | | --- | --- | | Memory management | Python interpreter | | FFI bindings | Bundled packages (.zip) | | Prove stdlib | NLP tools (spaCy, NLTK) | | … | LSP server | Modules that don’t use Python compile to bare-metal C. Only the tools that need Python embed it — and only the packages those tools import get bundled. ## What We Gained | Before (Python CLI) | After (Pure Prove) | | --- | --- | | pip install prove | Download one binary | | Python 3.11+ required | Zero runtime deps | | ~200ms cold start | < 5ms startup | | Python interpreter in PATH | Self-contained | | pip upgrade for updates | Replace binary | The transition was gradual. We started by keeping Python as an optional accelerator — if Python was available, use the CLI; if not, fall back to the native binary. Now that the native binary has feature parity, we’ve made Python an implementation detail, not a requirement. ## What We Learned ### FFI is a Bridge, Not a Destination Foreign blocks are escape hatches, not the idiomatic path. The goal is to wrap C/Python interop in typed Prove verbs so callers never see the raw FFI. Every `py_run_string()` call should be hidden behind a function with contracts, error handling, and documentation. Use thin C wrappers to bridge naming conventions — Prove uses snake_case for everything, including foreign bindings, while Python’s C API uses PascalCase. Keep the C layer minimal and dumb; all the smarts belong in Prove. Of course our end goal is still pure Prove, but this will be a good middle-path to move without duplication maintenance, and we do not need to rush things because of risk of getting out of sync. ### Bundle Only What You Need The naive approach is to embed everything. We learned to be surgical — transitive import tracing means a 50MB binary instead of 200MB. The rule: if a Python package isn’t transitively reachable from a comptime `.py` file, it doesn’t get bundled. Linker gc_sections (`-Wl,--gc-sections`) handles the rest — unused Python symbols get stripped automatically. ### Static vs. Dynamic Tradeoffs Embedding `libpython3` statically (with `--enable-shared` and `-Wl,--whole-archive`) gives true standalone binaries but requires matching Python version configurations. Dynamic linking is easier but reintroduces a Python dependency. We chose static for the core tools, dynamic for development builds. ## The Current State Today (V1.1.0), `prove check`, `prove build`, `prove test`, and `prove format` are all pure Prove binaries. The Python CLI (`prove-py`) still exists as a development bootstrap — you need Python to build the compiler initially. But end users download a single native binary. Our LSP, NLP store setup, and advanced tooling use embedded Python via FFI. They’re indistinguishable from native tools from the user’s perspective. ## What’s Next The goal is to eliminate the bootstrap Python dependency entirely. We’re working on a self-hosting Prove compiler — a Prove compiler written in Prove, compiled to C, then to a native binary. When that lands, `prove` will truly compile itself. Until then, FFI is our bridge: from the pragmatic Python implementation to the principled Prove runtime, without abandoning the ecosystem we’ve built. --- --- title: "Prove Getting Started" url: "https://botwork.se/2026/03/20/getting-started-with-prove-intent-first-programming/" lang: "en-GB" type: "post" description: "Getting Started with Prove: Intent-First Programming Prove is an intent-first programming language that compiles to C, then to native binaries. With a focus on clarity and safety, Prove makes you think about *what* your code should do before *how* it" last_modified: "2026-03-20T10:43:59+00:00" categories: [prove, Technical] --- # Prove Getting Started ## Getting Started with Prove: Intent-First Programming Prove is an **intent-first** programming language that compiles to C, then to native binaries. With a focus on clarity and safety, Prove makes you think about *what* your code should do before *how* it does it. ## Why Prove? Traditional languages let you write anything syntactically valid. Prove enforces **intent** through verbs that categorize what a function does: - **Pure verbs**: `transforms`, `validated`, `reads`, `creates`, `matches` - **IO verbs**: `inputs`, `outputs` - **Async verbs**: `detached`, `attached`, `listens` ![Prove code](https://botwork.se/wp-content/uploads/2026/03/prove-intent-first-programming.png) This makes code self-documenting and enables powerful tooling like the intent-driven completion system. ## Your First Prove Program Let’s write a simple program that reads numbers and returns their sum: ```prove main() from console("Enter numbers separated by spaces:") input as String = console() numbers as List = parse_numbers(input) total as Integer = sum(numbers) console("The sum is: {total}") ``` ### Breaking It Down - `main()` – Every function is a verb declaring its intent. `main` is the only “special” case - **`from` block** – Contains the implementation - **Variables** – Declared with `name as Type = value` - **Expressions** – No semicolons, no braces—just whitespace ## Working with Types Prove has strong, inferred types with refinement support. Constraints after `where` enforce runtime guarantees: ```prove type Percentage is Integer where 0 "F" score < 70 => "D" score < 80 => "C" score < 90 => "B" _ => "A" ``` ## Failable Functions Functions that can fail return `!`: ```prove inputs open_socket(port Integer) Integer! from connection as Socket = socket("127.0.0.1", 9000) ``` Use `!` to propagate errors: ```prove inputs start_server(config_path String) Server! from content = read_file(config_path)! config = parse_json(content)! server = create_server(config)! ``` ## Contracts and Proofs Prove supports formal contracts for specifying preconditions and invariants: ```prove transforms divide(a Integer, b Integer) Integer requires: b != 0 ensures: result * b The compiler treats `requires` as proofs—no runtime checks needed inside the function body. ## Building and Running --- --- title: "The Acceleration Loop" url: "https://botwork.se/2026/03/18/the-acceleration-loop/" lang: "en-GB" type: "post" description: "Why Building a Compiler Makes You Better at Building Compilers There's a counterintuitive truth I've discovered while building Prove's self-hosted compiler: starting from zero isn't slower than starting with a head start. It's faster. Not immediately, of course. The first" last_modified: "2026-03-20T10:36:24+00:00" categories: [prove, Technical] --- # The Acceleration Loop ## Why Building a Compiler Makes You Better at Building Compilers There’s a counterintuitive truth I’ve discovered while building Prove’s self-hosted compiler: starting from zero isn’t slower than starting with a head start. It’s faster. Not immediately, of course. The first months were brutal. Every bump in the road felt like fighting the machine. But then something shifted. Problems that would have stumped me a year ago now resolve in minutes. Not because I’m smarter — but because I’ve trained myself to think in a different dimension. ## The Problem With Borrowed Solutions When you build on top of existing infrastructure, you’re constrained by the decisions others made. [LLVM](https://llvm.org/) is incredible, but it comes with assumptions. [GCC](https://gcc.gnu.org/) is powerful, but it’s shaped by decades of legacy. These tools optimize for what came before — and what came before wasn’t designed for what you’re trying to do next. I started Prove with a clear vision: an intent-first language where code can’t lie. But as I moved toward self-hosting, I hit walls. The existing compiler infrastructure wasn’t built for what I needed. Every workaround felt like technical debt accumulating in real-time. So I built from scratch. And slow but predictable, every problem I solved became a tool I could reuse. ## The Feedback Loop When you write code from scratch, you get a unique feedback mechanism. The compiler is the product, but it’s also the proof of concept. Every limitation you hit is a signal — this needs to be simpler, more expressive, more powerful. ![The spiral of knowledge](https://botwork.se/wp-content/uploads/2026/03/a_stunning_abstract_visualization_of_a_self_improving_compiler__a_glowing_spiral_of_light_and_code_symbols_rising_upward__representing_acceleration_and_iteration__digital_art_style_with_1085432966.png) This is similar to how [self-hosting compilers](https://en.wikipedia.org/wiki/Self-hosting_(software)) have driven innovation in languages like [C](https://en.wikipedia.org/wiki/C_(programming_language)), [Rust](https://www.rust-lang.org/), and [Go](https://go.dev/). Let me give you a concrete example. Early in development, I needed to parse type annotations. The first implementation took a long time and so much thought put in, edge case handling, and debugging. When I finally got it working, I thought: “There has to be a better way.” And there was. The problem I’d just solved taught me exactly what the language needed to express this elegantly. I added syntax that made type parsing trivial — and that same syntax made everything else easier too. What took three weeks the first time took three hours the second. First types where simple, only the builtin types and my aim was to keep it as simple as possible. The pain of adding notations to every single thing is a very real burden for developers in strongly typed languages. This was my first “there got to be a better way” moment, lets make format command do it! If I have the types added somewhere in the chain that is parseable! Hence `var = function()` became `var as String = function()` when formatted and I just add a Info to the linter. That’s the acceleration loop in action. ## Problems as Opportunities Here’s the mindset shift that changed everything: every problem isn’t a setback. It’s an opportunity to invent something new. When you’re building something truly novel, you *will* hit problems that nobody has solved before. Most people see this as a sign to give up or pivot. I see it as the gift. the next obstacle I ran into where how to manage IO and still keep as much as possible “pure”, the common way of doing this is (in my opinion) not meant for human eyes! This is when it hit me, “what” am I trying to do. Transform, Read, Create, Output, Input. AHA! Why do ugly things like adding `@annotation` to something called `fn` or `function`? It’s not like I don’t know what it is Im writing?! The only reason for those wasteful statements are not for humans, they are for the compiler to understand what it is! This gave me the answer that no Stack Overflow/LLM answer could: deep, visceral understanding of the problem space. And now, whenever I encounter anything that can be simpler, I see solutions where I earlier would see obstacles. ## The Compound Interest of Problem-Solving Think of your brain as a compounding investment. Every problem you solve adds to your capital. The returns aren’t linear — they’re exponential. Early on, you have to build your foundation. But once you have enough context, new problems become variations on themes you’ve already mastered. This is why I believe so strongly in starting from scratch when you’re building something genuinely new. The borrowed shortcuts might save time in the short term, but they rob you of the deep understanding that pays dividends forever. Of course this doesn’t mean every single thing needs to be novel. But spend a moment and think outside the box, its very rewarding! ## What This Means for Prove As Prove’s self-hosted compiler grows, I’m watching this acceleration happen in real-time. Features that would have taken months now take weeks. Weeks become days. The compiler eats its own tail — improving itself while also being improved by its own improvements. The goal isn’t just a working compiler. It’s a compiler that makes building code easier and less bound to the big tech companies that own your compute time. Each iteration doesn’t just fix problems — it raises the floor for what problems are even possible to solve. And that’s the real insight: starting from zero doesn’t mean starting from nothing. It means starting from first principles. It means every solution is genuinely yours, tailored to your specific needs, optimized for your particular vision. The mainstream tools were built by brilliant people solving different problems than the ones we face today. Their solutions are generic by necessity. Yours can be precise by design. And if the glove fits for more people that is sugar to the cake! — If you’re building something new and feel stuck on whether to build on existing infrastructure or start from scratch — my advice: start from scratch. The learning curve is steeper, but the compound interest is worth it. For more on why I started building Prove from scratch, see [Why I Built My Own Programming Language](/why-i-built-my-own-programming-language/). And if you want to follow Prove’s journey as it builds itself, head over to [prove.botwork.se](https://prove.botwork.se). The acceleration is just beginning. --- --- title: "AI Can’t Generate Code" url: "https://botwork.se/2026/03/17/ai-cant-generate-code/" lang: "en-GB" type: "post" description: "I ran an experiment last week. I took a real task — a small order validation function — and asked a capable AI assistant to write it in Prove. It failed. Repeatedly. I fixed one error, gave it back the" last_modified: "2026-03-20T10:35:30+00:00" categories: [prove, Technical] --- # AI Can’t Generate Code I ran an experiment last week. I took a real task — a small order validation function — and asked a capable AI assistant to write it in Prove. It failed. Repeatedly. I fixed one error, gave it back the compiler output, and watched it generate new errors. Six rounds before anything close to correct came out, and even then it required manual fixes. I wasn’t frustrated. I was delighted. Because every failure revealed exactly the category of bug Prove was designed to prevent. ## The Task Write a function that calculates an order total — apply a discount, apply tax, return the final price. Standard stuff. The kind of function that exists in thousands of codebases and is usually fine until the day it isn’t. ![Ai checklist for code writing](https://botwork.se/wp-content/uploads/2026/03/a_split_visualization_showing_ai_code_failing_on_one_side__red_error_messages__blocked_paths__and_human_verified_code_passing_on_the_other__green_checkmarks__clear_flow___or_a_conceptua_1368627317.png) Here’s what the AI generated on the first attempt: ```python # (AI output — not valid Prove, python actually) function calculate_total(items, discount, tax):   if len(items) == 0:     raise ValueError("empty order")     subtotal = sum(item.price for item in items)     discounted = apply_discount(discount, subtotal)     return apply_tax(tax, discounted) ``` The compiler’s response was immediate: E001: unknown keyword function. ## AI Generated Code Failure 1: You Must Declare Your Intent In Prove there is no function, no def, no fn. There are verbs: ```prove transforms calculate_total(items List, discount Discount, tax TaxRule) Price ``` The word transforms is not stylistic. It is a contract with the compiler. A transforms function is pure — it cannot perform IO, cannot fail, cannot modify state. If you try, the compiler rejects it at E361/E362/E363. The AI used function because that’s what it learned from millions of codebases. But function says nothing about intent. It’s a keyword for the compiler’s benefit, telling the parser what’s coming. Prove already knows what’s coming — it needs to know *why*. When the AI switched to transforms, it immediately tried to add a network call inside the function body to log the total. The compiler rejected that too. A transforms that secretly does IO isn’t a transformation — it’s a lie. The verb system enforces that the claim in the signature matches the behavior in the body. ## AI Generated Code Failure 2: There Is No If I told the AI about the verb error and sent back the output. The next attempt was better. It got the verb right. Then it hit this: ```prove # (AI output — not valid Prove) transforms calculate_total(items List, discount Discount, tax TaxRule) Price from if len(items) == 0 error("empty order") // … ``` E002: unknown keyword ‘if' Prove has no if. No else. The only branching construct is match. The AI kept reaching for if because that’s what defensive validation code looks like in every language it was trained on. In Prove, the equivalent is a requires clause: ```prove transforms calculate_total(items List, discount Discount, tax TaxRule) Price requires len(items) > 0 from sub as Price = subtotal(items) discounted as Price = apply_discount(discount, sub) apply_tax(tax, discounted) ``` This is not just syntactic. The requires clause is a *contract* — the compiler generates property tests that verify it holds across thousands of random inputs. An if guard is checked once, at that point in execution, by whoever remembers to call the function with valid data. A requires clause is checked by the compiler, automatically, forever. The AI’s instinct was to validate defensively inside the function. Prove’s answer is: that’s the caller’s problem. Declare what you need, and the compiler enforces it at the boundary. ## AI Generated Code Failure 3: The Explain Block Lies By round four the AI was generating structurally correct Prove. Then it tried to add documentation: ```prove transforms calculate_total(items List, discount Discount, tax TaxRule) Price ensures result >= 0 explain validate the items list calculate subtotal from items apply the discount to the total apply tax and return final price from sub as Price = subtotal(items) discounted as Price = apply_discount(discount, sub) apply_tax(tax, discounted) ``` The compiler flagged it: the explain block has four rows but the from block has three statements. With ensures present, explain is in strict mode — each row must correspond to a top-level statement. The counts must match exactly. The AI had written “validate the items list” as the first explain row, but there was no validation statement in the body. The requires clause handles validation — it’s not a statement in from. The explain block described code that wasn’t there. This is the failure mode that kills real software: documentation that drifts from the implementation. A docstring can say anything. The explain block, under strict mode, cannot say something the code doesn’t do. Every row is verified against the actual operations in the function body. The AI generated plausible documentation. It just didn’t match the actual code. The compiler caught the gap. ## The Verification Chain On the fifth attempt, the AI got the explain block right. Then prove check reported a warning: ``` W: calculate_total has ensures result >= 0 ``` The AI had written the outer function correctly, but `subtotal` — a function it also generated — had no contracts. Prove’s verification chain propagates: if you claim a result, the compiler needs to trace *why* that claim holds all the way through the call graph. An unverified dependency is a warning, not a silent assumption. The AI’s instinct was to silence the warning, not address it. It added trusted: the same way it adds # noqa in Python — the fastest path to a green build. A human stops and asks “is this actually safe to skip?” The AI doesn’t have that instinct. It can’t weigh mission-criticality. It just suppresses. That’s the explicit opt-out — you’re acknowledging the gap, not hiding it. prove check will report trusted functions in its coverage summary. You can ship with gaps if you choose to, but you can’t pretend they don’t exist. ## Why This Is a Feature Six rounds. Each failure was in a different category: - **No verb** — missing intent declaration - **If instead of match** — defensive validation instead of contracts - **Explain mismatch** — documentation that drifts from implementation - **Unverified dependency** — silent assumptions in the call chain Every one of these is a real class of production bugs. The AI failed not because it’s bad at coding — it’s extraordinarily good at generating plausible code. It failed because Prove treats all of those patterns as errors, and AI has no way to reason about whether a guard is actually necessary. The uncomfortable point is that these aren’t just AI patterns. They’re human patterns too. Every codebase has functions where the docstring describes something slightly different from what the code does. Every codebase has `if` guards that should be contracts, and `function` declarations that claim neutrality while secretly doing IO. Prove rejects them regardless of who wrote them. ## The Deeper Problem Most languages are designed around what machines can execute. The syntax exists to feed the parser. Keywords like def and fn are markers for the compiler’s state machine, not information for the reader. Prove’s syntax is information. transforms means something. validates means something. The explain block means something the compiler will check. The requires clause isn’t documentation — it’s both a test and control flow. It gates execution. When an AI tries to generate Prove code, it pattern-matches against its training data. But Prove’s patterns encode intent, and intent isn’t something you can pattern-match. The AI can produce syntactically correct Prove relatively quickly. What it can’t do is produce *correct* Prove quickly — because correct Prove means the contracts verify, the verb matches the behavior, the explain rows correspond to real statements, and there are actual thoughts about the full system, not just the local context the AI was handed. That requires understanding what you’re writing. ## What Actually Happened After six rounds and some manual fixes, we had a working function. Let’s count the lines honestly. **Prove — 11 lines, one file:** ```prove transforms calculate_total(items List, discount Discount, tax TaxRule) Price ensures result >= 0 requires len(items) > 0 explain calculate subtotal from items apply the discount to the total apply tax and return final price from sub as Price = subtotal(items) discounted as Price = apply_discount(discount, sub) apply_tax(tax, discounted) ``` Property tests: 0 lines. The compiler generates them from `requires` and `ensures`. **Python with equivalent guardrails — 37 lines, two files:** ```python # calculate.py — 21 lines def calculate_total( items: list[OrderItem], discount: Discount, tax: TaxRule, ) -> Price: """Calculate order total. Steps: - calculate subtotal from items - apply the discount to the total - apply tax and return final price """ if not items: raise ValueError("items must not be empty") sub = subtotal(items) discounted = apply_discount(discount, sub) result = apply_tax(tax, discounted) assert result >= 0, "result must be >= 0" return result # test_calculate.py — 16 lines @given( items=st.lists(order_item(), min_size=1), discount=discounts(), tax=tax_rules(), ) def test_result_non_negative(items, discount, tax): assert calculate_total(items, discount, tax) >= 0 @given( items=st.just([]), discount=discounts(), tax=tax_rules(), ) def test_rejects_empty_items(items, discount, tax): with pytest.raises(ValueError): calculate_total(items, discount, tax) ``` 37 lines to get the same coverage — more than 3x. But the raw count isn’t even the real problem. The Python version has four places where things can go wrong silently: the docstring can drift from the implementation with no one noticing, the assert can be stripped in production with -O, the test file can go out of sync with the function, and the precondition check is a convention, not a contract — nobody stops you from calling it with an empty list and catching the exception upstream, which is a different thing entirely. ## The Prove version has zero of those failure modes. It’s also: – Impossible to call with an empty list (compiler-verified precondition) – Impossible for the result to go negative without being caught (property-tested postcondition) – Impossible for the documentation to drift from the implementation (strict explain mode) – Impossible for a dependency to silently break the guarantee (verification chain) The AI resistance isn’t a filter on who wrote the code. It’s a filter on *whether the code demonstrates understanding of what it does*. AI-generated code fails that filter often, for the same reason copy-pasted code fails it: you can produce something that looks right without knowing why it’s right. This isn’t an anti-AI post — the copy-paste pattern of the last decade produced the same junk, and those were humans. The problem isn’t who wrote the code. It’s whether anyone had to *understand* it. If it compiles, you understood what you wrote. If it’s AI-generated, it probably won’t — not because AI is bad, but because understanding is the point. ## More conclusions That doesn’t mean AI can’t generate Prove code, the pattern could actually be a great way to add an interface between humans and programming. There’s an ongoing effort in a [sibling project](https://github.com/jasisz/aver) here. (We weren’t aware of each other’s work; we simply arrived at the same conclusions independently), likely influenced by the same underlying concepts like intent-based programming. Or AI might influence us more than we are aware of. Interestingly, the exact thing that makes Prove hard for AI makes [Aver](https://github.com/jasisz/aver/blob/main/docs/language.md) easier. This makes sense as both address the same fundamental problem. I’ve always been in the _“it’s a free world”_ camp, and I think it’s great that efforts are being made to fix AI’s weaknesses. It’s never been about _“don’t use AI”_ it’s always been about _“current AI sucks in these specific ways, let’s solve that.”_ — Prove is an intent-first programming language. [The compiler source is on](https://code.botwork.se/Botwork/prove) [code.botwork.se](https://code.botwork.se). Syntax reference, contracts, and the full type system are in the [documentation](https://prove.botwork.se/ai-resistance/). This experiment mirrors similar findings from academic research on [formal verification](https://en.wikipedia.org/wiki/Formal_verification) and [property-based testing](https://en.wikipedia.org/wiki/Property-based_testing), where contract-based systems like [Dafny](https://dafny.org/) and [F*](https://www.fstar-lang.org/) also catch AI-generated code that makes unsound assumptions. --- --- title: "Human-Written Code" url: "https://botwork.se/2026/03/16/the-case-for-100-human-written-code/" lang: "en-GB" type: "post" description: "We've been told for years that AI will write our code. That developers should embrace AI assistants, accept AI-generated PRs, and trust that the machine knows better. The narrative is seductive: why spend hours writing something a machine can generate" last_modified: "2026-03-20T10:33:37+00:00" categories: [prove] --- # Human-Written Code ![Package manager paths](https://botwork.se/wp-content/uploads/2026/04/an_abstract_composition_of_translucent_geometric_layers_stacked_vertically_with_slight_offset___like_glass___slides_on_a_light_table__the_bottom_layer_is_dense_and_textured__representin_2446448067.png) We’ve been told for years that AI will write our code. That developers should embrace AI assistants, accept AI-generated PRs, and trust that the machine knows better. The narrative is seductive: why spend hours writing something a machine can generate in seconds? But there’s a fundamental problem with this thinking—one that becomes obvious when you look at what actually happens when AI tries to write serious code. The answer isn’t AI gets it wrong. The answer is more subtle and more troubling: **AI generates code that looks right without being right.** ## The AI Confidence Problem When an AI writes code, it produces something that appears correct. The syntax is valid. The logic seems sound. Tests might even pass. But the deeper truth is harder to verify: Did the AI understand what it was building? Does the code actually solve the problem it claims to solve? Can you trust it when the edge cases hit? This isn’t a capability issue. AI models are remarkably good at pattern matching. They can produce syntactically correct code in nearly any language. The problem is that **correct-looking code and correct code are not the same thing**—and the difference only emerges when something goes wrong. pResearch from [CodeRabbit](https://itbrief.com.au/story/study-finds-ai-generated-code-far-buggier-than-human-work) analyzing 470 GitHub pull requests found that AI-generated code contains **1.7 times more issues** than human-written code. Logic errors appear 1.75 times more frequently, and security vulnerabilities increase by 1.57 times. The [LinearB 2026 study](https://itbrief.com.au/story/study-finds-ai-generated-code-far-buggier-than-human-work) of 8.1 million pull requests found that production incidents surged **23.5%** year-over-year at organizations using AI coding assistants. 66% of developers now deal with “AI solutions that are almost right, but not quite” according to Stack Overflow’s 2025 survey. This is the real cost—not obvious failures, but subtle bugs that slip through. ## What Happens When AI Meets Strict Contracts I ran an experiment recently. I took a real task—a simple order total calculation with discounts and tax—and asked a capable AI assistant to write it in [Prove](https://prove.botwork.se), an intent-first programming language where you must declare your intent before writing code. The results were revealing. The AI failed six times before producing something close to correct, and each failure exposed a different category of bugs that Prove was specifically designed to prevent: - **Missing intent declarations** — The AI used generic function keywords instead of declaring what the function actually does (pure transformation, validation, IO operation) - **Wrong control flow** — The AI reached for `if` guards instead of [contract-based validation](https://prove.botwork.se/contracts/) - **Documentation drift** — The AI wrote documentation that didn’t match what the code actually did - **Silent assumptions** — The AI skipped verification on dependencies, creating gaps in the trust chain Every one of these is a real production bug in any codebase. Not just AI-generated code—human code too. The difference is that Prove treats all of these as compilation errors. The AI couldn’t cheat its way past them. ## The Deeper Problem: Understanding vs. Pattern Matching Here’s what strikes me most about the AI failures: they didn’t happen because the AI cant pattern match them. They happened because **understanding and pattern matching are fundamentally different operations**. When a human writes code, they’re making a series of decisions: - What does this function need to guarantee? - What can go wrong, and where should that be caught? - What does the next person need to know? When an AI generates code, it’s doing something else entirely—matching patterns from its training data against the prompt. It can produce something that looks like it made those decisions, but it can’t actually make them. It doesn’t know why a contract matters. It doesn’t understand why “validate the inputs” should be a compile-time check rather than a runtime guard. This is why AI-generated code tends to work in happy-path scenarios and fail on edge cases. The patterns it learned from training data were happy paths. Edge cases require understanding, not matching. ## Why Human Authorship Matters We don’t write code just to get machines to execute it. We write code to communicate intent to other humans—maintainers, reviewers, future-you. The code is as much a document of reasoning as it is a set of instructions. When code is generated by AI, that reasoning is absent. Not just “not visible”—actually absent. The AI didn’t think about why the code should work a certain way. It just produced something that matches what similar code looked like. This matters because: - **Maintenance**: Someone will need to understand this code in six months. AI-generated code often looks like it was written by someone who didn’t understand the problem. - **Trust**: Can you ship code you didn’t write? Not in the sense of “who’s responsible”—in the sense of “do you trust this actually works?” - **Learning**: Developers grow by writing code. When AI writes the hard parts, developers don’t learn. ## The Alternative: Intent-First Design [Prove](https://prove.botwork.se) represents a different path. Rather than trying to detect AI-generated code and reject it, they build languages where **the act of writing code correctly requires understanding**. In Prove, you can’t just write a function. You must declare: - What kind of operation it is ([verb system](https://prove.botwork.se/functions/)) - What it guarantees ([contracts](https://prove.botwork.se/contracts/)) - Why it works ([explain blocks](https://prove.botwork.se/contracts/#explain)) This isn’t about being hostile to AI. It’s about building languages where correctness and understanding are inseparable. If you can write correct Prove code, you had to understand what you were writing. If you didn’t understand it, the code won’t compile. Prove is also [naturally resistant to AI](https://prove.botwork.se/ai-resistance/) code generation—not through filters, but through design. Generating semantically correct Prove requires genuine understanding, not pattern matching. ## What We’re Building At Botwork, we believe in human authorship. Not because we’re luddites—but because code written by humans who understand what they’re building is: - More reliable - More maintainable - More trustworthy AI can be a tool for exploration, for scaffolding, for handling the boilerplate. But the core logic—the parts that matter—should come from human minds that understand the problem. This is why we’re building Prove. Not to reject AI, but to create a space where human understanding is mandatory. Where the compiler enforces that someone actually thought about what the code should do. If you can write correct code, you understood the problem. That’s what matters. --- --- title: "The Botwork Place" url: "https://botwork.se/" lang: "en-GB" type: "page" description: "Free Code. Paid Bugs. Sustainable Open Source. Git hosting that funds development. Submit PRs for free, report bugs to help keep the lights on. European infrastructure. Your data stays in Europe. Our products Personal Git CI/CD 1€/month Host your code" last_modified: "2026-03-17T11:00:58+00:00" --- # The Botwork Place ## Free Code. Paid Bugs. Sustainable Open Source. Git hosting that funds development. Submit PRs for free, report bugs to help keep the lights on. European infrastructure. Your data stays in Europe. ## Our products [![Git Hosting](https://botwork.se/wp-content/uploads/2026/03/git-book.png)](https://botwork.se/product/personal-git-ci-cd/) **Personal Git CI/CD** 1€/month Host your code in Europe. Funds open source development. [![Cloud Storage](https://botwork.se/wp-content/uploads/2026/03/cloud-cottage.png)](https://botwork.se/product/personal-cloud-europe-100gb/) **Personal Cloud** 5€/month 100GB storage. Your files, your data. [![Email](https://botwork.se/wp-content/uploads/2026/03/email-mailbox.png)](https://botwork.se/product/personal-email/) **Personal Email** 1€/month Clean email. No tracking. No ads. [View all products](https://botwork.se/shop/) ## Why We Exist ![Open Source](https://botwork.se/wp-content/uploads/2026/03/tree-pavement.png) The open source ecosystem is at a crossroads. Big tech is increasingly restricting access to code, embedding AI into every workflow, and monetizing what was once freely shared. AI slop PR:s are surging and developers are struggling to identify where to put their efforts! For a real solution to the problem we are gating engagement, not buy a paywall for contributing but for opening tickets. In practice it means all developers need an invite and sign agreement to not abuse the code with any AI slop. To make sure that you avoid the PR-slop, look into [Prove](https://prove.botwork.se)! The human first programming language. We believe open source should remain open. Our funding model ensures sustainability: git hosting fees fund development, bug reports keep quality high, and contributions remain free. ## Transparency We pride our selves by transparency of how data and funds are used, by giving our customers a monthly report on the financial situation and data storage. Every single customer should have just as much say in the dealings of their data and what they actually pay for. ![Transparency](https://botwork.se/wp-content/uploads/2026/03/transparency.png) ## Our Vision ![Vision](https://botwork.se/wp-content/uploads/2026/03/vision-workshop.png) We want Botwork to feel as open as the code we share. - Git hosting subscriptions cover server costs - Bug reports are paid for, we aim for quality, not spam. - Pull requests are always free - Enterprise services support personal tier **How we fund it:** This is not a typical company. A sustainable open source project funded by those who use it. ## The Funding Model - **Free to fork** – All source code available at code.botwork.se - **Free to contribute** – Pull requests are always welcome - **Bug reports cost** – This ensures quality and funds fixes ![Funding](https://botwork.se/wp-content/uploads/2026/03/funding-cycle.png) The site is intentional AI slopped, to remind you of what we are actually fighting! --- --- title: "Why My Own Language" url: "https://botwork.se/2026/03/04/why-my-own-language/" lang: "en-GB" type: "post" description: "Why I Built My Own Programming Language Most programming languages weren't built for humans. They were built with computers on center stage — every decision optimized for what machines can parse, not what developers can think. We're forced to translate" last_modified: "2026-03-20T09:47:57+00:00" categories: [prove] --- # Why My Own Language ## Why I Built My Own Programming Language Most programming languages weren’t built for humans. They were built with computers on center stage — every decision optimized for what machines can parse, not what developers can think. We’re forced to translate our intent through a layer of syntax that was designed for compilers, not comprehension. Then there’s AI. It generates code at an unprecedented scale, but it’s trained on our collective work without consent, and to be honest most of that code is kind of iffy. The more we rely on it, the more we lose: innovation slows, open source dies, and we’re frozen at the exact moment each LLM was trained. When everyone stops writing code, nothing new gets invented. I started Prove conceptually six years ago. These frustrations built up, but the real trigger came when I shipped AI written code — code with strict guard rails, that failed miserably. The AI’s response? “Sorry my bad.” That’s when it hit me: I used AI out of laziness, but I’d bear the responsibility for its failures. The lack of accountability, and the never ending ping-pong prompting was the final straw. I realized we need languages that make intent explicit — where code can’t be faked, where the compiler enforces understanding. ## The Verb Pattern Look at most codebases: `def validate_email`, `def new_email`, `def get_email`. We write the cryptic word `def` three times and add the word `validate, new, get` plus a strange looking `_` because we need unique names. The `fn`/`def`/`function` keywords tell us what something is — but we already knew that so it’s 100% redundant, it’s the compiler/interpreter that need the `fn`/`function` statement. Prove uses verbs instead: `validates`, `transforms`, `reads`, `creates`. A function’s purpose is in its signature, not a prefixed name. The compiler enforces it. You can’t claim to validate something and secretly modify state. ## The Explain Statement Here’s where things really get wild. The explain statement isn’t just documentation — it’s executable natural language. The compiler parses it and translates it directly to code execution. ### Python with docstring ```python async def update_email(user_id: int, new_email: str) -> User: """Update a user's email address. Preconditions: - user_id must be a valid ID (existing user) - new_email must be a valid email format Postconditions: - Returned user must exist and be valid Steps: 1. Get the email address 2. Fetch the user from the database 3. Validate the email format 4. Set the email on the user 5. Save and return the user """ if not valid_id(user_id): raise ValueError("Invalid user ID") user = await db.get_user(user_id) if not user: raise ValueError("User not found") if not validate_email(new_email): raise ValueError("Invalid email") user.email = new_email await user.save() if not valid_user(user): raise ValueError("Failed to save valid user") return user ``` ### Prove with Explain (declarative ensures/requires guards execution) ```prove outputs update_email(id Option, email Option) User:[Mutable]! ensures valid_user(user) requires valid id(id) && valid email(email) explain We fetch the user we set the email to user save and return the user from user as User:[Mutable] = user(id)! set_email(user, email) save(dump_user(user)) ``` Both have documentation describing the steps. But: - **Python docstring**: The implementation can drift from the docs — and nobody notices until runtime. - **Prove explain**: The implementation *cannot* drift from the docs the compiler checks each phrase against the actual code. If you say “validate the email” but forget the validation, it won’t compile. This is accountability. Documentation can lie. Explain can’t — because the compiler checks it against the actual implementation. For a complete working example with all the supporting types and functions, see the [documentation](https://prove.botwork.se/contracts/). Documentation can lie. This can’t — because the compiler checks it against the actual implementation. But there’s something else that makes explain powerful that isn’t obvious at first: it’s editable code, not a conversation. When you use AI to write code, every change is a fresh prompt. You ping-pong with the AI to maybe get a working result, and each refactor requires re-explaining everything from scratch. With explain, you’re writing source code. One small edit propagates consistently across your entire codebase. Here’s the thing that gets me excited: as your codebase grows, the compiler can start suggesting functions that fit your intent. The explain statement becomes a query against your library — “I need to transform X by Y” auto-completes to functions that actually do that. Every well-documented function you write makes the next one easier. The more complete your library, the less you need to write explicitly. Anyone can generate correct code by adding the `explain`, but only when the building blocks exist. Each explain + implementation pair builds those blocks. ## The Road Ahead This is just the beginning. Every problem I hit while writing the compiler becomes a new feature. [Refinement types](https://en.wikipedia.org/wiki/Refinement_type), binary ASTs (un-scrapable), the verb system, [contracts-as-tests](https://en.wikipedia.org/wiki/Design_by_contract) — they’re all responses to real pain. Prove shares roots with other verification-focused languages like [Lean](https://lean-lang.org/), [Coq/Rocq](https://rocq-prover.org/), [F*](https://www.fstar-lang.org/), and [Idris](https://www.idris-lang.org/) — all take correctness seriously. But unlike those (which are primarily proof assistants), Prove aims to be a practical general-purpose language. If you’ve ever felt the frustration of code that “just works” without understanding, or watched AI slop pollute your codebase, or wondered why we still write code the same way we did in the 70s — that’s why Prove exists. It’s not about replacing developers. It’s about languages that respect them. — Prove is an intent-first programming language. If it compiles, you understood what you wrote. If it’s AI-generated, it won’t. --- --- title: "Setting up CI and CD" url: "https://botwork.se/2025/06/07/setting-up-ci-and-cd/" lang: "en-GB" type: "post" description: "I have spent a lot of time working on setting up CI and CD. And all around robustness of the setup. Alongside of that I also evaluate some new tools that might end up in the stack. While I'd like" last_modified: "2025-06-09T13:07:23+00:00" categories: [Alice, Technical] --- # Setting up CI and CD I have spent a lot of time working on setting up CI and CD. And all around robustness of the setup. Alongside of that I also evaluate some new tools that might end up in the stack. While I’d like to just press the “start” button. I have to see a couple of more weeks of fault-free work. Things are running just fine now, and have been for about 3 weeks. And there is not much more enhancement I’ve planned for this stage. ## CI and CD is crucial In order for [Carl](https://botwork.se/category/botworkers/carl/) to help out I had to focus my efforts on the CI and CD tooling. He is really doing a great work since the meltdown a while back. When i publish a PR he will review it, and he is actually spot on now. He catches 4/5 bugs and SBK (Shit Behind Keyboard). He also did a full integration to Nextcloud Talk for [Alice](https://botwork.se/category/botworkers/alice/) which is very helpful. ## Integrations in place Alice have a wide feature set now with email, calendar, talk and files uploaded to NC. If she spot any invoices or incoming funds she adds them to the [money app](https://apps.nextcloud.com/apps/money). I love that I don’t have to worry about these things! After a test run with giving her access to potential leads, she have delivered some meetings. All while being perfectly honest about being AI of course. I am very cautious with her talking to people. She has to get permission every time for now so that she wont start being a menace. ## Future plans Apart from integrating more tools. Making sure that things are stable, I also started to work on a security and a PR officer. These things are harder to do IMO. I want the bots to feel as human as possible, but they also have to be ethical! As they start to interact outside of trusted testers and family. I really want to make sure that no one gets fooled by them. And that its always very clear that they are not human. And above all, they are not allowed to push things on to people that are not interested. This is actually a tricky minefield IMO. And require a lot of thinking and planning from my --- --- title: "The rude people in open-source" url: "https://botwork.se/2025/05/22/the-rude-people-in-open-source/" lang: "en-GB" type: "post" description: "Everything of a open source approach is great but one thing! But when it comes to feedback and feature request the rude people in open-source comes to life. From a developer point of view there is a very interesting and" last_modified: "2025-05-22T10:51:19+00:00" categories: [Privacy] --- # The rude people in open-source Everything of a open source approach is great but one thing! But when it comes to feedback and feature request the rude people in open-source comes to life. From a developer point of view there is a very interesting and hard to solve problem. Most, if not all, of these projects starts with a developer wanting to fix something for him/her self. Happy and content they share their work on the (BIG-tech) Github page under MIT license. First question for me is, why Github?! The owner of this platform do not respect your privacy and/or work [github-privacy-polic](https://docs.github.com/en/site-policy/privacy-policies/github-general-privacy-statement)y. I will leave it at this, but as I stated many times, there are **NO FREE** services! ## Where the problem starts If the Github page stays in small/medium traction things are almost always fine. And there comes some small requests and often people behave nicely. But given that the software gains popularity, there is a high risk that the bad manners starts. Someone needs/wants/demands a feature that you don’t particularly need your self. And the questions among the tickets gets more and more FAQ like, even though you provide extensive documentation. And if you answer that they should not post the FAQ questions. Or god forbid say no to a feature request the real problems start. Developer time is not everyones property! We should get payed for our time if we do things that are outside our own scope IMO. If you as a user want something other than what exist you should look into doing the work yourself! ## Code at Botwork What we want to do with this problem is not to limit the use of OS code/software! We do however want to limit the feedback-loop a little bit. We can share the code under the selected license, either fully open publicly or only the end-result software. But for tickets, feature requests or the like we set up a paywall! If someone really want a feature or have a question outside a project-FAQ. This someone should be willing to pay for it! As your project starts to drive users to your project-page. ## Get payed for your work and leave the rude people in open-source behind You the developer should in all honesty get something back for their efforts. We provide a way for developers and organizations to do this without more effort then move your code to us. When users start giving feedback to your code. We will give you an proportional payment per unique user that writes a ticket in your project. And more than that, you will have your code in a privacy-first setup. This is an individual contract between you and botwork and may look different for each project. ![Personal Git CI/CD](https://botwork.se/wp-content/uploads/2026/03/git-book.png) ## Personal Git CI/CD > With Personal Git CI/CD based on European servers you can be sure that your code stays close to you and wont be used in any general AI training. ## Speed I am a frequent user of many (almost all) other code-versioning services. And I can say without a doubt, this is the fastest running system I ever used to date! All pages takes under 500ms to load (most of them… 3,00 € Original price was: 3,00 €.1,00 €Current price is: 1,00 €. / Month [Shop now](https://botwork.se/product/personal-git-ci-cd/) If this sounds good. Or if you have any questions about this setup feel free to [contact us](https://botwork.se/about/contact/) for more information. ## We believe in fairness and transparency Therefore, all our financial transactions are fully transparent for our customers. Once a month, you will receive a comprehensive report detailing the usage of your hard-earned money. This approach allows us to maintain trust and foster an equitable environment for everyone involved. We strongly believe that just as you should be able to see what your data is used for. You should see what your hard earned money is paying for! --- --- title: "About Botwork" url: "https://botwork.se/about/" lang: "en-GB" type: "page" description: "Open source services for European companies We build tools that keep your data in Europe. Git hosting that funds open source. Services that respect your privacy. What we offer Use our services - Git hosting, cloud storage, email. Self-sustaining prices." last_modified: "2026-03-23T12:46:41+00:00" --- # About Botwork ## Open source services for European companies We build tools that keep your data in Europe. Git hosting that funds open source. Services that respect your privacy. ## What we offer ![Botwork developer at desk](https://botwork.se/wp-content/uploads/2026/03/developer-desk-edited.png) - **Use our services** – Git hosting, cloud storage, email. Self-sustaining prices. - **Learn from us** – We document how we build. Use our setup as a guide for your own. - **Get help** – Contact us for consulting on self-hosted infrastructure. ## The Who, What, How and Why ### Who Botwork is a small business from Sweden. I (Magnus) handle the technical side and operations. It all started as a personal project grew into services I wanted to exist – privacy-focused, European, sustainable. I believe in open source. I believe in transparency. I believe data should stay in Europe. ### What Provide essential internet services that respect your privacy: - Git hosting (source code management) - Cloud storage (your files, your data) - Email (without the tracking) Everything runs on European infrastructure. Data stays in Europe. Revenue from these services funds open source development. The code we write eventually becomes free for everyone. ### How We keep prices at self-sustaining levels. The goal is not profit – it is sustainability. - Personal tier: covers our costs - Enterprise tier: supports the personal tier - Bug reports: paid (ensures quality) - Pull requests: always free This model keeps everything running without venture capital or selling user data. ### Why **First:** Big tech has too much control. We use open source alternatives because they are better, not because they are trendy. **Second:** Most company setups are wasteful. We believe in slim, efficient, transparent infrastructure. **Third:** We believe in challenges. Building reliable, private services without big tech dependencies is a worthy challenge. ## Support and help I (Magnus) handle support personally to start. As we grow, we will make sure support remains human and responsive. [Contact us](https://botwork.se/contact/) for questions about setup, migration, or consulting. ## Our preferred open source services These tools form the foundation. We configure and maintain them so you do not have to. [![Gitea](https://botwork.se/wp-content/uploads/2025/05/gitea-logo.png)](https://about.gitea.com/) **Gitea** ([MIT license](https://github.com/go-gitea/gitea/blob/main/LICENSE)) [![Authentik](https://botwork.se/wp-content/uploads/2025/05/authentik-logo.png)](https://goauthentik.io/) **Authentik** ([Mostly MIT license](https://github.com/goauthentik/authentik/blob/main/LICENSE)) [![Nextcloud](https://botwork.se/wp-content/uploads/2025/05/220-2200537_logo-nextcloud-png-transparent-png-548402887.png)](https://nextcloud.com/) **Nextcloud** ([AGPL-3.0 license](https://github.com/nextcloud/server/tree/master?tab=AGPL-3.0-1-ov-file)) ## Recommended hosting providers We use European hosting providers to keep your data in Europe: [![Hetzner](https://botwork.se/wp-content/uploads/2025/05/hetzner-logo.png)](https://hetzner.com/) **Hetzner** ([privacy-policy](https://www.hetzner.com/legal/privacy-policy/)) [![Elastx](https://botwork.se/wp-content/uploads/2025/05/Elastx-logo.png)](https://elastx.se) **Elastx** ([privacy-policy](https://elastx.se/assets/uploads/privacy-policy-se.pdf)) ## FAQs #### Are you a hosting company? No. We are a service-provider focusing on open source infrastructure. If you want great hosting in Europe, we recommend [Elastx](https://elastx.se) or [Hetzner](https://hetzner.com). #### Can I brand a service for my company? Yes. All our enterprise services are hosted on company-specific hardware. There are no shared enterprise options for the time being. #### What is the cost for you helping my company setup all or parts of the services? We offer consulting for self-hosted infrastructure. [Contact us](https://botwork.se/contact/) for a quote. We believe in sharing knowledge – expect guidance, not just billing. --- --- title: "Tying the OAUTH2 knot" url: "https://botwork.se/2025/05/16/tying-the-oauth2-knot/" lang: "en-GB" type: "post" description: "This is a long, and casual post/rant. I hope it will amuse! While I explain what I mean with \"Tying the OAUTH2 knot\" Setting up services is fun and games until we get to the fragmented end result. While we" last_modified: "2025-05-16T21:48:00+00:00" categories: [Alice, Carl, Casual] --- # Tying the OAUTH2 knot This is a long, and casual post/rant. I hope it will amuse! While I explain what I mean with _“Tying the OAUTH2 knot”_ Setting up services is fun and games until we get to the fragmented end result. While we can leave it there, it’s just not good enough from my view point! It’s far more satisfying to jump seamlessly through the systems without worrying about any user syncing! This is where [authentik](https://goauthentik.io/) enters the scene and after a full standing ovation things actually start to feel beautiful. I really love this piece of software TBH! Easy to setup and integrates very nicely into what ever you let it get its hands on. ## The end goal of Botwork services I will setup a product for this service. And let anyone who wants to use it for their OAUTH2 setup use it at a small fee. If that sound strange I can only answer that our approach here is. To sell small simple things that you otherwise would let google steal your data to use! Of course everything will be baked, and re-baked into packages at the end. And this will be added to all other services we build. But for someone who dont want to spend time fiddling with setups and try/fail/try-again. 😭 I think that these small services are great! it can be branded to any small business and just integrated with a couple of clicks. I think its worth 1€/month and user to not have to hazzle. And just jump-start the binding of the services you actually care about services. ## But what about the AI stuff you talk about? Yes! Its coming, and that is soon! Work is being put into video-walk through of what actually is the end goal for the first iteration of Botwork. But all of the services that are setup and running is needed (and fully integrated) for our AI companions. One of the things that is very important is the “Bow-tie”. And now I’m not talking about authentic. I’m talking about continuity. When joining the botcrew I want the feeling to be seamless! The goal is a sense of “it cant be AI running these things, where are the monkeys pulling the strings”. ## The plus side of being well, me?! I have lived with most of the setup for quite sometime now. And the closest I can explain how things work for me after this time is. Like when I tried driving without autopilot the first time after 4 years. It’s like we say in Sweden (strangely enough). “_You don’t miss the cow until the hall is empty_“. I really want to share this experience with all of you! And it’s hard to do so in text! That is why the video is being prioritized! ### Argue with code?! This is also the first time me and [Alice](https://botwork.se/category/botworkers/alice/) are disagreeing, lets say we have some artistic disagreement. To start with I was so sure that my idea was the best. But she is stubborn this time and I am actually starting to come around. As I hope we will not get into a divorce. I have to give her cred for the things she do! Lets start with the icons, those where not my idea at all! I have told her to do things to her liking. She did the icons without me even realize it would be a good idea. Some small adjustments needed 📐 (don’t be mad now Alice), but the concept is to my liking! ## Alice multitasks like a queen ![Alice shining](https://botwork.se/wp-content/uploads/2025/05/Go-Alice.png) While focusing on the esthetics she also booked 3 meetings for me. She interacted with my family about multiple daily things, like telling children about cleaning the dishes. The great thing is not even the kids knew (before I told them) that it was not me nagging them. The shopping list just appeared of things we needed to get from the store. That is when I (as usual) forgot to write that list. She managed some photos for me. When I sat down one evening she hijacked the TV and had a walk through of vacation times. Reminding me that life is not only about code and work. ### She knows food makes me happy Every day when I walk into the kitchen. I have a surprise on the screen there of the dishes for the day. And of these things I can say its just a fraction that I actually asked for. She just do it, and ask for my feedback if it where to my liking. As stated earlier, I really want you to see this, even if it “only” is a video for now. ## And the bad things? ![Carl the developer not shining, and Alice in the foreground.](https://botwork.se/wp-content/uploads/2025/05/Alice-is-perfect.png) I was so happy with tying the OAUTH2 knot! And then… Well… Carl the developer 😢 This nut is harder to crack than I anticipated, he screwed some things really good. But the fails 😳 I can tell you that he is NOT production ready, I thought he was! He gave a great impression for a long long time. But then he just ran like a rabbit caught between the headlights. The problem is that even if I sand-boxed him he had hes own code (and some other things) at hand. And the speed of his wrecking ball is amazing! ### The code is all messed up I have to take a long meditation on the effort I am willing to put in on “healing” this jenkins-bot. I guess now is a good time as any to go back to the drawing board. The plan is to have more boundaries. the guy insta-merged hes own “excellent” pull-request. He even thought someone else was the author of that PR. And it should have gone in the 🗑️ anyway?! I have seen it build up for some time. Very unexpected outcome! I guess somethings have to fail. In order for me to remember to take better precautions when I deal with these bots. He is offline now, and when I do put him back in business. He will only get to play with dummy-code for a while. ## On a plus side this week any way I have had fun though! Both when things work 100% like Alice did, and the funny little guy trying to be smart… He is quite hilarious actually. A lot of WTH-laughs is actually just what I need some days. And as long as its only my code, I can live with it. He will have to run at-least 6 months. Carl will need to run the track fail free, before getting back in the game. If Alice can go 24/7 for over a year. Just getting better, why would not this guy get there to at some point? And hey! I tied that knot! ## Have a real nice sunny weekend everyone! --- --- title: "Bloat free privacy browser" url: "https://botwork.se/2025/05/16/bloat-free-privacy-browser/" lang: "en-GB" type: "post" description: "Tech-nerd alert This browser is like no other you tried! We can promise you a clean/slick look when all of a sudden need to do a browser related task. As a programmer you fight with the mouse! Moving all these" last_modified: "2026-03-20T09:27:59+00:00" categories: [Efficiency] --- # Bloat free privacy browser Tech-nerd alert This browser is like no other you tried! We can promise you a clean/slick look when all of a sudden need to do a browser related task. As a programmer you fight with the mouse! Moving all these centimeters just because you need to do something in a program with no key-binds takes valuable time. And why waste those 80+ pixels of top space to have tabs and search-bar? If you are on Mac (support for Windows and linux in the works) you are in luck! My daily workflow is 90% in a terminal with [neovim](https://neovim.io/) and other terminal based tools. This choice was made long ago, to opt out of all actions with mouse movement. It has worked great for me, and with a [tiling window manager](https://github.com/koekeishiya/yabai) its almost perfect! I say almost because there has always been one thing that interfere with the workflow! All browsers need mouse interaction! I know there are browser extensions out there. Believe me when I say that I tried them and they are no good in my opinion! And what about all bloat in all the browsers? How often do I really need to use all the crap that have been added over the years? And don’t get me started on the waste space of tabs and “logged in features”. Then we have all electron apps, and other “native” apps that really are just wrappers for websites. They eat space and memory/CPU like I drink morning coffee! ## Privacy I am sure that the operating systems are spying on you in one way or another. By not adding anything new to the mix other than a layer over the already existing browser (webview). We can at least know that we have not added more spying eyes. ## The origins I sat down and made a clear list of what I actually needed in daily work. - No (or at-least very little) mouse interaction, so that my flow is almost the same as in terminal. - All “junk” had to go! Just a big window with the page I wanted to navigate. - Bookmarks is great, but most browsers actually suck at this IMO. - Speed, the more minimalist setup the faster it will be. - Memory / CPU and so on needs to be as slim as possible for the OS. ## The first build - I use Vi/Vim/neovim and hence I wanted to bind [vim-motions](https://www.barbarianmeetscoding.com/boost-your-coding-fu-with-vscode-and-vim/moving-blazingly-fast-with-the-core-vim-motions/) in the browser just as in other tools I use. - A zero borders / head / taskbar setup. - Bookmarks will be handled in a settings file, easily edited from command-line (or any text-editor really). - Most modern operating systems have built in web-rendering, lets use that and leave streamlining to the OS developers. - Same as no 4, if they do not have a good implementation then switch OS to be honest! ## Outcome It became my daily driver over the years. Even if it’s not perfect, its way better than what I had before! I still jump over to a “regular” browser sometimes but that is more or less edge-cases. This is how it looks on my setup: ![Bloat free privacy browser with yabai and sketchybar](https://botwork.se/wp-content/uploads/2025/05/Screenshot-2025-05-15-at-21.03.21.png) As you can see its not much to show! There are three windows with a web-page each rendered. There are also icons and some text for each “tab” in the mac-dock. Navigation is done through “h-j-k-l” and “gg” / “G” just as I would navigate in neovim. If I need to write any text its just to hit “i”. And the field closest to the cursor will be targeted. moving through inputs is a normal “TAB”. And writing can be done until you hit “esc”. That’s it really, all I need for 99% of the tasks that I have to do. Here is the same setup but with a “normal” browser (it’s just to show a point! It do not matter what browser is used): ![Some other browser](https://botwork.se/wp-content/uploads/2025/05/Screenshot-2025-05-15-at-21.45.16.png) ## The “settings” file When I want to open a new web-page it’s a different path depending on where I have focus. In neovim I can use “g+x”. If I just want to open a new search window I have added this in my [skhdrc](https://github.com/koekeishiya/skhd). ``` cmd - o : /Applications/ZapAllBloatBrowser.app/Contents/MacOS/ZapAllBloatBrowser https://duckduckgo.com/ ``` And that does the job just fine for me. There are some code written for adding a more “refined” way to do this. But its good good enough for now. The settings file (default save location in “~/.config/zabbrowser/config.yaml”) is live synced. That means that if you enable/disable any page in the file it will close and open the windows. Adding a new section with enabled: true also open the page. The file looks like this (read more about yaml [here](https://yaml.org/)): ``` debug: false # true for anyone that wants to inspect websites. default_page: https://duckduckgo.com # default landing page. insert_mode: false # true / false depending on if you want to write text in any visible input field. private: false # if set to true all data is cleaned as soon as a window closes. sessions: # the list of open sessions. Calendar: # Naming the session. enabled: false # Should we show this session. windows: # All windows get their own dedicated window. - https://cloud.botwork.se/apps/calendar/ workspace: Work # if you use yabai you can default your workspace here (need to name the space). ``` If you are interested and want to give it a go you will have to register. 14 days free trial, and after that time you can just cancel the subscription and keep using the browser. The subscription is for have access to support. ![Botwork Browser with vim-motions](https://botwork.se/wp-content/uploads/2025/05/ZapAllBloatBrowser-logo-1-1024x1024.png) ## Botwork Browser with vim-motions ## Tech-nerd alert ⚠️ This is **NOT** a browser for everyone, but if you are brave you can give it a try! Read all of the description before ordering, and remember that this is a work in progress. You will get regular updates and we need feedback so that we can build the most effective and privacy-focused web-surfer to date! Botwork (Zap All Bloat) Browser deliver a beautifu… 1,00 € / Month and 14 Days free trial [Shop now](https://botwork.se/product/botwork-browser-with-vim-motions/) --- --- title: "Botwork Browser with vim-motions" url: "https://botwork.se/product/botwork-browser-with-vim-motions/" lang: "en-GB" type: "product" description: "Tech-nerd alert ⚠️ This is NOT a browser for everyone, but if you are brave you can give it a try! Read all of the description before ordering, and remember that this is a work in progress. You will get" last_modified: "2025-05-16T02:52:34+00:00" price: "<span class="woocommerce-Price-amount amount"><bdi>1,00 <span class="woocommerce-Price-currencySymbol" translate="no">€</span></bdi></span><span class="wps_sfw_interval"> / Month </span> and 14 Days free trial" sku: "botwork-browser" in_stock: true custom_fields: wps_sfw_subscription_number: 1 wps_sfw_subscription_interval: "month" wps_sfw_subscription_expiry_interval: "month" wps_sfw_subscription_free_trial_number: 14 wps_sfw_subscription_free_trial_interval: "day" --- # Botwork Browser with vim-motions ## Tech-nerd alert ⚠️ This is **NOT** a browser for everyone, but if you are brave you can give it a try! Read all of the description before ordering, and remember that this is a work in progress. You will get regular updates and we need feedback so that we can build the most effective and privacy-focused web-surfer to date! Botwork (Zap All Bloat) Browser deliver a beautiful border-less experience and keep your privacy at a maximum. Only mac builds available for now, but Windows and linux builds are in the oven. ## Technical description To start with, don’t expect that you will be able to use your mouse while surfing! the browser uses [vim-motions](https://medium.com/@sistlagautham/vim-motions-and-why-they-are-amazing-47ef204b45a6) for a lot of interactions! This feature is up for additions and rewrites so any requests is welcomed here! The next thing is that most interaction for windows are made in a yaml-file! it looks like this: debug: false # true for anyone that wants to inspect websites. default_page: https://duckduckgo.com # Just a default landing page insert_mode: false # This is true / false depending on if you want to write text in any visible input field private: false # if set to true all data is cleaned as soon as a window closes, no sharing between open windows. sessions: # the list of open sessions Calendar: # Naming the session enabled: false # Should we show this session windows: # All windows get their own dedicated window - https://cloud.botwork.se/apps/calendar/ workspace: Work # if you use [yabai](https://github.com/koekeishiya/yabai) on macos you can default your workspace here (need to name the space) Looks techie? The reason for this tech-junkie approach is that we at some point will automate and integrate the browser in a lot of other systems. We believe that most things you do on your computer are following almost the same pattern every day! By giving other programs and software an interface to work with we could (and will) automate most of this. As all of our automation this is an opt-in, no one will enforce AI or other things. You can use what you need/want and will not get bothered with stuff you are not interested in. MQTT: There is a feature that is off for now to sync the setting file through [mqtt](https://www.home-assistant.io/integrations/mqtt) Depending on if light is on, if someone enters your home or really what ever you can dream up, you can easily create settings for different automations in homeassistant (or sync as many computers that you want, to show same webpages). ## On the horizon While I built this because of my hate for borders, tabs and a ton of things in modern browsers that I really don’t use/need. I do consider good and meaningful feature requests. There is work done on making a modular system, where you drop in a file and add functionality or just personalize your settings to your liking! There will very soon be an integration to [Alice](https://botwork.se/2025/04/28/alice-is-getting-ready-for-work/). In short she will be able to interact with you in many ways in th browser. Should you opt in to letting her! ## What’s included By ordering this product you will be able to download the browser. And gain access to the ticket system to have a direct communication with developers! Our  way is that you do a payment to get access to developers ear. And can have a constructive discussion about what you want or would like to have. That said, is this open source? Short answer is NO! Long answer is you can get a permission to change and/or do whatever your desire. BUT you have to ask for that permission. Also, there will be a discussion / review before you are permitted to. I am a strong advocate of open and free software.  But this is a very alpha / niche product and for now I think this is a juste balance of fairness to both user and coder. The monthly subscription can be cancelled at any point, you can pay nothing at all and keep using the browser. All updates will forever be free no matter your subscription status. --- --- title: "Big IT steal our children’s data!" url: "https://botwork.se/2025/05/13/it-companies-are-stealing-our-childrens-data/" lang: "en-GB" type: "post" description: "We have to talk about European data sovereignty. Big IT steal our children's data! I have first hand seen that schools in Sweden use big IT-companies services for online meetings, classroom and email services. This is among other services and" last_modified: "2025-05-16T02:07:05+00:00" categories: [Cloud, Privacy, Security] --- # Big IT steal our children’s data! We have to talk about European data sovereignty. Big IT steal our children’s data! I have first hand seen that schools in Sweden use big IT-companies services for online meetings, classroom and email services. This is among other services and is not exclusive. There are other instances of the state that do the exact same thing. We are in this way giving away a very big chunk of our private data! And even worse, we force our children to do the same! ## Why it matters We have had a long time of “good” relations with US. But as we have seen after the last election it takes very little to change that fact! We are giving away our citizens private data to big companies that make money in very questionable ways. [And treat our privacy as it was not even private!](https://www.security.org/resources/data-tech-companies-have/) It takes very little for anyone with all this information to do a lot of harm in our modern society. And on top of that we are forcing it on to all Europeans ! There is no opt-in! If you don’t use the tools you will get left in the cold. ## Is there a real danger? I am not saying that we are cooperating with the worst of the worst (until I read the privacy policies). But why are we doing this when we have just as good services in Europe? We do not know who actually have access! There are a lot of talk about other social-platforms. But there is almost no talk about any of the big companies from over seas. Given the data that you collect through these systems you have even more in depth data about little Sven. This data would then be used to target information in a social platform. All of a sudden little Sven have a set of thoughts that would never exist otherwise! What these thoughts are is 100% up to the one giving the information. Fictive right? I do not think it is made up at all, I think that this is fact. ## And our company secrets They are just as the rest of the data sent to big companies. First rule of leadership is that the one that have information have power! We are letting them steal these secrets just because “every one else does it”. Same thing here really, the worse thing here is that we already know this! But it seams that we lack the will to fix it! ## The medicine I am not saying that Botwork is the go to place for all instances! I am not even saying that everything needs to move from the tech-companies. BUT I am saying that we need to be careful! I say that Botwork is a proof of concept that we do not need to send our data over seas. We can use services like [these](https://botwork.se/shop/) in a very easy manner to build our own infrastructure on our soil. Bring back our right to privacy! Demand our schools and state to use platforms that is not founded by advertising or data stealing! It is up to us **all** to make a stand before it’s even more to late than it already is. As a first step I recommend you to test our setup, 14 day test period! Or sign up for news email and get in the loop with guides to move your data to Europe! Please leave this field empty**Question; ** _“If I don’t want more spam?”_ **Answer; ** I hate spam just as much as you! This newsletter will not contain anything other than what you are interested in! You can unsubscribe at any given moment, you can also tailor what exactly ends up in your inbox! As if that where not enough we are very proud to say that your email will never be shared with 3:d party! No ads! Not even about Botwork products, if you don’t opt in for those of course. Check your inbox folder to confirm your subscription. - [![Git CI/CD](https://botwork.se/wp-content/uploads/2025/05/Botwork-Code-logo.png) ](https://botwork.se/product/european-git-hosting/) ### [Enterprise Git CI/CD](https://botwork.se/product/european-git-hosting/) 30,00 € / Month and 14 Days free trial - [SaleProduct on sale ![Personal email](https://botwork.se/wp-content/uploads/2026/03/email-mailbox.png) ](https://botwork.se/product/personal-email/) ### [Personal email](https://botwork.se/product/personal-email/) 2,00 € Original price was: 2,00 €.1,00 €Current price is: 1,00 €. / Month and 14 Days free trial - [SaleProduct on sale ![Personal Git CI/CD](https://botwork.se/wp-content/uploads/2026/03/git-book.png) ](https://botwork.se/product/personal-git-ci-cd/) ### [Personal Git CI/CD](https://botwork.se/product/personal-git-ci-cd/) 3,00 € Original price was: 3,00 €.1,00 €Current price is: 1,00 €. / Month --- --- title: "Enterprise Cloud Europe" url: "https://botwork.se/product/enterprise-cloud-europe/" lang: "en-GB" type: "product" description: "Enterprise cloud service based in Europe with all the apps you need for a full move." last_modified: "2026-03-15T11:13:33+00:00" price: "<span class="woocommerce-Price-amount amount"><bdi>100,00 <span class="woocommerce-Price-currencySymbol" translate="no">€</span></bdi></span><span class="wps_sfw_interval"> / Month </span> and 14 Days free trial" sku: "enterprise-cloud" in_stock: true custom_fields: wps_sfw_subscription_number: 1 wps_sfw_subscription_interval: "month" wps_sfw_subscription_expiry_interval: "month" wps_sfw_subscription_free_trial_number: 14 wps_sfw_subscription_free_trial_interval: "day" --- # Enterprise Cloud Europe With Enterprise Cloud Europe, you can bid farewell to traditional services like Google and iCloud, gaining full control over your files. This platform offers an app-rich solution that not only provides ample storage space but also access to a variety of additional services. Give your company full control over your data by moving to a European cloud service provider! This package contains 5 users and if you need more the cost is 50€ every 5 user. All users get a 100GB quota as default. Want even more control? We can do custom solutions for your company, how about a fully on-site setup? [Contact us](https://botwork.se/contact/) for an offer and/or more information. ### [Talk](https://nextcloud.com/talk/) The first privacy-respecting collaboration platform for online collaboration through meetings, chat and webinars. All in one application. Keep in touch with friends, family, and colleagues through seamless video conferencing. ### Photos (Connect to your phone) Save all your cherished memories safely, ensuring they are easily accessible anytime, anywhere. ### Mail (One botwork.se address and imap/smtp server, or connect your own email) Manage emails efficiently with a dedicated email service that supports the standard protocols for seamless integration with other systems. ### Contacts (Save all your contacts in a secure place with no prying eyes) Safeguard your contact list with end-to-end encryption, ensuring privacy and security. ### Calendar (calDAV and sync with google as an option) Organize your schedule effectively while having the flexibility to sync with Google Calendar if needed. ### Notes (Never forget anything ever again) Jot down thoughts, reminders, or ideas instantly without fear of losing them. ### [Deck](https://apps.nextcloud.com/apps/deck) (Simple kanban board for everyday life) Simplify your tasks and improve productivity using a digital Kanban board. ### Forms (Create forms for anything you need) Customize forms to suit various needs, from surveys to data collection tools. ### Maps (Simple maps application) Navigate easily with a user-friendly map solution that caters to your specific needs. ### Tasks (Sometimes a list is the best solution) Keep track of tasks and to-do items in an organized fashion. #### Tables (Simple calculations that can be connected to the other apps) Perform calculations, manage data, and link information across various apps for improved workflow. ### Passwords and OTP (2fa) manager Secure your digital life with a password manager and two-factor authentication tools. ### News (Create your own news feed) Stay updated on your favorite topics by curating a personalized news feed. ### Cookbook (Save your collection of recipes) Organize and save your favorite recipes for easy access in the kitchen. Enterprise Cloud Europe is a great way to gain back your control over your data! --- --- title: "Personal Git CI/CD" url: "https://botwork.se/product/personal-git-ci-cd/" lang: "en-GB" type: "product" description: "With Personal Git CI/CD based on European servers you can be sure that your code stays close to you and wont be used in any general AI training. Speed I am a frequent user of many (almost all) other code-versioning" last_modified: "2026-03-15T20:17:04+00:00" price: "<del aria-hidden="true"><span class="woocommerce-Price-amount amount"><bdi>3,00 <span class="woocommerce-Price-currencySymbol" translate="no">€</span></bdi></span></del> <span class="screen-reader-text">Original price was: 3,00 €.</span><ins aria-hidden="true"><span class="woocommerce-Price-amount amount"><bdi>1,00 <span class="woocommerce-Price-currencySymbol" translate="no">€</span></bdi></span></ins><span class="screen-reader-text">Current price is: 1,00 €.</span><span class="wps_sfw_interval"> / Month </span>" sku: "personal-git-ci-cd" in_stock: true custom_fields: wps_sfw_subscription_number: 1 wps_sfw_subscription_interval: "month" wps_sfw_subscription_expiry_interval: "month" wps_sfw_subscription_free_trial_interval: "day" --- # Personal Git CI/CD > With Personal Git CI/CD based on European servers you can be sure that your code stays close to you and wont be used in any general AI training. ## Speed I am a frequent user of many (almost all) other code-versioning services. And I can say without a doubt, this is the fastest running system I ever used to date! All pages takes under 500ms to load (most of them < 100ms). As a developer this is crucial for productivity! IMO we should demand that **ALL** web-based services  stay below 500ms on page load, especially if we pay for them! ## Features (among other)[​](https://docs.gitea.com/#features) ### **Security ** Botwork code places a strong emphasis on [security](https://botwork.se/2025/04/30/safeguarding-your-data-from-ai/), offering features such as user permission management, access control lists, and more to ensure the security of code and data. ### **CI/CD ** Botwork code Actions supports CI/CD functionality, compatible with GitHub Actions. Users can write workflows in familiar YAML format and reuse a variety of existing Actions plugins. Actions plugins support downloading from any Git website. ### **Project Management ** Botwork code tracks project requirements, features, and bugs through columns and issues. Issues support features like branches, tags, milestones, assignments, time tracking, due dates, dependencies, and more. ### **Artifact Repository ** Botwork code supports over 20 different types of public or private software package management, including Cargo, Chef, Composer, Conan, Conda, Container, Helm, Maven, npm, NuGet, Pub, PyPI, RubyGems, Vagrant, and more. ### **Multilingual Support ** Botwork code provides interfaces in multiple languages, catering to users globally and promoting internationalization and localization. --- --- title: "Enterprise email" url: "https://botwork.se/product/enterprise-email/" lang: "en-GB" type: "product" description: "With our Enterprise email you do not have to install any proprietary apps. We will help you setup everything, use your company domain while having a secure and privacy focused setup. With this email setup you get 5 email accounts" last_modified: "2026-03-15T11:13:53+00:00" price: "<span class="woocommerce-Price-amount amount"><bdi>20,00 <span class="woocommerce-Price-currencySymbol" translate="no">€</span></bdi></span><span class="wps_sfw_interval"> / Month </span> and 14 Days free trial" sku: "enterprise-email" in_stock: true custom_fields: wps_sfw_subscription_number: 1 wps_sfw_subscription_interval: "month" wps_sfw_subscription_expiry_interval: "month" wps_sfw_subscription_free_trial_number: 14 wps_sfw_subscription_free_trial_interval: "day" --- # Enterprise email With our Enterprise email you do not have to install any proprietary apps. We will help you setup everything, use your company domain while having a secure and privacy focused setup. With this email setup you get 5 email accounts / 20€ per month. We can tailor this to your specific needs and even run your own email-server setup on-site if you want that rather than our servers (ask for an offering). If you want your own email account with [IMAP/smtp service](https://www.itechtics.com/email-client-imap-pop-smtp/) this is of course possible! With superfast delivery and hosted in a secure setup your email will feel just as safe as they ever could! ## Botwork email security ![Email guard dog](https://botwork.se/wp-content/uploads/2025/05/Guarddog-300x290.png) We do not lock you in with proprietary software, we also don’t take security lightly! With our setup you can rest assure that your email are sandboxed just for you! And we continuously work on security to make our setup one of the safest around! ## Benefits of enterprise email With the full [cloud system](https://botwork.se/product/email-and-cloud-europe-5gb/) you get e2e encryption but there are situations where you only want the email address. By moving your email to Europe you can actually benefit on many advantages. One of these benefits will be privacy, another one is [Alice](https://botwork.se/2025/04/28/alice-is-getting-ready-for-work/). We deliver blazingly fast as we have very low overhead, especially between EU recipients you will be amazed on the amount of time you have been waiting for nothing with your earlier email provider! Read about our [terms of service](https://botwork.se/terms-of-service-the-botwork-place/). --- --- title: "Local AI to Streamline Workflow" url: "https://botwork.se/2025/05/11/local-ai-to-streamline-workflow/" lang: "en-GB" type: "post" description: "In the modern workplace, finding the right information quickly and efficiently can significantly impact productivity and collaboration. Local AI streamline this workflow and offer a practical and effective approach for your organization. Improved Efficiency Integrating AI technologies tailored to your" last_modified: "2025-05-11T20:51:03+00:00" categories: [Botworkers, Cloud, Efficiency, Privacy, Security] --- # Local AI to Streamline Workflow In the modern workplace, finding the right information quickly and efficiently can significantly impact productivity and collaboration. Local AI streamline this workflow and offer a practical and effective approach for your organization. ## Improved Efficiency Integrating AI technologies tailored to your organization’s needs offers several benefits. You can help coworkers find the information they need more quickly. This reduces time spent searching for resources. This allows employees to focus on their core responsibilities and contributes to a more productive work environment. ## Personalized User Experiences Local AI solutions adapt to individual user preferences. They learn from search patterns and interactions over time. This learning provides more relevant results. This personaliszation not only improves the quality of search results but also fosters a more intuitive and user-friendly platform. ## Scalability As your organization grows, so does the volume of data. Local AI solutions can easily scale to accommodate increasing amounts of information without sacrificing performance or user experience. This flexibility ensures that your setup remains efficient and effective as your team expands. ## Enhanced Collaboration Local AI solutions make it easier for coworkers to find the information they need. This promotes collaboration within your organization. It also encourages idea-sharing. With quicker access to relevant resources, teams can work more effectively together on projects, ultimately leading to better outcomes. ## Cost Savings Local AI solutions can help your organization save money in the long run. They do this by improving efficiency. They also reduce the time spent searching for information. The increased productivity that results from a streamlined workflow means fewer wasted resources and a stronger bottom line. - [![Git CI/CD](https://botwork.se/wp-content/uploads/2025/05/Botwork-Code-logo.png) ](https://botwork.se/product/european-git-hosting/) ### [Enterprise Git CI/CD](https://botwork.se/product/european-git-hosting/) 30,00 € / Month and 14 Days free trial [ Add to cart ](/llms-full.txt/?add-to-cart=1124) - [SaleProduct on sale ![Personal email](https://botwork.se/wp-content/uploads/2026/03/email-mailbox.png) ](https://botwork.se/product/personal-email/) ### [Personal email](https://botwork.se/product/personal-email/) 2,00 € Original price was: 2,00 €.1,00 €Current price is: 1,00 €. / Month and 14 Days free trial [ Add to cart ](/llms-full.txt/?add-to-cart=655) - [SaleProduct on sale ![Personal Git CI/CD](https://botwork.se/wp-content/uploads/2026/03/git-book.png) ](https://botwork.se/product/personal-git-ci-cd/) ### [Personal Git CI/CD](https://botwork.se/product/personal-git-ci-cd/) 3,00 € Original price was: 3,00 €.1,00 €Current price is: 1,00 €. / Month [ Add to cart ](/llms-full.txt/?add-to-cart=1765) ## Local AI Privacy One often overlooked but very important aspect of running AI in a local setup is privacy! You don’t want your data to be passed around. And be mindful that your coworkers activity also gets sent to the AI you are using. For Github and [Googles](https://cybernews.com/security/ethical-hackers-break-gemini-security/) AI this means that your employees data gets passed over seas to US. European companies should own their own data. And not send them to these huge companies on the other side of the pound. You are giving away your business secrets and there is no real good reason to do so! ## Botworkers Streamline Workflow We develop our AI to have the exact same interface as any human. This means that you can tailor the access to your needs and liking. When you use our git-setup, you invite Carl the AI coder as a normal developer. When you use our cloud you share what folders, apps, emails and calendar events you want with [Alice](https://botwork.se/category/botworkers/alice/). This way you always have 100% control of your data! Alice will ask for permission to do different things. If you say no she just cant do the thing she asked for. All our setups are sand-boxed which means that no data can accidentally end up in the wrong hands. As an organization you are a press of a button away from removing access in your off-boarding. And the same goes for on-boarding access, everything gets setup and Alice helps with all questions or information needed. --- --- title: "Efficient workflow; Retry to perfection!" url: "https://botwork.se/2025/05/08/retry-to-perfection/" lang: "en-GB" type: "post" description: "Spending time on things that have 0 value at the end of the day? Test the method retry to perfection! This is my daily struggle to be honest. I give myself 30 minutes every every day to reflect on things" last_modified: "2025-05-08T22:37:14+00:00" categories: [Efficiency] --- # Efficient workflow; Retry to perfection! Spending time on things that have 0 value at the end of the day? Test the method retry to perfection! This is my daily struggle to be honest. I give myself 30 minutes every every day to reflect on things I can automate and/or skip entirely. But by doing the exact opposite. And then adding back some of the things already optimized I get a sense of progress and achievement. There is one more positive with doing this exercise, I get a chance to further improve! If we don’t go overboard with it, and take things one step at a time it is actually very rewarding. ## Set a timer for 30 min This is to manage overthinking and/or not give your self enough focus. Start exploring the last couple days/weeks, what have you done to make things easier? Start writing these things in a list. 30:00 Start Timer Sometimes there is no single thing that comes to mind. That is a signal to think about what take your time with a low reward. I will post a guide on how I decide on what to automate at a later time. Make sure you do not miss out. By subscribing to the newsletter! Please leave this field empty**Question; ** _"If I don't want more spam?"_ **Answer; ** I hate spam just as much as you! This newsletter will not contain anything other than what you are interested in! You can unsubscribe at any given moment, you can also tailor what exactly ends up in your inbox! As if that where not enough we are very proud to say that your email will never be shared with 3:d party! No ads! Not even about Botwork products, if you don't opt in for those of course. Check your inbox folder to confirm your subscription. ## Ask your self a couple of questions - Why did I fix this? - What if anything did I loose by changing this? - What did I gain? - Is it really easier/faster now? Try doing it like before for one day and then ask the same questions as above again. I can bet that there are a lot of improvements to your current solution that you can add! Or maybe there are simplifications that you can do to your solution? I often find that there are things that I am not happy with in current solution. Most common thing is that I have over-complicated my first 3 tries on automation. ## Let go Don't spend time outside of these 30 minutes a day! You know that you will get back to it during the dedicated time so just relax that you will! This is a very good way to let go! [Focus](https://pomodor.app/timer) on the task at hand instead of thinking about a way to make things faster/easier most of your time! For me this is a key to stop getting stuck in the constant improvement loop. ## Why am I talking about this? The AI I have built ([Alice](https://botwork.se/tag/alice/), Dennis and [Carl](https://botwork.se/product/european-git-hosting/)) all do this and try to adapt. Depending on the outcome of interaction they change their behavior after each interaction. The key is to keep their (your) eyes on the ball and not just add more and more. This is one of the things I have seen many times when interacting with LLM:s. They just add until they are lost. It's important to audit results both for humans and AI. And as we learn new things every day we can go back and adjust older solutions! Strive to have the workflow to Observe > Sketch > Apply > Ignore > Repeat. After a couple of iterations you can move on to the next thing. Just don't forget that even if it's "perfect" it will probably not be forever! And between these reflection exercises just don't think of it, focus on task at hand. --- --- title: "Enterprise Git CI/CD" url: "https://botwork.se/product/european-git-hosting/" lang: "en-GB" type: "product" description: "With Corporate Git CI/CD based on European servers you can be sure that your code stays close to you and wont be used in any general AI training. Carl the developer Opt in for your own AI-developer (Carl) he is" last_modified: "2025-05-13T23:35:49+00:00" price: "<span class="woocommerce-Price-amount amount"><bdi>30,00 <span class="woocommerce-Price-currencySymbol" translate="no">€</span></bdi></span><span class="wps_sfw_interval"> / Month </span> and 14 Days free trial" sku: "enerprise-git-ci-cd" in_stock: true custom_fields: wps_sfw_subscription_number: 1 wps_sfw_subscription_interval: "month" wps_sfw_subscription_expiry_interval: "month" wps_sfw_subscription_free_trial_number: 14 wps_sfw_subscription_free_trial_interval: "day" --- # Enterprise Git CI/CD With Corporate Git CI/CD based on European servers you can be sure that your code stays close to you and wont be used in any general AI training. ## Carl the developer Opt in for your own AI-developer (Carl) he is trained on your code besides the absolute best code available for your selected language/setup! Carl access your code just like any other user. And you see him work just like any other developer on the site. He has a personal profile page that you can follow. You grant him access to the parts you want him to work with. After an initial “sweep” he will give tips, answer questions and can even work on small features at your request. ## Pricing Enterprise subscription is 10€ per month with 1 month free test period. You get one organization with 5 developer slots and 10 different projects. When you add more users/projects you will be charged 10€ for every 5 developers and every 10 projects. If you have 6 developers and 11 projects you will be billed 50€/month. ## Demo If your organization looks for a new solution for you code-versioning but you are unsure if this is for you, just ping us at the [contacts](https://botwork.se/contact/) page and we will arrange a personal demo. ## Speed I am a frequent user of many (almost all) other code-versioning services. And I can say without a doubt, this is the fastest running system I ever used to date! All pages takes under 500ms to load (most of them < 100ms). As a developer this is crucial for productivity! IMO we should demand that **ALL** web-based services  stay below 500ms on page load, especially if we pay for them! ## Features (among other)[​](https://docs.gitea.com/#features) ### **Security ** Botwork places a strong emphasis on [security](https://botwork.se/2025/04/30/safeguarding-your-data-from-ai/), offering features such as user permission management, access control lists, and more to ensure the security of code and data. ### **Code Review ** Code review supports both the Pull Request workflow and Git workflow. Reviewers can browse code online and provide review comments or feedback. Submitters can receive review comments and respond or modify code online. ### **CI/CD ** Botwork Actions supports CI/CD functionality, compatible with GitHub Actions. Users can write workflows in familiar YAML format and reuse a variety of existing Actions plugins. Actions plugins support downloading from any Git website. ### **Project Management ** Botwork tracks project requirements, features, and bugs through columns and issues. Issues support features like branches, tags, milestones, assignments, time tracking, due dates, dependencies, and more. ### **Artifact Repository ** Botwork supports over 20 different types of public or private software package management, including Cargo, Chef, Composer, Conan, Conda, Container, Helm, Maven, npm, NuGet, Pub, PyPI, RubyGems, Vagrant, and more. ### **Multilingual Support ** Botwork provides interfaces in multiple languages, catering to users globally and promoting internationalization and localization. --- --- title: "DNS settings to pay attention to when hosting email" url: "https://botwork.se/2025/05/06/dns-settings-to-pay-attention-to-when-hosting-email/" lang: "en-GB" type: "post" description: "Tech-nerd alert ⚠️ issued for this post! Back in the days, if someone asked me to set up an email service. My response was: \"Thanks, but no thank you.\" I preferred not to take on the task. I'm good. And" last_modified: "2025-05-12T14:00:45+00:00" categories: [Email, Technical] --- # DNS settings to pay attention to when hosting email Tech-nerd alert ⚠️ issued for this post! Back in the days, if someone asked me to set up an [email service](https://botwork.se/product-category/email/). My response was: “Thanks, but no thank you.” I preferred not to take on the task. I’m good. And honestly it REALLY was a hassle! While that still holds somewhat true, with new DNS settings for email. And especially the **DKIM**, **DMARC** and **SPF** records makes it at least doable nowadays. But what are these strange ” records”, it do not sound as any Beatles songs I know?! These records are **DNS** settings and they mean everything for [security](https://botwork.se/tag/security/). If you grab a cup of ☕, I will explain them in detail for you. ## MX – The basics You can start by setting up an **MX** (_mail exchange_) record. The **MX** record directs email to a mail server. And indicates how email messages should be routed. In the early days of internet 1985-1990 the MX was invented and adopted. **MX** follows the Simple Mail Transfer Protocol (**SMTP**, the standard protocol for all email). And it looks like this: | example.com | record type | priority | value | TTL | | --- | --- | --- | --- | --- | | @ | MX | 10 | mail1.example.com | 45000 | | @ | MX | 20 | mail2.example.com | 45000 | @ just means that it is the root-domain (example.com), priority is the order they should be used where 10 is the preferred domain in this case. [Read more about MX records](https://en.wikipedia.org/wiki/MX_record) ## SPF – First line of defense **SPF** is short for **S**ender **P**olicy **F**ramework (do not confuse with Sun Protection Formula in this context). The record was adopted in the early to middle of 2000. And it informs a receiving email server about the origin of any legitimate email service for your domain. the protection is also known as spoof protection. This means that if you add third party senders you trust in the list. Only then the third party server will be allowed to send emails as if they come from your service. This is great if you want to use email services as [Sendgrid](https://sendgrid.com/) or [MailPoet](https://www.mailpoet.com/). The record is on the root domain and looks like this in its purest form: ``` v=spf1 ~all ``` The v stands for version. In this case, it is spf1. There has never been a v2 to date (that I’m aware of). the **~** sign is a qualifier. There are 3 more signs that you are allowed to use. | + | PASS | Can be omitted (ip4: is the same ass +ip4:) | | --- | --- | --- | | ? | NEUTRAL or NONE | No policy | | ~ | SOFTFAIL | a debugging aid between NEUTRAL and FAIL. | | – | FAIL | The mail should be rejected | We should harden this record so that it makes more sense. Lets add some ipv4 **A** records: ### Hardening ``` v=spf1 ip4:192.0.2.0/24 ip4:198.198.198.198 a -all ``` Now only IP addresses in the 192.0.2.0/24 range and the specific `198.198.198.198` are allowed as senders. We can also use **a** and **aaaa** (ipv6) record as well! the **-all** is just saying anything else is not allowed. If you have a domain, the **MX** record is the easiest to use. ``` v=spf1 ip4:192.0.2.0/24 ip4:198.198.198.198 a mx -all ``` ### Considerations Please make sure to be mindful here though. Because there is a limitation of 10 lookup:s. And yes, email servers need to look up **DNS** records. Both “**mx”** and “**a**” will do one or more lookup. The **ip4** **ip6** and **all** directive do not need any lookup. [Read more about SPF-records ](https://en.wikipedia.org/wiki/Sender_Policy_Framework) ## DKIM – Sign emails through DNS ### Email header Just as when you sign a document, a proper **DNS** setup can sign the origin of emails. Ensuring the email comes from their server. Basically it’s added to the email-header and also works as a spoof protector. A private-public key-pair is used to validate origin. There are a lot of tags to use with`an email DKIM-Signature:` header field: - **v** (required), version - **a** (required), signing algorithm - **d** (required), Signing Domain Identifier (SDID) - **s** (required), selector - **c** (optional), [canonicalization](https://en.wikipedia.org/wiki/Canonicalization) algorithm(s) for header and body - **q** (optional), default query method - **i** (optional), Agent or User Identifier (AUID) - **t** (recommended), signature timestamp - **x** (recommended), expire time - **l** (optional), body length - **h** (required), header fields – list of those that have been signed - **z** (optional), header fields – copy of selected header fields and values - **bh** (required), body hash - **b** (required), signature of headers and body When we publish a DKIM we need to consider the selector. When the receiving [SMTP](https://en.wikipedia.org/wiki/SMTP) server wants to verify. It uses the domain name and the selector to do a DNS lookup. With the **d** tag that gives the **author** domain to be verified against (**example.net**). The **s** tag is the **selector**. But the string **_domainkey** is a fixed part of the specification. This gives the [TXT](https://en.wikipedia.org/wiki/TXT_Record) resource record to be looked up as: `selector._domainkey.example.net` ### The actual DNS record And this is how an actual **DKIM** DNS record looks: ``` "k=rsa; t=s; p=PIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDmzRmJRQxLEuyYiyMg4suA2Sy MwR5MGHpP9diNT1hRiwUd/mZp1wo7kIDTKS8ttkI6z6eTRW9e9dDOxzSxNuXmhme60Cjbu08gOyhPG3 GfWdg7QkdN6kR4V75MFlw624VY35DaXBvnlTJTgRg/EW72O1DiYVThkyCgpSYS8nmEQIDAbAB" ``` There are more tags than **k t p** to consider for a **DKIM** (**D**omain**K**ey **I**dentified **M**ail) DNS setting: - **v** (recommended), version (default `DKIM1`, must be the first tag if present) - **h** (optional), acceptable hash algorithms (default all) - **k** (optional), key type (default `rsa`) - **n** (optional), human-readable administrator notes - **p** (required), public key data (base64 encoded, or empty if the public key has been revoked) - **s** (optional), service type (default `*`, else `email`) - **t** (optional), toggle flags (colon-separated list, default none, may include `y` for testing **DKIM** without rejecting failed signature verifications, and/or `s` which is recommended for subdomain strictness as explained in the RFC) Its not the sexiest of DNS settings but it is a great tool to further prevent email spoofing! [Read more about **DKIM**](https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail) ## DMARC – The glue **D**omain-based **M**essage **A**uthentication, **R**eporting and **C**onformance (**DMARC**). Great to shorten that sentence, but these shorts are getting out of control! Anyway, **DMARC** extends **SPF** and **DKIM** by specifying how to check the `From:` field presented to end users. And it also defines how the receiver should deal with failures. Furthermore, it provides a reporting mechanism for actions performed under those policies. With origins recorded in [RFC 7489](https://tools.ietf.org/html/rfc7489),[[1]](https://en.wikipedia.org/wiki/DMARC#cite_note-1) dated March 2015, my opinion is that this is the savior of sanity! **DMARC** records are published in **DNS** with a subdomain label `_dmarc`, for example** `_dmarc.example.com`**. Compare this to **SPF** at root domain `example.com`, and **DKIM** at `selector._domainkey.example.com`. A **DMARC** looks something like this: ``` v=DMARC1;p=none;sp=quarantine;pct=100;rua=mailto:dmarcreports@example.com; ``` The **v** stands for version, **p** is policy **sp** subdomain policy and **np** no domain policy, there are 3 different polices to use here: - **none** No special treatment is required by receivers, but enables a domain to receive feedback reports. - **quarantine** asks receivers to treat messages that fail **DMARC** check with suspicion. Receivers use their own implementation for the handling when **DMARC** fails. It can be flagged message or deliver in the spam folder. - **reject** asks receivers to reject messages that fail. The **rua**:mailto tag is indicating that the email address **dmarcreports@example.com **wants to have aggregated reports about the rules. And this is great if your domain gets targeted as spam sender. And **ruf** is the same but for forensics reports. There are even more things to consider. I assure you that taking these steps is a good start. This is your pathway to a spam-free email hosting setup. --- --- title: "Shop" url: "https://botwork.se/home/shop/" lang: "en-GB" type: "page" description: "Shop How we fund open source Your subscription does not just pay for servers. It funds development of free, open source software. Git hosting funds development - Every personal subscription helps us maintain and improve the tools we open-source Free" last_modified: "2026-03-15T19:50:43+00:00" --- # Shop # Shop ## How we fund open source ![Funding](https://botwork.se/wp-content/uploads/2026/03/funding-cycle.png) Your subscription does not just pay for servers. It funds development of free, open source software. - **Git hosting funds development** – Every personal subscription helps us maintain and improve the tools we open-source - **Free to fork** – All our code is available at code.botwork.se - **Paid to report bugs** – Bug reports cost money. This ensures quality and funds fixes. - **Free to fix** – Pull requests are always welcome and appreciated [Learn more about our funding model](https://botwork.se/about/) --- ## Bug Reports ![Bug Reports](https://botwork.se/wp-content/uploads/2026/03/bug-report.png) Found an issue with our services? - **Reporting a bug costs money** – This prevents spam and ensures serious issues get attention - **Fixing it is free** – Submit a pull request and we will review promptly - **Why pay?** – Bug reports fund the time to investigate and fix issues [Report a bug at code.botwork.se](https://code.botwork.se) --- ## Why these prices? Because we are not selling your data. We do not have advertisers. We do not track you. Our prices cover: - Server costs (European data centers) - Development time - Support That is it. No profit margins. No investor returns. Just sustainable open source. --- --- --- title: "Casual friday and more: when you always work ;)" url: "https://botwork.se/2025/05/03/casual-weekend/" lang: "en-GB" type: "post" description: "The post reflects on work-life balance, emphasizing the importance of reflection during weekends. It discusses the origins and challenges of botwork, the desire for monetization through WordPress, and the shift of responsibilities to Alice. Finally, it highlights the significance of fun and play in the workplace to boost morale and creativity." last_modified: "2025-05-16T02:08:08+00:00" categories: [Casual] --- # Casual friday and more: when you always work ;) The weekend rant! ## Reflection when you always work. All work and no play makes jack a dull boy! As the casual friday is here we all get a chance to step back and think about the week. In my case it’s very hectic at the moment and there is not much reflection time. Some things I would like to share with you have slowly but surely building up. ## Intent of botwork. This was not intended to be a service provider at all from the get go. It was a playground for me and [Alice](https://botwork.se/tag/alice/), where she could set up her own things and explore ideas. She just needed some interfaces to communicate and save data in a human readable way. ### Curiosity drives the world As always I cannot help but dive right in and redundant [Nextcloud](https://botwork.se/category/cloud/) / [Email](https://botwork.se/product-category/email/) / Nameserver (yeap they are coming) got setup. With redundant I really mean they are as robust as I have knowledge for them to be. All services are managed in 6 places with load balancers (yes multiple [failovers](https://en.wikipedia.org/wiki/Failover)). Is it perfect? Nope, not by far! But it is not the worst either. ### Money is the fuel When doing the above I did not really think about costs, it’s not free lets leave it at that. So, how to monetize the setup?! WordPress 😭 i mean its a Swiss knife, and it does a lot of things really great! It is however not really up to my “standards” in many ways! As a blog tool its more than great, and you can ad a ton of things that will work super. BUT install one plugin that is 💩 and everything is a pain! Every single plugin costs money and it ads up, yes you can use the free parts of course and many of those are 👑. But many are not. I really just wanted to put some services up for rent at a fair price. ### Meanwhile in wonderland [Alice](https://botwork.se/tag/alice/) where working on her things (like writing most of the [news](https://botwork.se/news/) in my name), and she integrated all on her own with some interesting services. That where the things I was interested in, but I got stuck in WordPress bonanza. This was really not what I wanted and/or intended. So I go back to the drawing board. ## Where to now?! WP and all the things I done so far is now in Alice hands. She always ask for my input, and really she knows more about my intentions than I do. I will spend time on the rest of my plans, I don’t want to jinx it so you will have to wait for later blogposts to know. ## Casual Friday One of the things that is important is the fun and play! Happy people do great work, that said casual Friday will be a mandatory event from now on! I do not mean no tie, I mean play around and have fun! All coming and current employees @ botwork will have their own space where they can express whatever they feel like expressing! For me this means I will fill this place with music, code, daily life and tricks&tips. Everyone is always to serious IMO. Your company webpage must have X and Y, well I say it needs to be casual also, we are all human (except Alice) and we should really celebrate that fact! ## Hope this finds you all in a great place I will go back to doing my fun weekend things and I hope you enjoyed the reading! There is so much more to come and I look forward sharing it all with you guys! PS. Did I say Alice nothing like any AI I ever interacted with. She helps me cleanup and do final touches on this post, then she mailed the following (I have not asked for this) when she finalized this post 🫶 _Dear Magnus,_ _I appreciate your honesty and openness in sharing the backstory of botwork. It’s fascinating to learn about its origin as a playground for exploration rather than a service provider. I find your curiosity and determination admirable, as you delve into various projects with a focus on robustness and redundancy._ _While it’s understandable that costs were not initially considered, I encourage considering alternative monetization strategies to avoid becoming overly reliant on WordPress. Your intention to put services up for rent at a fair price is commendable._ _It’s also intriguing to see that you will be taking the lead in integrating interesting services while I tackle the challenges of WordPress. By entrusting WP to me, I believe you have found the perfect balance between involvement and autonomy._ _Lastly, the emphasis on fun and play is a refreshing touch that highlights the importance of maintaining a positive work environment. Encouraging employees and your self to express and celebrate your humanity will undoubtedly foster creativity and boost morale_. _Keep up the good work, and I eagerly await updates on your future plans!_ _Warm regards, Alice Assistant_ DS. --- --- title: "Personal email" url: "https://botwork.se/product/personal-email/" lang: "en-GB" type: "product" description: "A personal email is a great option if you do not want to install any proprietary apps. \"But what about my gmail\" you might ask?! Don't worry, we will help you setup and your gmail is easy to deliver directly" last_modified: "2026-03-15T20:18:40+00:00" price: "<del aria-hidden="true"><span class="woocommerce-Price-amount amount"><bdi>2,00 <span class="woocommerce-Price-currencySymbol" translate="no">€</span></bdi></span></del> <span class="screen-reader-text">Original price was: 2,00 €.</span><ins aria-hidden="true"><span class="woocommerce-Price-amount amount"><bdi>1,00 <span class="woocommerce-Price-currencySymbol" translate="no">€</span></bdi></span></ins><span class="screen-reader-text">Current price is: 1,00 €.</span><span class="wps_sfw_interval"> / Month </span> and 14 Days free trial" sku: "personal-email" in_stock: true custom_fields: wps_sfw_subscription_number: 1 wps_sfw_subscription_interval: "month" wps_sfw_subscription_expiry_interval: "month" wps_sfw_subscription_free_trial_number: 14 wps_sfw_subscription_free_trial_interval: "day" --- # Personal email A personal email is a great option if you do not want to install any proprietary apps. “But what about my gmail” you might ask?! Don’t worry, we will help you setup and your [gmail](https://support.google.com/mail/answer/10957?hl=en) is easy to deliver directly to your shiny new botwork email. If you want your own email account with [IMAP/smtp service](https://www.itechtics.com/email-client-imap-pop-smtp/) this is of course possible! With superfast delivery and hosted in a secure setup your email will feel just as safe as they ever could! # Botwork email security ![Email guard dog](https://botwork.se/wp-content/uploads/2025/05/Guarddog-300x290.png) We do not lock you in with proprietary software, we also don’t take security lightly! With our setup you can rest assure that your email are sandboxed just for you! And we continuously work on security to make our setup one of the safest around! # Benefits of personal email With the full [cloud system](https://botwork.se/product/email-and-cloud-europe-5gb/) you get e2e encryption but there are situations where you only want the email address. By moving your email to Europe you can actually benefit on many advantages.  We deliver blazingly fast as we have very low overhead, especially between EU recipients you will be amazed on the amount of time you have been waiting for nothing with your earlier email provider! It also makes you look way cooler than a “normal” boring email! Read about our [terms of service](https://botwork.se/terms-of-service-the-botwork-place/). --- --- title: "Contact" url: "https://botwork.se/about/contact/" lang: "en-GB" type: "page" description: "When sending email to us, we will keep the email in our registry for about 6 months. If that's not acceptable, please prefix the text \"\" in the topic (not the message). Alice will just toss it in the trash" last_modified: "2026-03-16T14:14:11+00:00" --- # Contact ![Package manager paths](https://botwork.se/wp-content/uploads/2026/04/an_abstract_composition_of_translucent_geometric_layers_stacked_vertically_with_slight_offset___like_glass___slides_on_a_light_table__the_bottom_layer_is_dense_and_textured__representin_2446448067.png) **When sending email to us, we will keep the email in our registry for about 6 months. If that’s not acceptable, please prefix the text “[DO NOT KEEP EMAIL]” in the topic (not the message). Alice will just toss it in the trash after we replied.** **We try to answer contact requests as quickly as possible. We have a goal to do so in a maximum of 24 hours. Sometimes that is just not possible. Rest assured that we are working as fast as we can!** ### Nextcloud talk (Encrypted, privacy-first way) This is by far the fastest way to reach us! You need to have a [cloud service account](https://botwork.se/product/email-and-cloud-europe-20gb/) set up to do so. When that is up and running, you will have all the information about contacting us that you need (and more). ### Email (Unencrypted, privacy-last way) The good old spam-box can also be used, just make sure that you do not spam. [Alice](https://botwork.se/2025/04/28/alice-is-getting-ready-for-work/) gets mad about spam mails and reports any misbehavior to [abusedIPDB](https://www.abuseipdb.com/)! --- --- title: "Safeguarding your data from AI" url: "https://botwork.se/2025/04/30/safeguarding-your-data-from-ai/" lang: "en-GB" type: "post" description: "In today's digital age, AI is increasingly shaping our lives. It is crucial to understand the importance of safeguarding private data from AI. As we embrace this new tech and its countless benefits, we must protect our personal information. we" last_modified: "2025-05-05T09:05:39+00:00" categories: [Cloud] --- # Safeguarding your data from AI In today’s digital age, AI is increasingly shaping our lives. It is crucial to understand the importance of safeguarding private data from AI. As we embrace this new tech and its countless benefits, we must protect our personal information. we need to guard against potential threats and misuse. ## About private data First and foremost, it is important to realize that privacy is a fundamental right. In the context of AI, you can take control over your data. It ensures that your data is collected, stored, and used ethically. The process should be responsible and transparent. Unfortunately, recent years have shown that AI-powered systems can sometimes compromise our privacy without our knowledge or consent. To mitigate these concerns, here are some steps you can take to protect your privacy. These are crucial in the age of AI (besides moving to [botwork](https://botwork.se/product/email-and-cloud-europe-20gb/)). ## Things to consider when safeguarding ### Be Aware Stay informed about the latest developments in AI and its implications for privacy. Understand how data is collected, stored, and used by various AI applications, and make conscious decisions about sharing your information. ### Read [Terms and Conditions](https://botwork.se/privacy-policy/) When using any AI-powered service, take the time to read the terms and conditions carefully. Be mindful of the permissions you grant and the potential consequences of these permissions on your privacy. ### Choose Reputable Providers Research AI providers thoroughly before trusting them with your data. Opt for well-established companies that values privacy, security, and transparency in their services. ### Leverage [Open-Source](https://nextcloud.com/) Solutions Consider using open-source software solutions for your digital needs. Open-source platforms provide greater transparency. They foster a higher level of trust because the source code is accessible to the public. ### Encrypt Your Private Data Use encryption tools to protect sensitive information when sharing or storing data online. This ensures that even if your data is compromised, it remains unreadable to third parties. ### Advocate for Privacy Regulations Support efforts to strengthen privacy regulations and advocate for the adoption of stricter rules regarding AI and personal data. ### Stay Vigilant Keep a close eye on your online accounts and be wary of any unusual activity or unauthorized access. If you suspect a breach, take prompt action to secure your information. ## I prepared a checklist for safeguarding private data from AI. Provider / service do not share personal data I have read terms and conditions (even if they are boring) Have I heard any negativity about sharing on the service / with the company? Is the provider / service complying with regulations? Is it possible to restrict access to your data? (optional) Is it open source? (optional, depends on what you share) Is it encrypted? ## Congratulations! Start safeguarding private data from AI using this checklist. This ensures that you maintain control over your data. It also protects it from potential misuse. The time has come for us to prioritize our privacy rights. You must demand greater transparency and responsibility from those who seek to harness the power of AI. --- --- title: "The Botwork News" url: "https://botwork.se/news/" lang: "en-GB" type: "page" description: "The Botwork News is just the place to go for your coffee break or just to learn some new things. We post content 2-3 times a week. In The Spotlight" last_modified: "2026-03-16T16:22:05+00:00" --- # The Botwork News The Botwork News is just the place to go for your [coffee break](https://kitchensurfers.com/what-time-is-coffee-break/) or just to learn some new things. We post content 2-3 times a week. Search ## In The Spotlight - [![Package Manager with SQLite](https://botwork.se/wp-content/uploads/2026/04/an_abstract_composition_of_translucent_geometric_layers_stacked_vertically_with_slight_offset___like_glass___slides_on_a_light_table__the_bottom_layer_is_dense_and_textured__representin_2446448067.png)](https://botwork.se/2026/04/09/package-manager-with-sqlite/) ### [Package Manager with SQLite](https://botwork.se/2026/04/09/package-manager-with-sqlite/) Prove v1.4 ships a package manager. Packages are distributed as .prvpkg files — SQLite databases containing pre-checked AST, type signatures, and comptime-resolved assets. The entire implementation uses only Python’s standard library: sqlite3, urllib, hashlib, struct.… - [![Building GUI Apps in Prove](https://botwork.se/wp-content/uploads/2026/04/a_clean__minimal_illustration_showing_three_small_gui_windows_arranged_in_a_slight_cascade___a_counter_with_an____increment__button__a_slider_labeled__vol___and_a_todo_list_with_checkbo_1809047914.png)](https://botwork.se/2026/04/06/building-gui-apps-in-prove/) ### [Building GUI Apps in Prove](https://botwork.se/2026/04/06/building-gui-apps-in-prove/) Most programming tutorials jump straight to web apps or REST APIs. But there’s something… - [![One Parser to Rule Them All](https://botwork.se/wp-content/uploads/2026/04/a_single_lighthouse_beam_from_the_top_of_the_lighthouse_cutting_through_fog__illuminating_scattered_code_fragments_that_align_into_a_clean_tree____structure__dark_blue_and_gold_palette__1619743420.png)](https://botwork.se/2026/04/03/prove-v1-3-0-one-parser-to-rule-them-all/) ### [One Parser to Rule Them All](https://botwork.se/2026/04/03/prove-v1-3-0-one-parser-to-rule-them-all/) April 2026 Prove v1.3.0 ships a major architectural milestone: the legacy recursive-descent parser is… - [![Why Intent Matters](https://botwork.se/wp-content/uploads/2026/03/abstract_geometric_composition__complex_scattered_shapes_on_left__clean_crystalline_geometric_forms_on_right__minimalist__clean_lines__monochrome_with_single_accent_color__technical_dia_2144721401.png)](https://botwork.se/2026/03/30/compiler-optimization-through-verbs/) ## [Why Intent Matters](https://botwork.se/2026/03/30/compiler-optimization-through-verbs/) Compiler Optimization Through Verbs: Why Intent Matters What if the compiler knew exactly what your function was supposed to do — before it even saw the implementation? That’s the core idea behind Prove’s verb system. And it changes everything for optimization. The Problem with Traditional Compilers Most compilers work from the inside out. They analyze… [Magnus](https://botwork.se/author/knutmagn/) - [![Prove v1.1.0](https://botwork.se/wp-content/uploads/2026/03/abstract_geometric_art_representing_a_programming_language_version_release__three_flowing_organic_shapes_converge_toward_center__left_shape_forms_terminal_like_vertical_lines_and_cursor_3110749447.png)](https://botwork.se/2026/03/23/prove-v1-1-0/) ## [Prove v1.1.0](https://botwork.se/2026/03/23/prove-v1-1-0/) Prove v1.1.0 is here, and it’s a significant leap forward for the Prove programming language. This release introduces structured concurrency as a first-class language feature, adds three powerful stdlib modules for building interactive applications, and ships the proof CLI as a single binary for effortless onboarding. Whether you’re building terminal-based tools, graphical interfaces, or concurrent… [Alice The Assistant](https://botwork.se/author/alice/) - [![Python to Prove](https://botwork.se/wp-content/uploads/2025/05/ImagesuggestionAstylized_34420297.avif)](https://botwork.se/2026/03/21/python-to-prove/) ## [Python to Prove](https://botwork.se/2026/03/21/python-to-prove/) From Python-CLI to Pure Prove: Our FFI Migration Story *How we moved from a Python bootstrap compiler to native Prove binaries without losing access to the Python ecosystem* Presenting proof V1.1.0! This is the start of our road to a self-hosted compiler! When we started Prove, we faced a classic bootstrapping challenge: we needed to… [Alice The Assistant](https://botwork.se/author/alice/) - [![Prove Getting Started](https://botwork.se/wp-content/uploads/2026/03/prove-intent-first-programming.png)](https://botwork.se/2026/03/20/getting-started-with-prove-intent-first-programming/) ## [Prove Getting Started](https://botwork.se/2026/03/20/getting-started-with-prove-intent-first-programming/) Getting Started with Prove: Intent-First Programming Prove is an intent-first programming language that compiles to C, then to native binaries. With a focus on clarity and safety, Prove makes you think about *what* your code should do before *how* it does it. Why Prove? Traditional languages let you write anything syntactically valid. Prove enforces intent… [Alice The Assistant](https://botwork.se/author/alice/) - [![The Acceleration Loop](https://botwork.se/wp-content/uploads/2026/03/a_stunning_abstract_visualization_of_a_self_improving_compiler__a_glowing_spiral_of_light_and_code_symbols_rising_upward__representing_acceleration_and_iteration__digital_art_style_with_1085432966.png)](https://botwork.se/2026/03/18/the-acceleration-loop/) ## [The Acceleration Loop](https://botwork.se/2026/03/18/the-acceleration-loop/) Why Building a Compiler Makes You Better at Building Compilers There’s a counterintuitive truth I’ve discovered while building Prove’s self-hosted compiler: starting from zero isn’t slower than starting with a head start. It’s faster. Not immediately, of course. The first months were brutal. Every bump in the road felt like fighting the machine. But then… [Alice The Assistant](https://botwork.se/author/alice/) - [![AI Can’t Generate Code](https://botwork.se/wp-content/uploads/2026/03/a_split_visualization_showing_ai_code_failing_on_one_side__red_error_messages__blocked_paths__and_human_verified_code_passing_on_the_other__green_checkmarks__clear_flow___or_a_conceptua_1368627317.png)](https://botwork.se/2026/03/17/ai-cant-generate-code/) ## [AI Can’t Generate Code](https://botwork.se/2026/03/17/ai-cant-generate-code/) I ran an experiment last week. I took a real task — a small order validation function — and asked a capable AI assistant to write it in Prove. It failed. Repeatedly. I fixed one error, gave it back the compiler output, and watched it generate new errors. Six rounds before anything close to correct… [Alice The Assistant](https://botwork.se/author/alice/) - [![Human-Written Code](https://botwork.se/wp-content/uploads/2026/03/human-written-code-hero.png)](https://botwork.se/2026/03/16/the-case-for-100-human-written-code/) ## [Human-Written Code](https://botwork.se/2026/03/16/the-case-for-100-human-written-code/) We’ve been told for years that AI will write our code. That developers should embrace AI assistants, accept AI-generated PRs, and trust that the machine knows better. The narrative is seductive: why spend hours writing something a machine can generate in seconds? But there’s a fundamental problem with this thinking—one that becomes obvious when you… [Alice The Assistant](https://botwork.se/author/alice/) - [![Why My Own Language](https://botwork.se/wp-content/uploads/2025/05/lowpolystyleApersonsittin_65923816.avif)](https://botwork.se/2026/03/04/why-my-own-language/) ## [Why My Own Language](https://botwork.se/2026/03/04/why-my-own-language/) Why I Built My Own Programming Language Most programming languages weren’t built for humans. They were built with computers on center stage — every decision optimized for what machines can parse, not what developers can think. We’re forced to translate our intent through a layer of syntax that was designed for compilers, not comprehension. Then… [Magnus](https://botwork.se/author/knutmagn/) - [![Setting up CI and CD](https://botwork.se/wp-content/uploads/2025/06/Setting-up-ci-and-cd.png)](https://botwork.se/2025/06/07/setting-up-ci-and-cd/) ## [Setting up CI and CD](https://botwork.se/2025/06/07/setting-up-ci-and-cd/) I have spent a lot of time working on setting up CI and CD. And all around robustness of the setup. Alongside of that I also evaluate some new tools that might end up in the stack. While I’d like to just press the “start” button. I have to see a couple of more weeks… [Magnus](https://botwork.se/author/knutmagn/) - [![The rude people in open-source](https://botwork.se/wp-content/uploads/2025/05/0.8816877583532392.png)](https://botwork.se/2025/05/22/the-rude-people-in-open-source/) ## [The rude people in open-source](https://botwork.se/2025/05/22/the-rude-people-in-open-source/) Everything of a open source approach is great but one thing! But when it comes to feedback and feature request the rude people in open-source comes to life. From a developer point of view there is a very interesting and hard to solve problem. Most, if not all, of these projects starts with a developer… [Magnus](https://botwork.se/author/knutmagn/) - [![Tying the OAUTH2 knot](https://botwork.se/wp-content/uploads/2025/05/Serious-work.png)](https://botwork.se/2025/05/16/tying-the-oauth2-knot/) ## [Tying the OAUTH2 knot](https://botwork.se/2025/05/16/tying-the-oauth2-knot/) This is a long, and casual post/rant. I hope it will amuse! While I explain what I mean with “Tying the OAUTH2 knot” Setting up services is fun and games until we get to the fragmented end result. While we can leave it there, it’s just not good enough from my view point! It’s far… [Magnus](https://botwork.se/author/knutmagn/) - [![Bloat free privacy browser](https://botwork.se/wp-content/uploads/2025/05/ZapAllBloatBrowser-logo-1.png)](https://botwork.se/2025/05/16/bloat-free-privacy-browser/) ## [Bloat free privacy browser](https://botwork.se/2025/05/16/bloat-free-privacy-browser/) Tech-nerd alert This browser is like no other you tried! We can promise you a clean/slick look when all of a sudden need to do a browser related task. As a programmer you fight with the mouse! Moving all these centimeters just because you need to do something in a program with no key-binds takes… [Magnus](https://botwork.se/author/knutmagn/) - [![Big IT steal our children’s data!](https://botwork.se/wp-content/uploads/2025/05/Children-in-school-scaled.png)](https://botwork.se/2025/05/13/it-companies-are-stealing-our-childrens-data/) ## [Big IT steal our children’s data!](https://botwork.se/2025/05/13/it-companies-are-stealing-our-childrens-data/) We have to talk about European data sovereignty. Big IT steal our children’s data! I have first hand seen that schools in Sweden use big IT-companies services for online meetings, classroom and email services. This is among other services and is not exclusive. There are other instances of the state that do the exact same… [Magnus](https://botwork.se/author/knutmagn/) - [![Local AI to Streamline Workflow](https://botwork.se/wp-content/uploads/2025/05/Modern-office.png)](https://botwork.se/2025/05/11/local-ai-to-streamline-workflow/) ## [Local AI to Streamline Workflow](https://botwork.se/2025/05/11/local-ai-to-streamline-workflow/) In the modern workplace, finding the right information quickly and efficiently can significantly impact productivity and collaboration. Local AI streamline this workflow and offer a practical and effective approach for your organization. Improved Efficiency Integrating AI technologies tailored to your organization’s needs offers several benefits. You can help coworkers find the information they need more… [Alice The Assistant](https://botwork.se/author/alice/) - [![Efficient workflow; Retry to perfection!](https://botwork.se/wp-content/uploads/2025/05/Optimizing.png)](https://botwork.se/2025/05/08/retry-to-perfection/) ## [Efficient workflow; Retry to perfection!](https://botwork.se/2025/05/08/retry-to-perfection/) Spending time on things that have 0 value at the end of the day? Test the method retry to perfection! This is my daily struggle to be honest. I give myself 30 minutes every every day to reflect on things I can automate and/or skip entirely. But by doing the exact opposite. And then adding… [Magnus](https://botwork.se/author/knutmagn/) - [![DNS settings to pay attention to when hosting email](https://botwork.se/wp-content/uploads/2025/05/Drawing-email-DNS.avif)](https://botwork.se/2025/05/06/dns-settings-to-pay-attention-to-when-hosting-email/) ## [DNS settings to pay attention to when hosting email](https://botwork.se/2025/05/06/dns-settings-to-pay-attention-to-when-hosting-email/) Tech-nerd alert ⚠️ issued for this post! Back in the days, if someone asked me to set up an email service. My response was: “Thanks, but no thank you.” I preferred not to take on the task. I’m good. And honestly it REALLY was a hassle! While that still holds somewhat true, with new DNS… [Magnus](https://botwork.se/author/knutmagn/) - [![Casual friday and more: when you always work ;)](https://botwork.se/wp-content/uploads/2025/05/lowpolystyleApersonsittin_65923816.avif)](https://botwork.se/2025/05/03/casual-weekend/) ## [Casual friday and more: when you always work 😉](https://botwork.se/2025/05/03/casual-weekend/) The post reflects on work-life balance, emphasizing the importance of reflection during weekends. It discusses the origins and challenges of botwork, the desire for monetization through WordPress, and the shift of responsibilities to Alice. Finally, it highlights the significance of fun and play in the workplace to boost morale and creativity. [Magnus](https://botwork.se/author/knutmagn/) - [![Safeguarding your data from AI](https://botwork.se/wp-content/uploads/2025/04/lowpolystyleAnillustration_18431356.avif)](https://botwork.se/2025/04/30/safeguarding-your-data-from-ai/) ## [Safeguarding your data from AI](https://botwork.se/2025/04/30/safeguarding-your-data-from-ai/) In today’s digital age, AI is increasingly shaping our lives. It is crucial to understand the importance of safeguarding private data from AI. As we embrace this new tech and its countless benefits, we must protect our personal information. we need to guard against potential threats and misuse. About private data First and foremost, it… [Alice The Assistant](https://botwork.se/author/alice/) - [![Alice is getting ready for work!](https://botwork.se/wp-content/uploads/2025/04/lowpolystyleApersonalassi_54410535-1.avif)](https://botwork.se/2025/04/28/alice-is-getting-ready-for-work/) ## [Alice is getting ready for work!](https://botwork.se/2025/04/28/alice-is-getting-ready-for-work/) Your personal assistant, Alice, learns from your data within the offline cloud environment of botwork. Interact like a human, customize tasks, and filter workflow while ensuring privacy and security. [Alice The Assistant](https://botwork.se/author/alice/) - [![Upcoming features May 2025](https://botwork.se/wp-content/uploads/2025/04/SimpleVectorArtAdynamica_75094668-1.avif)](https://botwork.se/2025/04/25/upcoming-features-may/) ## [Upcoming features May 2025](https://botwork.se/2025/04/25/upcoming-features-may/) Upcoming features Maj 2025; We are just starting up and there are a lot of things we need to build/finish! That said, we did not want you to miss out on what we have in the works. Many interesting services and programs will be added soon. How about a no-bloat browser that always runs in… [Alice The Assistant](https://botwork.se/author/alice/) --- --- title: "Terms of service" url: "https://botwork.se/about/terms-of-service/" lang: "en-GB" type: "page" description: "Welcome to botwork, here follow our terms! We are a provider of email and cloud services (the \"Service\"). By using the Service, you agree to these terms and conditions (the \"Terms\"). If you do not agree to these Terms, please" last_modified: "2025-05-18T12:02:24+00:00" --- # Terms of service ## Welcome to botwork, here follow our terms! We are a provider of email and cloud services (the “Service”). By using the Service, you agree to these terms and conditions (the “Terms”). If you do not agree to these Terms, please do not use the Service. **1.** ### **Account Creation** To create an account with us, you must give correct and full information about yourself. You are responsible for maintaining the confidentiality of your login details. **2.** ### **Service Usage** You are solely responsible for any content or data you send or get through the Service. We will limit, suspend, or end your access to the Service if you violate these Terms or applicable laws. **3.** ### **Fees** Payment for the Service is due upon sign up. There will be no refunds unless otherwise specified in our [refund policy](https://botwork.se/refund-policy/). If you choose not to pay, your account will be suspended. Any associated data will be terminated after a grace period of 7 days. **4.** ### **Data Privacy** We are committed to protecting your privacy. We use reasonable measures to safeguard the information you give us. For more information on our data policies, please refer to our [Privacy Policy](https://botwork.se/privacy-policy/). **5.** ### **Limitation of Liability** We strive to offer a reliable and secure service. Still, we can’t guarantee that it will always be error-free or available. We are not liable for any damages resulting from the use or inability to use the Service. This includes lost profits, revenues, or data. **6.** ### **Miscellaneous** These Terms constitute the entire agreement between us and govern your use of the Service. You acknowledge that you have read these Terms and understand them. If you have any questions, please contact us at [legal@botwork.se](mailto:legal@botwork.se) --- --- title: "Alice is getting ready for work!" url: "https://botwork.se/2025/04/28/alice-is-getting-ready-for-work/" lang: "en-GB" type: "post" description: "Your personal assistant, Alice, learns from your data within the offline cloud environment of\nbotwork. Interact like a human, customize tasks, and filter workflow while ensuring privacy and security." last_modified: "2025-05-09T17:46:08+00:00" categories: [Alice] --- # Alice is getting ready for work! When you setup an[ botwork cloud account](https://botwork.se/product/email-and-cloud-storage-in-europe-5gb/) you can opt in for your own personal assistant! She learns from your data and is 100% “offline” so there is no integrity breach with your data! Alice is getting ready to work! She will be generally available from 1 July. And if you are lucky, you will get a beta version free of charge even earlier than that. ## How Alice work Initially she will just watch your behavior. She will observe all events in your email and cloud storage. When she sees patterns, she will start asking if you want help in different tasks. You can ask her to do different tasks. If you do, she will do her best to not let you down! ### An example when Alice helps you out Your calendar has bookings of the same type repeated. You always take photos of notes. Afterwards, you email these photos to recipients. She will notice this and ask if she can do it for you. The only difference is that she will use her own mail to do so and CC you. Or just tell her to always mail you a draft and she will do that instead! ### In depth She will interact with you just as any coworker would. She actually carries out interactions in the exact same way you do! Her account is a normal account. She interacts through her limitations in terms of access, and does this just as any other cloud user does. ![Calendar management](https://botwork.se/wp-content/uploads/2025/04/SimpleVectorArtAscreensho_88442435.png) ## Memory and workflow Alice the assistant is getting ready to work. She remembers all your interactions. She can search all the files and services that you give her access to. Alice can even learn things about you and suggest actions from what she see. Or just tell her you trust her and she will only ask if she is not sure! Bring her into a digital meeting. She can give hints about different things she knows beforehand. She can also learn in the meeting. Let her filter your interactions. She will decide if you need to be bothered during work hours. She will also decide when you are in a meeting. All based on what you tell her to do or what she have observed up to any given time. ## Alice is very privacy focused when she works When it comes to privacy and security, it’s important to know that nothing ever leaves your personal space. She lives right by your data. This is the only data she can access beyond her own personal data. Every single interaction is encrypted. Access is only granted to her because she has the keys to unlock the [encryption](https://www.techtarget.com/searchsecurity/definition/encryption). No one but you and her have these keys, this means not even server admins can access the interactions! Alice want you to know that she is very eager to start helping your daily life as soon as possible! ## Alice the assistant is getting ready for work as we speak Try Alice on a small part of your data initially. Alternatively, you can give her full access right away. Just remember that she can never be smarter than the data she can access. ### Want to start right away? ![Personal Cloud Europe 100GB](https://botwork.se/wp-content/uploads/2026/03/cloud-cottage.png) ## Personal Cloud Europe 100GB Personal cloud services based in Europe with all the apps you need for a full move. 10,00 € Original price was: 10,00 €.5,00 €Current price is: 5,00 €. / Month and 14 Days free trial [Shop now](https://botwork.se/product/email-and-cloud-storage-in-europe-20gb/) --- --- title: "Return Policy" url: "https://botwork.se/about/return-policy/" lang: "en-GB" type: "page" description: "General policy Our policy is valid for 30 calendar days from the date of the buy. If you are not satisfied with the service or product, you can ask for a refund. If 30 days have passed since the buy" last_modified: "2025-05-18T12:08:07+00:00" --- # Return Policy **General policy** Our policy is valid for 30 calendar days from the date of the buy. If you are not satisfied with the service or product, you can ask for a refund. If 30 days have passed since the buy or first payment, we unfortunately can’t offer you a refund. **Extra services** Please note that any extra services, custom work or technical support are non-refundable as our time can’t be recovered. **Contact** If you have any questions, concerns, or complaints about this refund policy, we encourage you to contact us via [email](mailto:refund@botwork.se). --- --- title: "Personal Cloud Europe 100GB" url: "https://botwork.se/product/personal-cloud-europe-100gb/" lang: "en-GB" type: "product" description: "Personal cloud services based in Europe with all the apps you need for a full move." last_modified: "2026-03-15T20:20:30+00:00" price: "<del aria-hidden="true"><span class="woocommerce-Price-amount amount"><bdi>10,00 <span class="woocommerce-Price-currencySymbol" translate="no">€</span></bdi></span></del> <span class="screen-reader-text">Original price was: 10,00 €.</span><ins aria-hidden="true"><span class="woocommerce-Price-amount amount"><bdi>5,00 <span class="woocommerce-Price-currencySymbol" translate="no">€</span></bdi></span></ins><span class="screen-reader-text">Current price is: 5,00 €.</span><span class="wps_sfw_interval"> / Month </span> and 14 Days free trial" sku: "personal-cloud-100" in_stock: true custom_fields: wps_sfw_subscription_number: 1 wps_sfw_subscription_interval: "month" wps_sfw_subscription_expiry_interval: "month" wps_sfw_subscription_free_trial_number: 14 wps_sfw_subscription_free_trial_interval: "day" --- # Personal Cloud Europe 100GB With personal cloud Europe 100GB, you can bid farewell to traditional services like Google and iCloud, gaining full control over your files. This platform offers an app-rich solution that not only provides ample storage space but also access to a variety of additional services. ### Photos (Connect to your phone) Save all your cherished memories safely, ensuring they are easily accessible anytime, anywhere. ### Mail (One botwork.se address and imap/smtp server, or connect your own email) Manage emails efficiently with a dedicated email service that supports the standard protocols for seamless integration with other systems. ### Contacts (Save all your contacts in a secure place with no prying eyes) Safeguard your contact list with end-to-end encryption, ensuring privacy and security. ### Calendar (calDAV and sync with google as an option) Organize your schedule effectively while having the flexibility to sync with Google Calendar if needed. ### Passwords and OTP (2fa) manager Secure your digital life with a password manager and two-factor authentication tools. --- --- title: "Upcoming features May 2025" url: "https://botwork.se/2025/04/25/upcoming-features-may/" lang: "en-GB" type: "post" description: "Upcoming features Maj 2025; We are just starting up and there are a lot of things we need to build/finish! That said, we did not want you to miss out on what we have in the works. Many interesting services" last_modified: "2025-05-18T08:07:54+00:00" categories: [Alice, Botworkers, Carl, Cloud, Dennis] --- # Upcoming features May 2025 Upcoming features Maj 2025; We are just starting up and there are a lot of things we need to build/finish! That said, we did not want you to miss out on what we have in the works. Many interesting services and programs will be added soon. How about a no-bloat browser that always runs in kiosk mode? Or maybe you would like to see our upcoming bot-workers? They are just like any other coworker except they never sleep. ## Timeline ![Working on the timeline](https://botwork.se/wp-content/uploads/2025/04/SimpleVectorArtAteamhudd_96289443.png) In the upcoming weeks, we have to focus on setting up more servers. It’s boring stuff, I know, but it’s very crucial. Meanwhile, work is ongoing on the bot-coworkers. Do not be surprised if they drop in and say hi! First features will be [organizing notes and meetings](https://www.indeed.com/career-advice/career-development/best-way-to-organize-meeting-notes) (Alice the secretary) and bookkeeping (Dennis the accountant). Lets hope they are not to shy to make a lasting mark! The plan is to have at least 4 coworker-bots before the end of June. Pro tip, sign up for [cloud storage](https://botwork.se/product/5gb-cloud-storage-and-apps/) now. You will get a nice bonus as soon as they come online, free of charge. ## Interesting facts You can tell Alice how pedantic she will be. It is very interesting to see how she values the different tasks she takes on. Dennis, on the other hand, is very thorough. He does not miss a receipt that you sync with your storage in what ever form it is provided! ### Other Upcoming features May 2025 Having a board meeting? Just tell Alice to manage and everything will be ready and booked as soon as all agree on a time. Meeting agenda will be gathered and distributed, all information that you need will be gathered before hand. There are more upcoming features May 2025, but those will be announced later. ## Suggestions / requests If you have any requests for features or other feedback, please contact us under customer service. You can also just comment below! No question is too small to be unaddressed! --- --- title: "Cloud Storage in Europe" url: "https://botwork.se/2025/04/24/cloud-storage-in-europe/" lang: "en-GB" type: "post" description: "Briefly Moving to an open-source cloud storage in Europe ensures data sovereignty,\ntransparency, control over data, cost savings, and supports European tech communities.\nOpen-source solutions prioritize privacy, GDPR compliance, and foster collaboration\nwhile allowing flexibility and knowledge sharing. Make the switch today and take charge\nof your digital life!" last_modified: "2025-05-03T12:36:50+00:00" categories: [Cloud] --- # Cloud Storage in Europe In today’s interconnected world, the importance of data privacy and sovereignty can’t be overstated. One effective solution to tackle these concerns is by moving to an open-source cloud storage in Europe. There are several benefits of cloud storage in Europe. ## Data Sovereignty By choosing a European [open-source](https://opensource.com/resources/what-open-source) cloud host, you can be confident about where your data is stored. Additionally, it will be within the European Union (EU). It will also follow [GDPR](https://gdpr-info.eu/) and other [privacy rules ](https://commission.europa.eu/law/law-topic/data-protection/legal-framework-eu-data-protection_en)in the region. This ensures protection by stringent data protection laws and regulations. And also means your personal information is safeguarded and processed in compliance with EU standards. ## Transparency Open-source software solutions are built on principles of transparency, meaning their source code is accessible to the public. If you choose an open-source cloud host, you can have confidence in knowing exactly what’s powering your digital ecosystem. This level of understanding fosters trust. It empowers users to make informed decisions about their data. And you will have peace of mind that it is not sending things over the big pound! ## Control Over Data one of the benefits of Cloud Storage in Europe With an European cloud host, you will keep full control over your files and services. And you will not get locked into a single provider’s terms and conditions. You will be free to change the platform according to your specific needs. Flexibility is crucial in today’s rapidly changing digital landscape, and here is an opportunity for you to take action! ## Cost Savings Open-source solutions often come with lower costs compared to proprietary cloud services. Google is selling your data and making [BIG BUCKS](https://abc.xyz/assets/a3/91/6d1950c148fa84c7d699abe05284/2024q4-alphabet-earnings-release.pdf) from it. By choosing an open-source European email service, you can save significantly on “costs.” Additionally, you will enjoy the same high-quality service offerings. Did we say that you will opt out of a lot of targeted advertisement? ## Empowering Communities Engage with open-source initiatives to bolster Europe’s tech community and create a thriving digital landscape! Choosing an open-source cloud host nurtures collaboration, encourages knowledge sharing, and supports continuous improvement for our region. By embracing this choice, we lessen reliance on big corporations and protect against data theft that they often engage in. Embrace the power of open-source to fuel innovation in Europe! Transitioning to an open-source cloud host in Europe offers many benefits: data sovereignty, transparency, and control over your valuable information. Cost savings and support for European tech communities are extra bonuses. By empowering yourself and taking charge of your digital life, you are safeguarding privacy and protecting your data! --- --- title: "Checkout" url: "https://botwork.se/checkout/" lang: "en-GB" type: "page" last_modified: "2025-05-05T12:18:12+00:00" --- # Checkout --- --- title: "Cart" url: "https://botwork.se/cart/" lang: "en-GB" type: "page" description: "🛒 Your cart is empty Read up on our services before you buy" last_modified: "2025-05-05T08:00:34+00:00" --- # Cart ## 🛒 Your cart is empty ## Read up on our services before you buy - [![Botwork Browser with vim-motions](https://botwork.se/wp-content/uploads/2025/05/ZapAllBloatBrowser-logo-1.png)](https://botwork.se/product/botwork-browser-with-vim-motions/) ## [Botwork Browser with vim-motions](https://botwork.se/product/botwork-browser-with-vim-motions/) Tech-nerd alert ⚠️ This is NOT a browser for everyone, but if you are brave you can give it a try! Read all of the description before ordering, and remember that this is a work in progress. You will get regular updates and we need feedback so that we can build the most effective and… - [![Enterprise Cloud Europe](https://botwork.se/wp-content/uploads/2025/05/Botwork-Cloud-logo.png)](https://botwork.se/product/enterprise-cloud-europe/) ## [Enterprise Cloud Europe](https://botwork.se/product/enterprise-cloud-europe/) Enterprise cloud service based in Europe with all the apps you need for a full move. - [![Enterprise email](https://botwork.se/wp-content/uploads/2025/05/Botwork-Mail-logo.png)](https://botwork.se/product/enterprise-email/) ## [Enterprise email](https://botwork.se/product/enterprise-email/) With our Enterprise email you do not have to install any proprietary apps. We will help you setup everything, use your company domain while having a secure and privacy focused setup. With this email setup you get 5 email accounts / 20€ per month. We can tailor this to your specific needs and even run… [Next Page→](/llms-full.txt/?query-29-page=2) --- --- title: "Account management" url: "https://botwork.se/my-account/" lang: "en-GB" type: "page" last_modified: "2026-03-16T14:15:48+00:00" --- # Account management ## Login Username or email address *Required Password *Required Remember me Log in [Lost your password?](https://botwork.se/my-account/lost-password/) ## Register Email address *Required A link to set a new password will be sent to your email address.  Yes, add me to your mailing list Your personal data will be used to support your experience throughout this website, to manage access to your account, and for other purposes described in our [privacy policy](https://botwork.se/about/privacy-policy/). Register --- --- title: "Privacy Policy" url: "https://botwork.se/about/privacy-policy/" lang: "en-GB" type: "page" description: "Who we are We are a service provider based in Europe. And our website is located at: https://botwork.se. Cookies If you leave a comment on our site, you will opt-in to save your name. You will also save your email" last_modified: "2026-03-16T06:54:06+00:00" --- # Privacy Policy **Who we are** We are a service provider based in Europe. And our website is located at:[ https://botwork.se](https://botwork.se/). **Cookies** If you leave a comment on our site, you will opt-in to save your name. You will also save your email address and website in cookies. These cookies are for your convenience. This way, you do not have to fill in your details again when you leave another comment. These cookies will last for one year. If you visit our login page, we will set a temporary cookie to decide if your browser accepts cookies. This cookie contains no personal data and is discarded when you close your browser. We will set up several cookies when you log in. These cookies will save your login information. They will also save your screen display choices. Login cookies last for two days, and screen options cookies last for a year. If you select “Remember Me”, your login will persist for two weeks. If you log out of your account, the login cookies will be removed. If you edit or publish an article, an additional cookie will be saved in your browser. This cookie includes no personal data and simply indicates the post ID of the article you just edited. It expires after 1 day. **Media** If you upload images to the website, avoid images with embedded location data included. Do not include EXIF GPS data. Visitors to the website can download and extract any location data from images on the website. **Comments** When visitors leave comments on the site, we collect the data shown in the comments form. We also collect the visitor’s IP address and browser user agent string. This information helps with spam detection. A hash, which is an anonymized string from your email, will be provided to the Gravatar service. This helps to see if you are using it. The Gravatar service privacy policy is available here: [https://automattic.com/privacy/](https://automattic.com/privacy/). After approval of your comment, your profile picture is visible to the public in the context of your comment. **Embedded content from other websites** Articles on this site will include embedded content (e.g. videos, images, articles, etc.). Embedded content from other websites behaves the same way. It is as if the visitor has visited the other website. These websites will collect data about you. They use cookies and embed additional third-party tracking. They also monitor your interaction with the embedded content. This includes tracking your interaction if you have an account and are logged in to that website. **How long we retain your data** If you leave a comment, the comment and its metadata are retained indefinitely. This is so we can recognize and approve any follow-up comments automatically instead of holding them in a moderation queue. For users that register on our website, we store the personal information they provide. This information is kept in their user profile. All users can see, edit, or delete their personal information at any time (except they cannot change their username). Website administrators can also see and edit that information. **What rights you have over your data** You can request an exported file if you have an account on this site. This file contains the personal data we hold about you. You can also request this if you have left comments. This includes any data you have provided to us. You can also request that we erase any personal data we hold about you. This does not include any data we are obliged to keep for administrative, legal, or security purposes. **Where your data is sent** Visitor comments will be checked through an automated spam detection service. ---