Repository navigation
Republish delivery, _canary and _estate on 1.0.0 #380
Copy link
Copy link
Closed
4 / 44 of 4 issues completedLabels
area: deployhomelab-deploy, deploy-v2, manifests, and rollout flow.homelab-deploy, deploy-v2, manifests, and rollout flow.priority: P2Medium; normal planned work.Medium; normal planned work.type: choreMaintenance work without intended behavior change.Maintenance work without intended behavior change.
Description
Parent
Rewrite the spec and the compiler in place, release 1.0.0, and hand over every Project
What to build
The three things already on the estate path move to the 1.0.0 contract, once. After it the estate path composes on the final model and the first handover can start. Settled in Decide between a spec/v2 and reworking v1 in place. The work spans JorisJonkers-dev/delivery and JorisJonkers-dev/estate.
Rollout order
Composition parses every held fragment with the composing toolkit's schema, so a fragment carrying a field 1.0 removed is refused, and a field is dropped only in the same change that moves its repository onto the new toolkit, never ahead of it. In order:
- deploy-kit 1.0.0 is published (Cut what the map cut and release package 1.0.0 #379, release PR chore(main): release 1.0.0 #631), after the other session's feat(model): move an Application between Projects by declaring it in the new one first #650 merges.
- The shared Publish Fragment workflow pins 1.0.0: Pin Publish Fragment to deploy-kit 1.0.0 github-workflows#197.
- auth-api moves onto 1.0 and releases: Move auth-api's project file onto deploy-kit 1.0 auth-api#119 (drop
alertClass, wire${identity:vaultRole}). The Platform document'sforwardAuthnamesauth/auth, so this one must not lag. n8n does the same: Move n8n's project file onto deploy-kit 1.0 n8n#25 (PR feat(deploy): publish on deploy-kit 1.0 n8n#24). - delivery moves onto 1.0: feat: move onto deploy-kit 1.0's schemas, scrape the Release Gate, and narrow its record writes delivery#97, repointed at the 1.0.0 tag's commit, then a delivery release (Release delivery with the off-cluster copy, garage-catalog and the gate's metrics delivery#98).
- The estate moves onto 1.0: Move the estate onto deploy-kit 1.0 estate#231 (branch
feat/deploy-kit-1.0), which needs the maintainer's age key (Generate the backup age key pair, and write the off-cluster backup credential estate#228).
Acceptance criteria
- The in-cluster delivery services regenerate their types against the 1.0.0 schemas and build.
-
delivery,_canaryand_estatepublish fragments validated with 1.0.0. - The estate composes, and the composition lock names 1.0.0.
- The Reconcile Units report Ready on the estate path, and one consumer-visible value is checked: a Ready condition alone is not evidence.
Blocked by
Metadata
Metadata
Assignees
Labels
area: deployhomelab-deploy, deploy-v2, manifests, and rollout flow.homelab-deploy, deploy-v2, manifests, and rollout flow.priority: P2Medium; normal planned work.Medium; normal planned work.type: choreMaintenance work without intended behavior change.Maintenance work without intended behavior change.
Activity
ExtraToast commentedon Oct 27, 2026
The estate-side edits this needs, from the audit in the estate HANDOVER.md (estate main against deploy-kit main plus #628):
forwardAuthas{provider, surface, path}(feat(model): a tier's forward-auth names its provider, not a URL #612);alertClassout ofdata.project.yml;acme:account (E_NO_ACME_POLICY, feat(model): give a tier its L4 Address and its own certificate #624);ingressClassonpublic-frankfurtandlan;signIn.contract: "1.2"(feat(cli): generate an Application's App Roles in its language #632);offCluster.recipient, required in 1.0 (feat(model)!: encrypt every off-cluster copy to a recipient the platform names #636): the maintainer generates the age key pair (age-keygen) and keeps the private key off the cluster, and the public key goes inplatform.intent.yml. Without it the Platform document does not parse on 1.0;substrate.upstreamNameservers(Resolve a DNS-serving Process through the platform's upstream nameservers #634), which utility's adguard needs;apiAccess.namespaceHoldersfor any Process holding namespace-scopedapirules (feat(model): scope an api rule to its Process's namespace or the cluster #640).In delivery, beside the regenerated types:
release-gatedeclaresobservability.scrapeonhttpat/metrics(delivery#22, rendered as a ServiceMonitor by feat(model): scrape a rolling Process through a ServiceMonitor #638);create/updateto a Role indelivery-system.The off-cluster backup credential (
AWS_ENDPOINT_URL,AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEYatsecret/data/platform/backup/off-cluster) is the maintainer's to write. It is needed before the first nightly backup on 1.0 copies anything off-cluster.ExtraToast commentedon Oct 27, 2026
Prepared against deploy-kit main
e255f846, 2026-10-27.The whole estate validates on main: its Platform document and project files, plus every Project's
deploy/on main, giveaccepted (60 read). That needs these changes:forwardAuth: {provider: auth/auth, surface: http, path: /api/auth/forward};ingressClasstraefik-publicandtraefik-lan(the live classes);acme(the live ClusterIssuer's account,postmaster@jorisjonkers.dev, token atsecret/data/platform/cloudflare);substrate.upstreamNameservers: [9.9.9.10, 149.112.112.10](adguard's live ones);alertClassout ofdata.project.yml;offCluster.recipientfeat/deploy-kit-1.0, not pushed: estate CI runs 0.31, and the recipient waits on the maintainer's age keyrelease-gatescraped, ConfigMap writes scoped to its namespacetask checkgreenalertClassdroppedVAULT_KUBERNETES_ROLE=${identity:vaultRole}(E_SELF_WITHOUT_VAULT_CLIENT)alertClassdroppedOrder, because composition parses every held fragment with the composing toolkit's schema:
alertClassgone. Those two can release now, on 0.31.forwardAuthnamesauth/auth.For the maintainer: the age key pair. Before edge hands over (#662), a Vault document at
secret/data/platform/cloudflareholdingCF_DNS_API_TOKEN(today the token sits atsecret/platform/edgeundercloudflare.dns_api_token). ThesignInblock waits for identity to go live (identity#25), so it is not in this change.ExtraToast commentedon Oct 27, 2026
A correction to the comment above:
alertClassis required whereverobservabilityis declared on 0.31 and 0.32 (and on 0.20.0, which n8n's CI pins), so it can't be dropped before 1.0.The order becomes:
alertClassand wires${identity:vaultRole}in one change, then releases. n8n dropsalertClassand movestools/deploy-kitto 1.0.0, then releases.ExtraToast commentedon Oct 27, 2026
Resume here (updated 2026-10-27)
e255f846, 2026-10-27. The whole estate (its files plus every Project'sdeploy/on main) givesaccepted (60 read). The parts:task checkgreen);feat/deploy-kit-1.0, pushed, tracked as Move the estate onto deploy-kit 1.0 estate#231;alertClassand other removed fields are dropped only in the change that moves a repository onto 1.0 (auth-api#116 dropped it early and feat: link a route's and a scrape's names to the Process and surface they mean #118 reverted it). ThesignInblock waits for identity (Phase 1 cutover: identity goes live identity#25).npm ci), thennode src/cli/index.ts validate <estate files> <every repo's deploy/>. Fetch each Project'sdeploy/withgh api repos/JorisJonkers-dev/<repo>/git/trees/main?recursive=1; auth's repository isauth-api.E_SCHEMA_VERSION_MISMATCHis raised since feat(model): refuse a fragment written at a model version the toolkit does not read #670 (in 1.0.0): a fragment at a newer minor than its composer is isolated.task checkneeds a committed tree (gen:check diffs git), and its tools come frommise exec --.ci: publish fragments with deploy-kit 1.0 (#390)
ExtraToast commentedon Oct 29, 2026
Verified on 2026-10-29 by reading values back, not exit codes. All four criteria hold.
1. delivery regenerates its types against the 1.0.0 schemas and builds.
9f4a7d61, release 0.16.0):third_party/deploy-kit/REFreadsae1d36fc7b27212c79f1a973449c396dfc5726e4, which is the commit tagv1.0.0resolves to.Taskfile.ymlpinsDEPLOY_KIT_REFto the same commit. Theinternal/deploykit/{lock,pins,resolved,clusterstate}/types_gen.gofiles are generated from those vendored schemas.push, head9f4a7d61):schemas:check,gen:check,test,build, all nine images andPipeline Completesucceeded.release-gatepod indelivery-systemrunsdelivery/release-gate@sha256:dca2a4b1…. That digest is the onev0.16.0resolves to in the registry, and the one the delivery 0.16.0 fragment'simages.lock.ymlnames. The image carries the labelorg.opencontainers.image.version=0.16.0. The livecollectordigest (sha256:80526921…) also matches the fragment.2.
delivery,_canaryand_estateare published on 1.0.0.delivery:intent-delivery:latestresolves tosha256:8e289648…, which is 0.16.0 at revision9f4a7d61, withfragment.ymlschemaVersion: 1.0.0. It was published by delivery's Release run 40578019705 through Publish Fragment16d241e4(= v0.36.0). That run logsdeploy-kit 1.0.0andaccepted (4 read)._estate: this render comes from the Platform document's fragment.intent-jorisjonkers.dev:latestresolves tosha256:0a5e9a10…, which is 0.31.2 at revisionef14336f, withschemaVersion: 1.0.0, and it carriesoffCluster.recipient. It was published by the estate's Release run 40568781182 through Publish Fragment v0.36.0. All seven fragment jobs logdeploy-kit 1.0.0andaccepted. Composition at 1.0.1 renderedrender-estate@sha256:701d47a4…, and that is the digest pinned inprojects/_estate/source.yaml(commitc605daf9, 27 Oct)._canary: there is no fragment to validate. The canary is a plain ConfigMap thatcompose.yml's canary job pushes withflux push, not a deploy-kit render, so its content does not depend on the toolkit version. Its pin,render/canary@sha256:f69adb82…from 2 Oct, still passes the signer check: OCIRepositorycanaryreadsSourceVerified=True, and its applied ConfigMapflux-system/estate-canaryreadscommit: c2c21152…, the same commit as the artifact's revision annotation. Nothing on 1.0 asks for it to be republished.3. The estate composes, and the lock names 1.x.
composed:latestresolves tosha256:6418df4e…, and itsCOMMITisfa7f25df. That is the nightly safety-net run 40845550384 on 29 Oct (schedule, headfa7f25df, success).lock.jsonreadstoolkitVersion: 1.0.1andschemaVersion: 1.0.1, and all 24 fragments it composes carryschemaVersion: 1.0.0. 1.0.1 is a patch on the 1.0 contract, so this meets the criterion's intent.composition.jsongives_estatecontent hashsha256:563d4a33…anddeliverysha256:11862af7…, bothmoves: false. Those are thecontent-hashannotations on the pinnedrender-estateandrender/deliveryartifacts.4. The Reconcile Units are Ready, and a consumer-visible value checks out.
These Kustomizations read
Ready=True ReconciliationSucceeded:apps-delivery(appliedsha256:a8b4f3ee…);canary(sha256:f69adb82…);estate-stable-addressesandestate-vso-secrets(sha256:701d47a4…);estate-pins(main@sha1:0c768e63, estate main HEAD);apps-estate-dashboard.The OCIRepositories
project-delivery,canaryandestatereadReady=True SourceVerified=True, and each revision equals the digest in its pin source.Consumer-visible value: JorisJonkers-dev/delivery has GitHub Deployment 7369721745, environment
production, sha9f4a7d61,version: 0.16.0, artifactrender/delivery@sha256:a8b4f3ee…. That is the same digest Flux applied. Its latest status issuccess, "delivery 0.16.0 applied by Flux and ready" (20:49Z, 27 Oct). It wentin_progress→failure(health check) →success, so the status tracks what Flux actually did. The release-gate image digest under criterion 1 is a second consumer-visible value.What changes next: estate main's
toolkit.ymlnow readsdeploy-kit: 1.2.0(JorisJonkers-dev/estate#252, JorisJonkers-dev/estate#253), andrelease.ymlpublishes through Publish Fragment v0.37.0 (deploy-kit 1.2.0). The next composition will therefore name toolkit 1.2.0.The handovers #656, #657, #658, #659, #660, #661, #662 and #663 no longer have this blocker. Each still has its own, such as the runbook.