Nested projects. Inherited everything.
A Vadyl project is sovereign — its own runtime, its own bindings, its own lifecycle. But it lives inside a hierarchy: child projects inherit provider bindings, capability grants, governance envelopes, auth policies, federation rules, and quota attribution from their ancestors. Override what you must. Inherit what you don't.
One canonical project tree. O(1) ancestry queries.
Every Vadyl deployment seeds a single root project. From there, organizations, divisions, environments, services, sandboxes — all nested as ordinary projects. The closure table makes parent / ancestor / descendant queries instant. The lifecycle state machine makes every transition deliberate.
Closure-table topology
ProjectTopologyEdge materializes (ancestor, descendant, depth) tuples. O(1) queries for the full tree without recursive CTEs.
Five-state lifecycle
Provisioning → Active ↔ Suspended → Archived → DeprovisionPending. Each state gates reads, writes, admin separately. No silent transitions.
Sovereign runtime
Each project compiles its own runtime descriptor — provider bindings, governance envelope, capability grants, auth policy, billing scope. Cached, invalidated coherently across instances.
Inheritance with explicit override.
Children get their parent's setup by default. Override only what differs. Closer-ancestor-wins for bindings; deterministic merge discipline for envelopes.
Provider bindings
Database, cache, storage, distribution, identity — declared once on a parent, inherited by every descendant. Children with no binding fall through. Override at any level.
Governance envelope
~30 axes — allowed providers, allowed federation targets, max auth strength, quota caps, permission bits, restriction bits — merged via intersection (allowlists narrow), union (denylists grow), min (caps), max (auth strength), AND, OR.
Capability grants
HostChildProjects (parent → direct children), DelegatedManagement (ancestor → any descendant), SelfWithHostChildProjects, CrossProjectFederation. All time-bounded, auditable, revocable.
Auth policy
Minimum auth strength merges down the chain. A parent requiring MFA cannot be relaxed by a child. The scope chain is walked top-down, numerics resolved by min/max.
Cache + secret bindings
Cache provider bindings inherit closer-ancestor-wins. Secret references are resolved through the same scope chain. No raw connection strings on the wire — ever.
Federation, surfaces, quotas
Federated contracts, installable-surface installations, billing attribution, usage rollups — all carry the right project context, with each child inheriting its parent's defaults until overridden.
What an actor can do across the tree, by design
Data intent. Read or write entity rows. Always self-only. A parent admin cannot read a child's data without an explicit FederatedContract — deny-by-default cross-project data access is absolute.
Management intent. Create, suspend, archive, deprovision a project. Mutate provider bindings, capability grants, branching state, surface installations. Routes through the hierarchy: parent → direct child via HostChildProjects; ancestor → any descendant via DelegatedManagement.
ChildCreation intent. Spawn a sub-project. Requires HostChildProjects on the parent. The new project inherits parent envelope at creation time and recompiles whenever the parent's envelope tightens.
Three intent kinds × the canonical IProjectAuthorizationService — one authority, walked the same way every time. No second auth model, no privileged dashboard path. The middleware classifies every endpoint by intent; the service decides every check.
Merged top-down per project
Each gating reads, writes, admin separately
Data · Management · ChildCreation
Fail-closed at every site
Provision a project tree in minutes.
Sovereign per-project runtime. Inherited per-project setup. Every mutation guarded by the descendant envelope. No assembly required.