Repository navigation
Admit first backend routes on an owned never-live production lane - #6058
Conversation
The Director agent's first-hostname continuation only covered testing, so an owned production lane whose product was never Live had no path for its first backend routes. Extend the same bounded continuation to that lane: the owner must not be Live, the compose must be the service-created empty target that never deployed, and an unresolved original setup keeps custody. Reuse the empty auto-deploy correction's unresolved-setup check instead of a second copy.
A subset check let a retry under the same key add hostnames after the routes were recorded but the receipt was lost. Require the tracked domains to be empty or exactly the requested set, as testing already did.
|
Review result: weighed Independent review by OpenAI (Codex CLI default; the CLI did not report the model), two rounds, read-only, static. Prompts and results are kept in local task evidence. Acted on (round 1, P2 sibling): a subset check on tracked domains let a same-key retry add hostnames after the routes were recorded but the receipt was lost. Tracked domains must again be empty or exactly the requested set (aae2ad8). Declined, with reason (round 1, P2 remainder): this route stores its receipt only on success, so a changed retry after a pre-commit partial outcome is not refused by key. Round 2 confirmed this gives no effect a fresh, fully qualified request on the same state would not also get, and bypasses no ownership, Live, protection, claim, never-deployed, unresolved-setup or alias check. The behavior predates this branch and is shared with the testing continuation and the generic path. Same-original continuation guidance stays: the identical request and key. Round 2: no safety findings. |
|
Ready for the merge train Head: aae2ad8 |
|
Launchplane completed the merge-train step for this pull request.
Launchplane finished the merge-train step for this pull request. Launchplane manages this comment and will update it as the train moves. |
…a78a3dbca1d9ba4: merge PR #6058
Why
The Director agent could add the first backend hostname route to an empty, service-created compose only on a testing lane. An owned production lane whose product was never Live had no path, so ordinary first setup there was refused with
authorization_deniedbefore any provider or record effect. This happened to a reviewed TK production route apply (tracelaunchplane_req_4355b1e274c04d23bfefba0e12cbd77d). The cause is insetup_dokploy_target:director_testing_domainrequiredinstance == "testing", and no other admission path covers a production domain reconcile for this identity.This extends the existing bounded first-hostname continuation to that case. It does not loosen the lane check, add a grant, add a product allowlist, or use a profile label.
What changed
setup_dokploy_target(control_plane/http_app.py): the Director-agent domain continuation (director_empty_domain) now also admitsinstance == "prod"when the context's exclusive owner is not Live. That is the sameproduction_use != "live"invariantfirst_production_setupalready uses, now shared asowner_not_live. The service-authenticated Director-agent marker, exclusive context ownership and the terminal-identity gate are unchanged.setup_empty_lane_domain(control_plane/dokploy_testing_domain.py, formerlysetup_empty_testing_domain) qualifies production with the same evidence as testing:On production it also refuses a Live owner, holds the first-production setup lock, and refuses any unresolved original setup or production operation. Testing keeps exactly one hostname. Production accepts the reviewed hostname set, each matched or created exactly.
require_no_unresolved_production_setup(control_plane/dokploy_target_setup_http.py) is the empty auto-deploy correction's existing predecessor check, extracted so both paths share one copy.The testing-only held state-volume check now applies only to testing lanes, so production does not inherit an unrelated hold.
docs/operations.mddescribes the generalized continuation.Effect boundary (unchanged primitives): per hostname, at most one Dokploy
domain.createof an HTTPSwebroute on the profile's runtime port withcertificateType: none(the existing default certificate), or adoption of an exactly matching route. Then one compare-and-write of the tracked target'sdomains. There is no certificate issuance and no env, compose source or file, mounts, auto-deploy, deploy, workload, DNS, front-proxy, profile, policy, grant, classification or release-exemption change.production_use: unknownis admitted only together with that positive never-used evidence. It is notprelaunch_bootstrap_authorizedand grants no bootstrap or release exemption.Verification
authorization_deniedwith the real trace's message.tests/test_director_testing_domain_setup.py, 40 tests:invalid_request): caller-supplied authority fields.idempotency_key_reused.Independent review
OpenAI (Codex CLI default; the CLI did not report the model), two rounds.
Removed: the duplicated unresolved-setup loop in
dokploy_empty_automation.pyand the testing-only instance assumptions in the shared first-hostname helpers.Net lines: source +92 (−128 / +220: multi-hostname matching, the production lock and the split predicates), docs +3, tests +279.
Refs #6054