Pressure-testing Ota on Langfuse: env overlays, Compose truth, and honest workflow boundaries
How Langfuse forced Ota to separate source-dev env truth from Compose runtime env truth, move Docker Compose adapter inputs into the contract, and keep workflow diagnosis exact instead of hand-wavy.
Overview
Langfuse was the pressure repo that made Ota grow up on Compose and env ownership.
This was not a simple “add a Docker workflow” exercise. Langfuse already had multiple real paths:
- source development with local infrastructure
- CI-style source verification
- published self-host runtime through Docker Compose
- source-built Docker runtime proof through
docker-compose.build.yml
Those paths did not share one truthful env story.
That is exactly why this repo mattered. If Ota could only say “copy one .env and run some commands,” it was still too weak for serious multi-path application repos.
Why Langfuse mattered
Langfuse looks like the sort of repo that breaks shallow readiness tooling:
- a large pnpm monorepo
- source and packaged runtime paths that are both real
- multiple Compose files with different purposes
- local-host contributor defaults that do not match container-internal service discovery
- workflow slices that must stay explicit instead of collapsing into one generic “app” story
It was also important to stay honest about scope.
The contract branch is a selected readiness slice, not full repo coverage. It focuses on the highest-signal source-dev, CI, self-host, and source docker-build paths. That narrower claim is a strength, not a weakness. It keeps the contract operational.
What Langfuse exposed in Ota
1. one dotenv lane was not enough
At the start of pressure-testing, the real blocker was repo truth.
Langfuse's source-dev path wanted local-host style values. The self-host Compose path wanted compose-compatible service hostnames and ports. The source docker-build path had its own container-facing assumptions as well.
Treating all of that as one shared .env lane was not honest.
This repo made the distinction unavoidable:
- source-dev needs
.env - test isolation needs
.env.test - packaged self-host needs
.env.selfhost - source docker-build needs
.env.docker-build
That separation is not over-modeling. It is the only truthful way to describe the repo.
2. Compose adapter truth was still too shell-shaped
Langfuse also exposed a contract-boundary problem.
The important runtime inputs for the Docker paths were not only the command body. They were the Compose-owned selections around:
- env files
- compose files
- selected workflow/runtime lane
If those stay buried in shell docker compose ... flags, the contract is only describing half the runtime truth.
Langfuse is where Ota had to stop treating that as incidental shell detail.
3. workflow diagnosis needed to stay selected-path exact
When a chosen workflow was blocked, the diagnosis needed to fail for the right reason and stop at the right boundary.
This repo exposed why that matters:
- self-host should fail on self-host env drift, not on unrelated source-dev assumptions
- docker-build should fail on docker-build env drift, not on generic repo noise
- selected workflow service checks should stay scoped to the chosen path
That is trust work. A readiness system is only useful if the blocker belongs to the path the operator actually selected.
4. runtime proof needed to reflect real host claims
Langfuse also reinforced a governance point Ota should keep making:
- Ubuntu can do the heavy runtime proof
- macOS can prove contract and dry-run behavior
- Windows can prove contract and unsupported-host diagnostics
That is not incomplete. It is accurate.
What changed in Ota
Langfuse pushed several Ota surfaces forward.
Compose adapter ownership became first-class
Instead of asking authors to hide adapter truth in shell flags, Ota now has explicit Compose-owned input surfaces on tasks:
build:docker: adapter_inputs: compose: env_files: - .env.docker-build files: - docker-compose.build.yml command: exe: docker args: - compose - buildThat is a stronger contract surface than treating --env-file and -f as opaque command trivia.
workflow diagnosis and runtime gating got stricter
Langfuse helped force tighter selected-path behavior around:
- workflow-scoped service diagnosis
- blocking-precondition short-circuiting
- readiness/proof failure attribution for the chosen workflow
That work matters because multi-path repos are where sloppy diagnosis becomes expensive.
env governance became more explicit
The final contract no longer pretends one copied env file is enough for every path. It keeps env ownership visible and bounded:
- source-dev setup creates
.envonly when missing - self-host setup creates
.env.selfhostonly when missing - docker-build setup creates
.env.docker-buildonly when missing - precondition checks enforce compose-compatible values for the Compose lanes
That is the maturity move. Ota should not blur repo truth just to keep the contract shorter.
What the contract says now
The strongest part of the Langfuse contract is that it keeps unlike workflows separate instead of flattening them.
The packaged self-host path is modeled explicitly:
selfhost:compose: adapter_inputs: compose: env_files: - .env.selfhost launch: kind: command exe: docker args: - compose - up requirements: tools: docker: "*" checks: - selfhost-env-compose-compatibleAnd the workflow that selects it stays equally explicit:
selfhost: intent: packaged_runtime prepare: task: setup:env:selfhost run: task: selfhost:compose readiness: surfaces: - web - workerThe source docker-build path gets its own lane rather than pretending it is the same thing:
run:docker: adapter_inputs: compose: env_files: - .env.docker-build files: - docker-compose.build.yml launch: kind: command exe: docker args: - compose - upThat is the right design.
Langfuse is not one runtime. It is one repo with several distinct runtime claims.
What the matrix now proves
The Langfuse matrix is stronger than simple parse-only coverage.
It proves:
ota validateota tasks --useota tasks --safe --use- exported task catalog and execution topology
- native dry-runs for install, verify, source-dev, source-start, selfhost, and docker-build lanes
- native and container dry-run sweeps across non-internal tasks
- real safe verification execution on the source path
- Ubuntu runtime proof for the self-host Compose workflow
- Ubuntu runtime proof for the source docker-build Compose workflow
- truthful unsupported-host diagnosis for native Windows source-dev
That is a much better signal than “the repo has Docker somewhere.”
It proves that the contract can distinguish planning, verification, runtime, and host support without collapsing them together.
Why this repo mattered
Langfuse was the repo that made Ota answer a harder question:
can a readiness contract own env and Compose truth cleanly enough that humans, CI, and agents do not need to reconstruct runtime inputs from shell conventions and scattered templates?
After this pressure pass, the answer is much closer to yes.
The contract does not hide the repo's complexity. It names it:
- source-dev is one thing
- source-start is another
- self-host packaged runtime is another
- source docker-build runtime is another
That is what serious repo readiness looks like.
Links:
- Contract: langfuse
ota.yaml - Matrix workflow: test-ota-contract-matrix.yml
- Green matrix run: #27495673256
Take action