Say that DMN decision tables are deployed with the workflow module The page "What VanillaBP is sized for" still said there was no DMN model type and that DMN was not designed yet. A .dmn file next to the BPMN files of a module is deployed with them. The page now says that and links the section on decision tables in Workflow modules. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RVEfP4rFpf8XUVXB9CFuL7
VanillaBP owns four tables, and decision 16 says so (446) The housekeeping table came with the night window, so Home and the migration page count four now. Observability drops the number. The two links to decision 16 follow its new heading. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RVEfP4rFpf8XUVXB9CFuL7
A page for blocked outbox entries How to find a blocked entry, open it again or delete it, on the table and on the MongoDB collection, and what to check about a younger entry of the same key first. The ERROR of every dispatcher links here. The statements move from the two platform pages to this one, and the gruelbox store is linked to its own README section. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RVEfP4rFpf8XUVXB9CFuL7
Blueprints 12: injected beans are named after their role Code examples now call the ProcessService bpms and the use case service loanApproval, the names the blueprints use from now on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RVEfP4rFpf8XUVXB9CFuL7
Name the Camunda 8 adapter in the community hub The Camunda 8 adapter lives in camunda-community-hub/vanillabp-camunda8-adapter, so the links point there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RVEfP4rFpf8XUVXB9CFuL7
Name the Camunda 7 adapter in the community hub The Camunda 7 adapter lives in camunda-community-hub/vanillabp-camunda7-adapter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RVEfP4rFpf8XUVXB9CFuL7
908: the main artifact is recognised in a repackaged JAR Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RVEfP4rFpf8XUVXB9CFuL7
905: an extension reads the open user tasks of a workflow
898: waiting for a read model uses no attempts An entry whose BPMS does not report its workflow yet uses none of block-after-attempts any more. It is blocked once vanillabp.outbox.wait-for-visibility-at-most passed since it was written, about four hours by default. The outbox sections of both platform pages, the migration page and the metrics table say so. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NGP1Z1mjfXKxCgHzecPvuX
897: an operation on a workflow reads the start row Correlating a message and aggregateChanged read the row written when the workflow started where the election cache has none, so they stay patient after a restart and on another node. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NGP1Z1mjfXKxCgHzecPvuX
893: the election of an extension reads the start row before it waits Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NGP1Z1mjfXKxCgHzecPvuX
892: workflowStartOf also names the adapter which started the workflow Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NGP1Z1mjfXKxCgHzecPvuX
892: every row of the delivery log carries the version of its process PROCESS_VERSION is written for a delivery and for the start of a workflow, wherever the adapter names it. Extensions read it with the id through workflowStartOf, and versionsAreReported says whether an empty version may still come. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NGP1Z1mjfXKxCgHzecPvuX
A message starts only the process of its own ProcessService The page on message correlation says what startWorkflowByMessage refuses, quotes the exception and the sentence of the start for an adapter which cannot be checked, and says which adapter decides during a migration. The migration page lists it among the behaviours which differ from version 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NGP1Z1mjfXKxCgHzecPvuX
889: the delivery log also says where a workflow runs A row of VANILLABP_TASK_DELIVERY is a processed delivery or the start of a workflow, and RECORD_KIND says which. The start row carries the aggregate and the id that workflow has in the BPMS, which is what saves the question "which of my configured BPMS holds this workflow" - asked of every one of them today, and answered by none of them in the first seconds after a start on a BPMS which reads from an exporter. With it the second period: vanillabp.delivery.workflow-start-retention, thirty days from the start, and the end of the workflow does not take the row. Changes to an aggregate keep arriving after its workflow ended. Where a period is the wrong shape, keep-workflow-start-while-aggregate-exists asks the aggregate instead. Extensions get workflowIdOf, which answers the id and elects nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JEc3zVEgrqjMp2xsPnw1Wy
882: version 1 had no outbox, so the paragraph about its table goes "Migrating from version 1" told a reader that version 1 already kept its phase-two calls in the gruelbox table TXNO_OUTBOX. It never did: Stephan confirmed on 2026-10-02 that version 1 had no outbox at all and completed the Camunda 8 job from a listener which ran after the commit. The paragraph goes, and the outbox section says what version 1 did instead and that there is nothing to drain. "Spring Boot integration" keeps the description of the store which used to be here, because the bridge in the platform is real. What changes is the audience it names: an application which ran a 2.0 snapshot, not a version-1 one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017T37nXyH8Gc8d3bcyitce2
385: what the upgrade costs under load The migration page had no section about cost at all and did not link to a sizing page. It gets one now, at the end of "Behaviors that differ", in rows, transactions and threads and without a millisecond. A start costs one outbox entry and your transaction still commits once. On Camunda 7 that count is what version 1 had, because version 1 wrote a job of its own engine in the caller's transaction; what moved is the table and the thread. Answering a message, completing a task and cancelling one are where an application on Camunda 7 pays, because version 1 did that work inside the caller's transaction. Every task delivery costs one record, written in the handler's transaction. The threads are what to size. Version 1 on Camunda 7 used the engine's job executor, three threads growing to ten with Camunda's Spring Boot starter, and version 1 on Camunda 8 used the thread which committed. Version 2 dispatches on four, and on Camunda 7 that is a second pool beside the job executor rather than a replacement. "What VanillaBP is sized for" gets the paragraph which belongs to it: the only threads VanillaBP brings of its own are the outbox lanes, and they hold a connection while they work. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017T37nXyH8Gc8d3bcyitce2
780: a wired process with an unserved user task ends the boot Step 0 of the migration said that a user task modelled the way version 1 modelled it is not served and that an open task can no longer be completed. The Camunda 8 adapter now refuses a BPMN process which a @WorkflowService class claims and which carries such an element, so the application does not start until the model is changed. The step says that too. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168Fox39crp8dfWkZ9W84Ub
Merge remote-tracking branch 'origin/wiki/755-the-two-causes-of-a-404-on-an-open-task'
Merge remote-tracking branch 'origin/wiki/719-717-where-the-bpms-numbers-and-calls-live'
docs: the two causes of a 404 on a user task which was open A user task the Business Cockpit shows as active while a check about it answers 404 is the case Stephan has in operation, under version 1. The page now names it and separates the two causes: version 1 asked the index, which is behind the engine, and the user task shape it served up to 1.6.3 has no user-task record in the cluster at all. Measured on 2026-09-28 against 8.8.39, 8.9.21 and 8.10.0-rc1, counting from the creating listener job: the index answered 404 for 1667 ms, 649 ms and 219 ms, while version 2 asks the engine and got 204 after 12 ms, 21 ms and 13 ms. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168Fox39crp8dfWkZ9W84Ub
The key belongs to the artifact which reads it The coordinate is the plain 'io.vanillabp:gruelbox-phase-two-outbox', and the one reference to that store says what the key does: with the artifact, 'false' hands the entries back to VanillaBP's own store, and without the artifact the line reads as nothing at all. VanillaBP does not comment on a key it does not own. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168Fox39crp8dfWkZ9W84Ub
The age a store cannot read is about a store which came from somewhere else "Every store VanillaBP ships" was true while gruelbox was in this repository. It ships from another one now, so the sentence names this platform instead. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168Fox39crp8dfWkZ9W84Ub
The gruelbox store is named once, and it is named where it lives The store left adapter-platform-integration, so its documentation goes with it. What stays on the Spring Boot page is one section: what gruelbox was, where the artifact is now, and that an application which keeps it changes no configuration. The rows and paragraphs which described how that store differs from the ones VanillaBP writes itself are documented in its own repository. The migration page says the same thing from the version-1 side: entries move to VanillaBP's own table, and what is left in TXNO_OUTBOX is counted at every start. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168Fox39crp8dfWkZ9W84Ub
docs: point at the adapter for the numbers and for the worker calls What VanillaBP is sized for says what the framework is built for and answers nothing about how big one application has to be. That number belongs to the adapter, because a remote engine is sized against the requests an application keeps open to it and an engine inside the application against the threads and database connections it takes there. So the page now points at the Camunda 8 adapter's new Sizing page and says what the four numbers are. Extensions gets the same kind of pointer. Everything on that page is VanillaBP's and the same on every BPMS; whatever an extension does to the engine goes through the adapter's own API. On Camunda 8 the part which costs the most when it is missed is opening a job worker, so the paragraph names the three calls and what skipping the last one costs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168Fox39crp8dfWkZ9W84Ub
docs: compensation is a second writer the start now warns about A compensation throw event which undoes two finished activities starts both handlers, so the workflow holds a token per handler and each of them writes the same workflow aggregate. The start now says so where that aggregate has no version attribute, naming the process, the throw event and the handlers. What each engine really does was measured. Camunda 8 hands out both handler jobs at the same moment. Camunda 7 starts them one after the other, and the order it undoes them in is not stable: it sorts the subscriptions by a creation time of millisecond resolution, so two activities compensated within one millisecond are undone in the order they ran in. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168Fox39crp8dfWkZ9W84Ub
Story 303: a @TaskParam the BPMS may hand back as something else The section about what a @TaskParam may be declared as now says which two declarations the startup names, and points at the rule. `@TaskParam Object` is the second of them: Camunda 7 answers it with a BigDecimal and Camunda 8 with a Double. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168Fox39crp8dfWkZ9W84Ub
Stories 303 and 503: which types travel, and what a section's null object does 303 adds the section "Which types may travel": only a plain boolean and a text reach the BPMS unasked, everything else is declared first, and the two directions are judged by different things. It also says what a declared path which does not resolve does, and how a substitute is written. 503 adds the paragraph about sections of a larger process to "Decoupling BPMN from the data model", with the blueprint bpmn-process-sections and the getter which answers whether a section ran. The last sentence of it was measured while that blueprint was built: an existence gateway cannot sit directly behind a call activity, because what a called process shares stays in the child instance. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168Fox39crp8dfWkZ9W84Ub
docs: the block differs between Spring Boot and Quarkus Since the end of a Spring Boot start moved into the lifecycle, what the start of the workflow processing notices is a late finding there and part of the block on Quarkus. The Observability page now says so, so the difference is read rather than discovered by comparing two logs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168Fox39crp8dfWkZ9W84Ub
docs: the counter for work which is not ours A new section says what happens when a BPMS hands this application a task of a workflow another application owns, with the counter to watch and why no delivery record is written. The meter table got its row, and the paragraph about a deleted workflow aggregate no longer names deletion as the only reading. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168Fox39crp8dfWkZ9W84Ub