state has no project registry — the list of what exists lives only in the operator's head #25
Labels
No labels
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-triage
ready
release
scope:apply
scope:capture
scope:coolify-api
scope:fleet
scope:manifest
scope:secrets
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/cast#25
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
The state repo cannot say which projects exist.
environments.yamlis keyedby environment — but the state it increasingly needs to hold is scoped by
project × environment:
smoke_target: core— which names incubator's compose app, under a key thatclaims to be about the environment, and will be simply wrong the day a
second project deploys into
prodgithub_apps.<repo>already solved this correctly, by keying on the repo. It isthe registry in embryo. Make it first-class:
Why it matters beyond tidiness
Three things become possible, and none of them can be done today:
cast diff --all/apply --allneed a list toiterate. Today "every project" is a thing the operator remembers.
repo" is currently an assumption. It cannot even be attempted without
knowing what was on it. The registry is the difference between a documented
recovery and an archaeology exercise.
environment key.
Coordination
⚠️ #21 is being worked in a parallel session. That issue covers
destinations and the project-scoped state shape; this one covers the
registry itself (the list of projects, and fleet iteration over it). They
touch the same file and should land in a compatible order — whichever goes
first should define the
projects:block, and the other should build on itrather than inventing a second shape.
#28 delivered the shape. What remains is the authority.
environments.<env>.projects.<org>/<repo>now exists, keyed by full slug with a bare-repo fallback — exactly thegithub_appsprecedent this issue asked for, andsmoke_targethas already moved into it. The structural half of this issue is done.But the block is optional ("an environment whose server hosts one project declares neither"), and that is correct for its purpose — a destination you don't need shouldn't have to be declared. It does mean the block is not yet a registry: a project that exists but declares nothing is invisible to it.
That gap is what the two dependents actually need:
--all) — iteratingprojects:today iterates the projects that happened to need per-project state, not the projects that exist. A fleet diff that silently skips an undeclared project reads exactly like a clean one.So the remaining ask is narrow: make absence mean "does not exist", not "not declared". Either every project deploying into an environment gets an entry (even an empty one), or fleet ops read a separate authoritative list. Both are cheap; the point is that something must be able to say "these, and no others."