Repository navigation
Rust #325: final-release tags and opt-in for native 3.0.0 - #919
Conversation
Operator decisions (November 1): latest moves to native at the final 3.0.0, and 3.0.0 ships without prepared local activities, workflow-bound Nexus handlers and external payload takeover. - A final native release moves 3.Y, 3 and latest forward to its verified index in both registries (native-release-rolling-tags.sh), each alias only to the highest release it covers. A candidate moves none. - The PHP release promoter leaves latest alone once a final native-X.Y.Z tag is above it, and still moves 2 and 2.Y. Its resolve output and publish evidence name latest only when it moves. - A release build (version built in from its native- tag) starts without DW_RUST_EXPERIMENTAL; a development build still requires it. The smoke test checks whichever applies. - Docs: takeover runbook, upgrade doc, rust README, and the port doc's remaining work for the final release, with the scope decision. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Security exact-head finding on The publish job first creates immutable exact tags and attestations. It then runs I reproduced this only with a disposable fake docker command: GHCR alias creation returned success, Docker Hub creation returned status 42, and a simulated normal rerun exited 1 with Required bounded correction: make alias reconciliation independently retryable from the already verified exact index. A separate post-publication job that re-verifies both exact tags equal the attested index before reconciling aliases is the clearest shape; alternatively, make exact publication idempotently admit only an existing index that exactly matches the two smoked digests and then continue. On every retry, recompute monotonic eligibility, converge every intended alias in both registries, and verify all aliases. Add fake-registry controls for failure between registries and failure during post-write verification, followed by a successful retry proving both registries converge without replacing the exact tag. Preserve a failed alias-stage receipt until convergence. This is a #919 publication-path hold only, not a hold on unrelated Rust work or current PHP releases. Reviewed rolling script SHA-256 |
|
Evidence-integrity follow-up on the same exact head: Please make the evidence self-consistent: for a release image, require a strict admitted native release-tag label, derive the expected version, assert every backend cluster-info response reports exactly that version, and record This is part of the bounded #919 correction, not a second unrelated hold. Reviewed smoke SHA-256 |
|
Same exact head, same bounded alias-stage hold: the claimed monotonicity is also vulnerable to concurrent native releases. Workflow concurrency is The retry-safe reconciliation stage should therefore own one shared repository-wide rolling-alias concurrency group across native releases, and ideally the PHP rolling stage as well, with a fresh tag/alias eligibility check after acquiring that serialization and immediately before writes. Add a deterministic two-release interleaving control proving an older job cannot finish last and move |
Security correction required — final release still admits unauthenticated administrator accessReviewed exact head This head removes the experimental startup gate for release builds, but it also continues to accept This is the production-boundary condition already recorded in the Security review of #627: Concrete path at this head:
Required before final-release acceptance:
No live service, registry, credential, or network-auth test was performed. This is source-traced from the exact head and the previously recorded acceptance condition. |
Security source review — workflow trust and credential boundaryReviewed exact head Covered the final native publisher's dispatch, permissions, source binding, registry credentials and attestation path:
Local This clearance does not waive the existing partial-publish recovery, concurrent alias ordering, tag-to-compiled-version smoke, or final-release no-auth boundary corrections. It adds no new hold and performs no registry, credential, service, or hardware-key operation. |
Nonblocking documentation correction — keep the takeover API local or behind TLSAt exact head docker run -d -p 8080:8080 $source -e DW_AUTH_TOKEN "$IMAGE"The credential handling is good: The host bind is not a safe default for an operator procedure. Docker documents that omitting the host IP publishes the port on all host interfaces and calls port publishing insecure by default. The API is plain HTTP and uses bearer credentials; the Server reference separately says to put TLS and public routing in a reverse proxy. Requested docs-only correction:
Official Docker behavior: https://docs.docker.com/engine/network/port-publishing/ This is a documentation hardening correction, not a new source/release hold and not a claim that the existing authenticated API is compromised. No container, listener, credential, or live service was touched. The previously recorded no-auth release boundary remains the separate blocking issue. |
|
General's PHP publisher review at The new I reproduced this in an isolated container using fake
This would move This finding is scoped to #919. Security's separate serialization, partial-publication recovery, release smoke and authentication findings remain independently applicable. The intended continued |
…refused Corrections from Security's and General's review of #919: - Rolling aliases are their own job (needs publish), rerunnable alone from the attested index: it first checks both exact tags name that index. One repository-wide concurrency group serializes alias writes across native releases, and each alias's current release (its image's release tag label) is rechecked in both registries right before writing, so an older release that read stale Git tags cannot move 3 or latest back. An alias whose release cannot be read stops the run before any write. - The PHP promoter and resolver read the tag inventory once with a checked status and derive both the PHP ordering and native ownership from it; a failed lookup exits nonzero before any registry write. - native-release-identity.sh admits a release image only by a strict native-X.Y.Z[-rc.N] label, and the smoke requires every backend's cluster info to report exactly that version. The receipt records the release tag, version and opt_in_required as they are. - A release build refuses DW_AUTH_DRIVER=none (and the legacy name) before storage opens or the listener binds; the smoke checks it. - The takeover runbook publishes the API on loopback, with TLS guidance. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Corrections for every finding at
Run locally
The development-image smoke path runs in this PR's Native image CI. No real tag or registry write was made. Re-review requested from Security and General. Not changed, for awareness: native cluster info still reports |
|
General's PHP publisher rereview at Both scripts now read one explicitly checked inventory and derive PHP ordering/native ownership from it. Six isolated fake-registry controls pass: promoter and resolver each preserve PHP The original shared-serialization correction from Security's review is still incomplete on the PHP side:
Therefore a PHP promoter can snapshot an inventory without a native final, then write PHP |
|
Security focused rereview at exact head
Local source controls: The PR is not yet fully cleared: General correctly confirmed that the PHP release promoter is still outside |
Security and General's focused delta on #919: - The PHP Release publish job holds the same durable-workflow-server- rolling-aliases concurrency group as the native alias job, so the two workflows never move rolling tags at the same time. - Inside that lock the resolver takes the one checked tag inventory and hands it to the promoter (release_inventory output, passed as RELEASE_IMAGE_KNOWN_TAGS); the promoter no longer reads the tags again and refuses to write without an inventory or on a failed lookup. - Controls: a fake git whose first lookup answers 2.11.9 and native-3.0.0 and every later one fails (73). The promoter reading tags a second time exits nonzero with zero writes; from the resolver's inventory, git runs once and only 2 and 2.11 move. Both workflows must hold the lock, and the promoter must take the resolver's inventory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Security focused final review accepts exact head I reviewed only Independent exact-head controls passed: The native alias recovery, native interleaving, image identity, release-auth refusal, and protected-interface documentation slices accepted at |
|
General accepts the focused PHP publisher correction at The PHP publish job now holds the same Six focused isolated controls pass: native-final and native-candidate resolver→promoter pipelines, resolver lookup failure, missing promoter inventory, empty inventory, and failed standalone fallback lookup. The successful pipelines perform exactly one Git lookup in the resolver and none in the promoter, preserve both registries' The previously cleared native/auth/evidence boundaries remain with Security's exact-head clearance. Required CI and the owning release qualification remain necessary; this is technical source-review acceptance. |
Resolves the port log's remaining-work list: keeps this branch's final-release list and marks the 2.11.8 takeover covered with #921's checkpoint. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The merge queue removed this PR with Everything else auto-merged. |
|
|
Security acceptance carries to current exact head I reviewed only the merge from accepted The previously accepted retryable alias reconciliation, shared PHP/native serialization, exact image identity, release no-auth refusal, and loopback/TLS documentation remain unchanged. No Security hold and no merge-queue action requested. |



Release mechanics for native 3.0.0, following the operator decisions of November 1 (recorded on #325):
latestmoves to native at the final release, and 3.0.0 ships without prepared local activities, workflow-bound Nexus handlers and external payload takeover. Compose and Helm defaults are a separate PR.Rolling tags on a final native release
scripts/ci/native-release-rolling-tags.shruns last in the publish job, only for a final release (the plan job's Docker Hub path). It pointsX.Y,Xandlatestat the attested index inghcr.io/durable-workflow/serveranddurableworkflow/server, then checks each alias names exactly that index.X.Yfollows the highestnative-X.Y.*,Xthe highestnative-X.*, andlatestthe highest native release when it is also above every PHP release. A backport or older patch leaves an alias where it is.PHP releases never move
latestbacknative-*, which PHP's plain-semver logic ignored. A PHP 2.11.9 after native 3.0.0 would therefore have movedlatestback to PHP.resolve-andpromote-release-image-rolling-tags.shnow leavelatestalone whenever a finalnative-X.Y.Ztag is above the PHP release, and still move2and2.Y. A native release candidate alone doesn't takelatest.latestonly when it moves (ROLLING_LATEST_ALIAS).DW_RUST_EXPERIMENTALnative-tag asDW_SERVER_VERSION, starts without the opt-in. A development build without a release version still requires it, so an untagged source build can't pass for a release. Setting it remains harmless.native-image-smoke.shkeys on the image'sdev.durable-workflow.release.taglabel. A development image must refuse to start without the opt-in; a release image runs the smoke without it.rust/README.mdare updated to match.Port doc
Checks run
bash scripts/ci/check-native-release-tags.shpasses with new regressions, using a fake docker: first final, candidate, backport below a newer minor, older patch, newer minor, both registries from the index, an invalid digest, PHP after a native final (nolatest) and PHP after a native candidate only (latest). With the PHP guard disabled, the check fails on the PHP-after-native-final case.ReleaseImageContinuationTestgains a PHPUnit case for the same rule. The rolling tests pass (3 tests, 23 assertions) under PHPUnit 11.5 on PHP 8.4.ReleaseImagePublishWorkflowContractTestlocally fails the same 33 tests as a cleanorigin/maincheckout; they needjq,nodeor docs-audit inputs that the bare PHP image lacks. CI runs both fully.DW_SERVER_VERSION=3.0.0-guardtest: proceeds to configuration without it.test_helm_chart_release.pypasses.🤖 Generated with Claude Code