Add Kruxia Flow to the bake-off (infrastructure + DAG 3 verified) - #1
Draft
deangoodmanson wants to merge 6 commits into
Draft
Add Kruxia Flow to the bake-off (infrastructure + DAG 3 verified)#1deangoodmanson wants to merge 6 commits into
deangoodmanson wants to merge 6 commits into
Conversation
The file was mode 644. The Postgres entrypoint runs docker-entrypoint-initdb.d
in lexical order and *execs* a .sh file when it looks executable, otherwise
sources it. Under Docker Desktop on macOS a bind-mounted 644 file is presented
as executable, so the entrypoint exec'd it and it died:
/docker-entrypoint-initdb.d/02-init-runners.sh: /bin/bash:
bad interpreter: Permission denied
The result is a fresh pgdata volume with bootstrap_bakeoff() defined but NOT
CALLED FOR ANY RUNNER -- no <ns>_dag1/_dag3/_dag4 schemas at all -- and `up`
reports success throughout. The failure only appears in the postgres container
log, and every DAG then fails later against missing tables.
Making it executable is correct under both runtimes: the script already ends
`return 0 2>/dev/null || exit 0` precisely so it works sourced or exec'd.
Found on a machine where podman has no VM and Docker Desktop is the live
runtime, so it is likely latent rather than new.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015LaJtGQxTm5k4J8cB4AGA1
Kruxia Flow 0.8.3 -- a Rust durable-execution engine, one binary plus Postgres.
Evaluated head-to-head against Temporal (category) and Conductor (mechanism)
rather than re-running the other eleven tools.
Infrastructure:
- `kruxiaflow` compose profile on ports 8100/8101 (NOT its own defaults of
8080/8081, which belong to Airflow and Kestra here), with the keygen and
catalog one-shots upstream requires. Image pinned to 0.8.3: `latest` on
Docker Hub is 0.3.0 and predates --insecure-dev, so it 401s everything.
- `kruxiaflow` database on the shared postgres; BAKEOFF_NS schema isolation;
bakeoff-db.sh routing; Justfile teardown lists; RUNNING.md port map.
- A `kruxiaflow` resume provider in both mock services. It checks the response
BODY, not the status code: the signal endpoint answers HTTP 200 with
{"signaled": false} when nothing was waiting.
DAG 3 (payment) -- verified, all six spec assertions, zero authoring defects:
happy path; non-retriable decline in 1 attempt; retriable 5xx in exactly 5
attempts (48.6s = 3+6+12+24); validation rejection; duplicate idempotency key
with no second debit; graceful degradation on notification failure. All of its
database work is declarative -- five validation checks as one CASE expression,
and the debit/credit as one idempotent CTE under `serializable`.
DAG 4 is written and deploys but has NEVER RUN, and DAG 2 cannot be written at
all: wait_for_signal cannot complete on 0.8.3 (a signalled activity always
fails). Treat the DAG 4 files as a design record, not verified code. Testing
was stopped there rather than measuring polling workarounds -- see
kruxiaflow_bakeoff/README.md for the reasoning.
comparison.md is deliberately NOT given a 13th column: three of four DAGs are
unverified, so a full column would imply a completeness this does not have.
The provisional score (49 as-is, 55 if the blocker is fixed) and the two
head-to-heads live in kruxiaflow-comparison.md.
Engine defects were filed upstream in kruxiaflow-internal, not here;
kruxiaflow_bakeoff/UPSTREAM-ISSUES.md indexes them.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015LaJtGQxTm5k4J8cB4AGA1
deangoodmanson
marked this pull request as draft
August 15, 2026 01:16
Same self-review applied to the upstream PR, run over this side before the maintainer reads it. Corrections: - **`http.rs:307` cited the file-download branch**, which is easy to dismiss as a special case. Replaced with `http.rs:130` (the `HttpResponse` struct) and `:364`, the main path's unconditional `Ok(...)` -- a much harder line to argue with, and the actual basis for the claim. - **"Temporal: 7+ components"** came from Kruxia Flow's own README comparison table, appears nowhere in this repo, and is contradicted by this repo's own compose, which runs Temporal as three services on the auto-setup image. Now states what was actually observed here. Vendor framing does not belong in this comparison. - **"Conductor ~60s start"** was the compose healthcheck's start grace, not a measurement. Reworded as configuration. - **Binary size** was cited as 13 MB, then briefly as a measured 9.1 MB with a note that upstream's own docs say 7.5 MB and 13 MB in different places. That is splitting hairs about a number that varies by build host and toolchain -- the material point is "one small static binary, not a JVM", so it now says that and nothing more. Verified while reviewing: the provisional score table sums correctly (49 as-is, 55 if the blocker is fixed) with no category exceeding its weight, and all remaining code citations resolve to what the text claims. Citations in the markdown are now links to that exact line on kruxia/kruxiaflow at commit 75f9a77, and UPSTREAM-ISSUES.md links each filed doc on the kruxiaflow-internal branch rather than naming paths in prose. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015LaJtGQxTm5k4J8cB4AGA1
…e instead Every reference pointed at kruxia/kruxiaflow-internal, which is private -- a reviewer of this PR would have hit a 404 with no explanation. All 20 are gone. Three of them were load-bearing *evidence*, so they needed public substitutes rather than deletion, and in each case the public version is the stronger claim: - "no dynamic fan-out" cited an internal feature doc marked Proposed. It now rests on the source itself -- no such field on ActivityDefinition, no reference anywhere in the Rust tree -- plus the public loops-guide, which lists "Parallel iterations: Multiple iterations executing simultaneously" under Future Enhancements (Post-MVP). Checkable by anyone. - "no sub-workflow construct; chaining is Deferred" cited an internal doc. It now rests on absence from ActivityDefinition and from the built-in activity registry, which is what actually matters to a workflow author. - The NUMERIC finding cited an internal fixed-bug report as prior art. Reworded to state the fact (the maintainers have fixed this symptom before on other types by extending the same ladder) without pointing at an unreachable file. UPSTREAM-ISSUES.md is restructured: its whole premise was linking private docs, so it is now a self-contained summary of what was reported and why three of the four DAGs are unverified, with each finding traceable to a line in the public repo at 75f9a77. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015LaJtGQxTm5k4J8cB4AGA1
It noted that kruxia/kruxiaflow has issues enabled and has never received one. Accurate, but it was a swipe at the project's maturity in a document whose job is to explain why three of the four DAGs are unverified -- and the maturity judgement already has a proper home in the scored comparison, where it can be weighed rather than dropped in as an aside. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015LaJtGQxTm5k4J8cB4AGA1
dag4_order_fulfillment.yaml pointed at `dag4_order_fulfillment_flat.yaml` as though it existed. It does not: the flat variant was planned to measure what the missing sub-workflow construct costs, and was abandoned when the composed version turned out to be unrunnable -- comparing two untested files would have measured nothing. The header now says that, and states plainly at the top that this file and all three subflows/ have never been run. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015LaJtGQxTm5k4J8cB4AGA1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds Kruxia Flow 0.8.3 — a Rust durable-execution engine, one binary plus PostgreSQL — as a thirteenth tool, evaluated head-to-head against Temporal (the category comparison, since Kruxia Flow's own README claims that category) and Conductor (the mechanism comparison, since architecturally they are near-twins). The other eleven tools are not re-run.
Please read this first
Only DAG 3 is verified. DAG 2 cannot be implemented at all and DAG 4 is written but has never run, because
wait_for_signal— the engine's suspend/resume primitive — cannot complete on 0.8.3: a signalled activity always fails. Root cause is pinned toorchestrator.rs:1522-1535and filed upstream.Testing was stopped there rather than re-implementing DAG 2 and DAG 4 as polling workarounds. That would have measured a workaround the tool does not advertise and converted its best rubric category into its worst on the basis of a bug that is a few lines from fixed. The reasoning is recorded in
kruxiaflow_bakeoff/README.mdso the decision can be disagreed with.Treat
dag4_order_fulfillment.yamlandsubflows/as a design record, not as verified code — they deploy cleanly and show what composition and saga compensation have to look like in a tool with no sub-workflow construct and no OR-join, but on this repo's own evidence four unrun workflow definitions contain several defects.comparison.mdis deliberately untouched. Three of four DAGs are unverified, so a full thirteenth column would imply a completeness this evaluation does not have. The provisional score lives inkruxiaflow-comparison.mdinstead: 49 as-is, 55 if the blocker is fixed — the two columns reflect a real choice about how to score a defect, and both are explained.What is verified
DAG 3 (payment), all six spec assertions, evidence from the engine's own
workflow_eventstable:completedin ~2sretryable=falsecompletedZero authoring defects in the DAG itself — it worked as written on the first run. Worth noting alongside Temporal's 0 and Kestra's 18 in the Implementation Friction table.
The finding worth putting in the deck: all of DAG 3's database work is declarative. Validation is a single
postgres_querywhoseCASEexpression does all five checks the other implementations do as five Python round-trips, and the money movement is one idempotent CTE inside aserializabletransaction. No other YAML-defined tool in this bake-off can do that without a custom worker.Two commits
1d353c6is independent of Kruxia Flow and worth landing regardless —shared-services/init-runners.shwas mode 644, and under Docker Desktop the Postgres entrypoint execs a bind-mounted.shrather than sourcing it, so it died withbad interpreter: Permission denied. The result is a freshpgdatavolume withbootstrap_bakeoff()defined but never called for any runner — no schemas at all — whileupreports success throughout. Happy to cherry-pick it onto its own branch if you would rather review it separately.ff23b8fis the Kruxia Flow work: compose profile on 8100/8101 (not its own defaults of 8080/8081, which belong to Airflow and Kestra here), image pinned to 0.8.3 becauselateston Docker Hub is 0.3.0 and predates--insecure-dev,BAKEOFF_NSisolation,bakeoff-db.shrouting,Justfileteardown lists,RUNNING.mdport map, and akruxiaflowresume provider in both mock services.Environment note
This machine has no
justand podman with no initialised VM (Docker Desktop is the live runtime), so every documented recipe was run as its rawdocker composeequivalent withCONTAINER_RUNNER=docker. TheJustfilepicks a runtime by binary presence without checking it connects — flagged inPROGRESS.md, not changed here, since it touches shared infrastructure for all twelve other tools.Engine defects were filed upstream in the Kruxia Flow repo rather than here;
kruxiaflow_bakeoff/UPSTREAM-ISSUES.mdindexes them.🤖 Generated with Claude Code
https://claude.ai/code/session_015LaJtGQxTm5k4J8cB4AGA1