Sub-Prism Inheritance
Overview
Every prism can contain a hierarchy of sub-prisms declared under bundled_prisms. Each sub-prism is a YAML config file that contributes settings to the final merged configuration. Like a prism refracting white light into a spectrum, this system refracts organizational complexity into layered, composable configurations.
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#eef2ff', 'primaryTextColor': '#1e293b', 'primaryBorderColor': '#6366f1', 'lineColor': '#6366f1', 'secondaryColor': '#f0fdf4', 'tertiaryColor': '#faf5ff', 'background': '#ffffff', 'mainBkg': '#eef2ff', 'nodeBorder': '#6366f1', 'clusterBkg': '#f8faff', 'edgeLabelBackground': '#ffffff'}}}%%
flowchart TD
P["💎 fortune500.prism"]
subgraph required["Required — applied to everyone"]
B["base\nEnterprise standards\nproxy · security · git"]
end
subgraph optional["Optional — user selects one per tier"]
D1["divisions / technology"]
D2["divisions / digital"]
D3["divisions / data"]
R1["roles / software-engineer"]
R2["roles / devops-engineer"]
R3["roles / data-engineer"]
end
subgraph result["Merged Result"]
M["merged-config.yaml\ntools_required · environment\nrepositories · security"]
end
P --> required
P --> optional
required --> result
D1 --> result
R2 --> result
style required fill:#f0fdf4,stroke:#22c55e,color:#1e293b
style optional fill:#eef2ff,stroke:#6366f1,color:#1e293b
style result fill:#faf5ff,stroke:#a855f7,color:#1e293b
style P fill:#fff7ed,stroke:#f97316,color:#1e293b
style B fill:#dcfce7,stroke:#22c55e,color:#1e293b
style M fill:#f3e8ff,stroke:#a855f7,color:#1e293b
Each layer inherits and extends from previous layers:
- ✅ Base defines company-wide standards (proxy, security, required tools)
- ✅ Division adds division-specific tools and tech stacks
- ✅ Role adds role-specific tools and workflows
- ✅ Business unit adds compliance and context-specific settings
How Sub-Prism Merging Works
When you install a prism, the engine:
- Loads all required sub-prisms automatically (the
basetier) - Applies any user-selected sub-prisms from optional tiers
- Deep-merges them in declaration order using
ConfigMerger - Writes the merged result to
config/merged-config.yaml
The merged config drives everything: which tools get installed, which repos get cloned, which proxy settings apply.
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#eef2ff', 'primaryTextColor': '#1e293b', 'primaryBorderColor': '#6366f1', 'lineColor': '#6366f1', 'secondaryColor': '#f0fdf4', 'tertiaryColor': '#faf5ff', 'background': '#ffffff', 'mainBkg': '#eef2ff', 'nodeBorder': '#6366f1', 'edgeLabelBackground': '#ffffff'}}}%%
sequenceDiagram
participant E as InstallationEngine
participant B as base/company.yaml
participant D as divisions/technology.yaml
participant R as roles/devops-engineer.yaml
participant M as merged-config.yaml
E->>B: load (required)
B-->>E: tools=[git,docker] env={proxy}
E->>D: load (user selected)
D-->>E: tools=[vscode,kubectl] stack={...}
E->>R: load (user selected)
R-->>E: tools=[terraform,ansible]
Note over E: union merge tools_required
Note over E: deep_merge environment
E->>M: write final merged config
M-->>E: git·docker·vscode·kubectl·terraform·ansible
Merge Strategies
Controlled by config/inheritance.yaml (or the built-in defaults):
Arrays (lists):
merge_strategy:
arrays:
tools_required: "union" # Combine, remove duplicates
resources: "append" # Keep all, in order
onboarding_tasks: "append"
Objects (dicts):
merge_strategy:
objects:
environment: "deep_merge" # Recursively merge
git: "override" # Later layer wins
career: "user_only" # Only the user can set this
Example — union merge:
# Base sub-prism
tools_required: [git, docker, kubectl]
# Role sub-prism
tools_required: [terraform, helm]
# Merged result:
tools_required: [git, docker, kubectl, terraform, helm]
Example — deep_merge:
# Base
environment:
proxy:
http: "http://proxy.company.com:8080"
maven:
url: "https://maven.company.com"
# Division
environment:
npm:
registry: "https://npm.company.com"
# Merged:
environment:
proxy:
http: "http://proxy.company.com:8080"
maven:
url: "https://maven.company.com"
npm:
registry: "https://npm.company.com"
Real-World Example
Scenario: New Developer at Fortune 500
Selected sub-prisms:
base→ enterprise base (required, auto-applied)divisions/technology.yaml→ Technology Divisionroles/devops-engineer.yaml→ DevOps Engineer
Merged result:
# From base:
environment:
proxy:
http: "http://proxy.company.com:8080"
vpn:
required: true
tools_required:
- git
- docker
- kubectl
- python3
security:
sso_required: true
mfa_required: true
# From Technology Division:
tools_required:
- vscode
- docker
- kubectl
tech_stack:
languages: [Python, TypeScript, Java]
platforms: [Kubernetes, AWS, GCP]
# From DevOps Engineer:
tools_required:
- terraform
- ansible
- kubectl
- docker
- git
Final merged tools_required (union): git, docker, kubectl, python3, vscode, terraform, ansible
Defining Sub-Prisms in bundled_prisms
bundled_prisms:
# Required tier — applied to every user
base:
- id: "company-base"
name: "Company Base"
description: "Company-wide settings: proxy, git, required tools"
required: true # ← always included
config: "base/company.yaml"
# Optional tier — user picks one
divisions:
- id: "technology"
name: "Technology Division"
description: "IT and software engineering"
config: "divisions/technology.yaml"
- id: "digital"
name: "Digital Division"
description: "Digital products and platforms"
config: "divisions/digital.yaml"
# Optional tier — user picks one
roles:
- id: "software-engineer"
name: "Software Engineer"
config: "roles/software-engineer.yaml"
- id: "devops-engineer"
name: "DevOps Engineer"
config: "roles/devops-engineer.yaml"
Sub-Prism Config File Structure
Each sub-prism is a plain YAML file. Any keys it contains are merged into the final config. Tools are referenced by string name only — they must exist in the centralized tool-registry.yaml:
# base/company.yaml
company:
name: "My Company"
domain: "mycompany.com"
environment:
proxy:
http: "http://proxy.mycompany.com:8080"
vpn:
required: true
tools_required:
- git
- docker
- kubectl
security:
sso_required: true
# divisions/technology.yaml
division:
id: "technology"
name: "Technology Division"
tools_required:
- vscode
- kubernetes
tech_stack:
languages: [Python, TypeScript]
# roles/devops-engineer.yaml
role:
id: "devops-engineer"
name: "DevOps Engineer"
tools_required:
- terraform
- ansible
- helm
Environment Variable Substitution
Use ${VAR} and ${VAR:-default} placeholders in sub-prism configs:
git:
user:
name: "${USER}"
email: "${USER}@mycompany.com"
cloud:
region: "${CLOUD_REGION:-us-central1}"
These are resolved at install time by the engine.
Python API
from scripts.config_merger import load_merged_config
config = load_merged_config(
company="config/base/company.yaml",
sub_org="config/orgs/engineering.yaml",
department="config/departments/supply-chain.yaml",
team="config/teams/receiving-systems.yaml",
user="config/user-profile.yaml"
)
proxy = config["environment"]["proxy"]["http"]
tools = config["tools_required"]
repos = config.get("repositories", [])
Benefits
✅ DRY — define company standards once, inherit everywhere ✅ Flexible — each layer can override or extend ✅ Scalable — add new teams without duplicating config ✅ Maintainable — update the base once, all users get the change ✅ Contextual — each developer gets exactly what their role needs