feat: supabase stack seeds a requires on the substrate at create

A stack's substrate dependency now becomes a real encoded `requires` at
`castle program create` time (STACK_REQUIRES), so the relationship graph shows it.
This keeps `stack` uncoupled from the runtime model — the stack declares the edge
once at creation; the graph only ever reads the encoded `requires`, never the stack.
This commit is contained in:
2026-07-05 15:24:18 -07:00
parent b9d38be707
commit d14b9eafa7
3 changed files with 19 additions and 1 deletions

View File

@@ -16,6 +16,7 @@ from castle_cli.manifest import (
ManageSpec,
PathDeployment,
ProgramSpec,
Requirement,
RunPython,
SystemdDeployment,
SystemdSpec,
@@ -38,6 +39,14 @@ STACK_BUILD_OUTPUTS: dict[str, str] = {
"react-vite": "dist",
}
# Substrate a stack's apps depend on — seeded as a `requires` at creation so the
# relationship graph shows it. This keeps `stack` uncoupled from the runtime model:
# the stack declares the edge once here; the graph only ever reads the encoded
# `requires`, never the stack. See docs/relationships.md.
STACK_REQUIRES: dict[str, list[Requirement]] = {
"supabase": [Requirement(kind="deployment", ref="supabase")],
}
def next_available_port(config: object) -> int:
"""Find the next available port starting from 9001 (9000 is reserved for gateway)."""
@@ -111,6 +120,8 @@ def run_create(args: argparse.Namespace) -> int:
source=str(project_dir),
stack=stack,
build=build,
# Seed the stack's substrate dependency (e.g. supabase) as a real `requires`.
requires=list(STACK_REQUIRES.get(stack or "", [])),
)
if kind == "tool":
# A PATH-managed deployment: installed via `uv tool install`, no unit/route.
@@ -120,7 +131,10 @@ def run_create(args: argparse.Namespace) -> int:
elif kind == "static":
# A caddy-managed static deployment: no systemd unit, served from the build dir.
config.deployments[name] = CaddyDeployment(
id=name, manager="caddy", program=name, root=static_root or "dist",
id=name,
manager="caddy",
program=name,
root=static_root or "dist",
description=description,
)
elif kind == "service":

View File

@@ -21,6 +21,7 @@ from castle_core.manifest import ( # noqa: F401 — explicit re-exports for typ
Reach,
ReadinessHttpGet,
RemoteDeployment,
Requirement,
RestartPolicy,
RunCommand,
RunCompose,