The narrowest bug in my v0.2.0 field test is the one I keep telling SREs about. helm lint passed. helm template passed. The chart rendered. The API pod crash-looped, because the container probed port 8100 and the process listened on 8000.
A green signal from a layer that doesn't include the runtime is a green signal about a different system.
This is the article about configuration delivery as a seam on HivePlane v0.2.0 — the failure mode that's invisible to lint, template, and any test that doesn't run the container. "It's in the .env" is not "the process has it."
Three configs that were exported and never passed
| Finding | What was exported | What the process got | What broke |
|---|---|---|---|
| Trigger webhook secret | Set in .env
|
Never passed to the container | Signed ingest returned 403
|
Auth env (HIVEPLANE_AUTH__*) |
Set in .env
|
Never passed to the container |
--auth was a silent no-op |
| Helm probes/ports | Rendered in the chart | Probe pointed at 8100; process on 8000 | Crash-loop; helm lint green |
The trigger source that "couldn't possibly fail" failed on a missing env var. The entire RBAC suite ran against an unauthenticated plane because the auth env never reached the process. And the chart that linted green deployed a crash-looping pod.
The port that wasn't
The Helm chart was the cleanest example. values.yaml declared api.containerPort: 8000 and api.service.port: 8100. The probes pointed at the service port. The process listened on the container port. The probe hit 8100 inside a container where nothing listened on 8100. Crash-loop. helm lint has no opinion about whether the probe target matches the listening port — it validates the chart's schema, not the runtime's reality. This was F-12 in the field-test report — and it didn't stop at the port: the chart also never set the execution adapter or certification executor, so runs were admitted but never executed.
The fix was aligning the probe to the container port (or the process to the service port — but you pick one and assert it). The deeper fix is a field test that runs the container and asserts the probe succeeds, not a lint that asserts the chart is well-formed.
tip:
helm lintproves your chart is valid YAML with valid schema. It does not prove your pod starts. A chart that lints green and crash-loops is a chart whose test suite stopped at the wrong layer. Test the wiring inside the container, not the template outside it.
The secret that was in the .env and not in the process
The trigger webhook secret was the one that felt impossible. I had set HIVEPLANE_TRIGGERS__SECRETS in .env. The signed ingest endpoint verified HMAC over the body. It returned 403 — bad signature — because the secret the process used was empty. The .env had it; the container didn't.
Configuration delivery is a seam. The value exists in the orchestrator's model (the .env, the chart values, the compose environment) and never reaches the process. It's invisible to any test that doesn't run the container, because the in-process test reads the .env directly. The field-test report calls this out explicitly in its lessons: "env vars exported by the runner but absent from the container's environment become unset" — producing a 403 (trigger secret) or an effectively disabled auth layer.
The fix pattern from the field test: assert the value is passed, not merely exported. A config-delivery assertion at the container boundary — docker compose exec api printenv HIVEPLANE_TRIGGERS__SECRETS is non-empty — turns "it's in the .env" into "the process has it."
The auth that was a no-op
The auth env was the same bug with a worse blast radius. HIVEPLANE_AUTH__ENABLED=true was set in .env and not passed to the container. So --auth was a silent no-op. The entire RBAC suite — the one I wrote the previous article about — was running against an unauthenticated plane. Every "viewer cannot approve" test passed because there were no viewers and no roles; everyone was anonymous-admin.
A green RBAC test against a container that never received the auth env proves your chart renders and your tests assume. It does not prove authorization works. The fix is the same seam: assert the env is present inside the container, then run the suite.
What I learned
"Exported" is not "passed." A value in the .env or the chart values exists in the orchestrator's model. The process is a different process in a different mount namespace with a different environment. The seam between them is a testable surface — and it's the one lint and template never touch.
Lint proves the chart; the pod proves the wiring. helm lint validates schema. helm template renders manifests. Neither runs the container. A green chart and a crash-looping pod are not contradictory — they're about different systems. Test the one the operator runs.
Assert the value inside the container. A config-delivery assertion at the boundary — the env var is present in the process that uses it — turns a silent no-op into a loud failure. "It's in the .env" is a statement about your filesystem; "the process has it" is a statement about your runtime.
The v0.2.0 field test runs the full container suite against the live Docker Compose stack — 67/67 scenarios — and the config-delivery findings are the ones that only surfaced because the test ran the container, not the chart. Full evidence in the Docker test report; the Helm chart and k3d reference deployment are under deploy/ with a runbook.
References
-
HivePlane —
pip install hiveplane==0.2.0 - Docker test report (67/67) · Field test report (F-12, §6.7–6.9)
- k3d reference deployment runbook
- Helm chart
Pick one env var your chart sets. Is it present inside the running container — or only in the values file? If you can't answer without running the pod, your config-delivery seam is untested. And your helm lint is green.
Top comments (2)
The auth one is worse than the port. A probe pointing at 8100 pages you immediately, but "--auth was a silent no-op" means the entire RBAC suite passed against a plane with no auth on. That is the version of green that teaches the wrong lesson. Do you have a check now that asserts the env actually landed in the process, not just that it was exported?
프로브가 서비스 포트 8100을 보지만 실제 프로세스는 8000에서 듣는 예시는 lint와 런타임 검증의 차이를 잘 보여주네요. 인증도 환경변수 존재 확인에 더해, 자격 증명 없는 요청이 실제로 거부되는지 확인하는 부정 테스트를 배포 후 점검에 넣으면 silent no-op을 더 빨리 잡을 수 있겠습니다.