guildhall/apps/guildhall_ops_db/priv/repo/seeds.exs
Tyler J King 38cf2b7c6b feat(orchestrator): governance correctness — override revocation + bootstrap ceremony
Wire founding override enforcement (TTL guard, periodic sweep, second-
master auto-revoke, manual revocation) and replace the approve stub with
a real Ed25519 signing flow through two bootstrap modes (self-sovereign
and partner-hosted with Guildhouse as default partner).

Pipeline now pauses at awaiting_approval, returns schematic_hash for the
signer, and resumes via POST /api/approvals webhook. HostingAgreement
table + HostingCeremony module support partner-hosted onboarding with
auto-ratification for Guildhouse-as-partner.

70 tests, 0 failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Tyler J King <tking@guildhouse.dev>
2026-05-16 12:54:55 -04:00

259 lines
8.9 KiB
Elixir

# Dev seed data for guildhall_ops_db.
# Matches the nine JSONB content examples in
# DESIGN-OPS-DB-CHAIN-OF-CUSTODY-0001 §2.3.
#
# Run with: mix run apps/guildhall_ops_db/priv/repo/seeds.exs
alias Guildhall.OpsDb.{
Repo,
Guild,
AccordBinding,
GovernedArtifact,
CustodyTransition,
DeploymentState,
VerificationResult
}
now = DateTime.utc_now()
# ────────────────────────────────────────────────────────
# 0. Guildhouse operational guild (default hosting partner)
# ────────────────────────────────────────────────────────
_guildhouse =
Repo.insert!(
%Guild{}
|> Guild.changeset(%{
guild_id: 0x001,
name: "Guildhouse Operations",
slug: "guildhouse-ops",
guild_type: "nsp",
status: "active",
registrant_did: "did:web:guildhouse.dev:user:tking",
contact_did: "did:web:guildhouse.dev:user:tking",
trust_domain: "guildhouse.dev"
}),
on_conflict: :nothing,
conflict_target: :slug
)
# ────────────────────────────────────────────────────────
# 1. Accord binding (shared by all artifacts below)
# ────────────────────────────────────────────────────────
accord =
Repo.insert!(%AccordBinding{
accord_cid: "sha256:dev-accord-example",
accord_name: "acme-saas-dev",
member_dids: ["did:web:guildhouse.dev:user:tking"],
witness_dids: ["did:web:guildhouse.dev:user:tking"],
ceremony_classes: ["SingleApproval"],
verification_interval_sec: 300,
chronicle_retention_days: 90,
effective_from: now,
accord_terms: %{
"name" => "Development Accord",
"tier_policy" => %{"default" => "a"}
}
})
# ────────────────────────────────────────────────────────
# 2. Governed artifacts — nine examples from §2.3
# ────────────────────────────────────────────────────────
artifacts = [
%{
cid: "sha256:intune-profile-example",
artifact_type: "intune_config_profile",
artifact_name: "Production Baseline",
artifact_runtime: "intune",
tier: "b",
content: %{
"@odata.type" => "#microsoft.graph.windows10GeneralConfiguration",
"displayName" => "Production Baseline",
"bitLockerEncryptDevice" => true,
"defenderRequireRealTimeMonitoring" => true,
"passwordMinimumLength" => 12,
"assignments" => [%{"groupId" => "corp-devices"}]
}
},
%{
cid: "sha256:dns-zone-example",
artifact_type: "dns_zone",
artifact_name: "guildhouse.dev zone",
artifact_runtime: "zone",
tier: "c",
content: %{
"zone_apex" => "guildhouse.dev.",
"serial" => 2_026_041_701,
"records" => [
%{"name" => "@", "type" => "SOA", "rdata" => "ns1.guildhouse.dev. ..."},
%{"name" => "@", "type" => "NS", "rdata" => "ns1.guildhouse.dev."},
%{"name" => "auth", "type" => "A", "rdata" => "10.0.0.10"}
]
}
},
%{
cid: "sha256:dsc-bitlocker-example",
artifact_type: "dsc_configuration",
artifact_name: "EnsureBitLockerEnabled",
artifact_runtime: "mof",
tier: "b",
content: %{
"instances" => [
%{
"class" => "MSFT_BitLockerResource",
"name" => "EnsureBitLockerEnabled",
"properties" => %{
"MountPoint" => "C:",
"PrimaryProtector" => "TpmProtector",
"AutoUnlock" => true
}
}
]
}
},
%{
cid: "sha256:yang-running-config-example",
artifact_type: "restconf_config",
artifact_name: "edge-router-1 interfaces",
artifact_runtime: "json",
tier: "c",
content: %{
"ietf-interfaces:interfaces" => %{
"interface" => [
%{
"name" => "GigabitEthernet0/0",
"type" => "iana-if-type:ethernetCsmacd",
"enabled" => true
}
]
}
}
},
%{
cid: "sha256:helm-values-example",
artifact_type: "helm_values",
artifact_name: "substrate-operator production values",
artifact_runtime: "values",
tier: "b",
content: %{
"bound_chart_cid" => "sha256:abc...",
"environment" => "production",
"image" => %{"digest" => "sha256:def..."},
"replicas" => 3
}
},
%{
cid: "sha256:jea-application-role-example",
artifact_type: "jea_role_capability",
artifact_name: "Application-class JEA role",
artifact_runtime: "psrc",
tier: "c",
content: %{
"visible_cmdlets" => ["Get-Service", "Get-Process", "Test-DscConfiguration"],
"visible_providers" => ["FileSystem"],
"language_mode" => "ConstrainedLanguage",
"session_type" => "RestrictedRemoteServer"
}
},
%{
cid: "sha256:conditional-access-example",
artifact_type: "entra_conditional_access",
artifact_name: "Require compliant device",
artifact_runtime: "json",
tier: "c",
content: %{
"displayName" => "Require compliant device for corp resources",
"conditions" => %{"users" => %{"includeGroups" => ["all-employees"]}},
"grantControls" => %{"builtInControls" => ["compliantDevice"]}
}
},
%{
cid: "sha256:tls-keycloak-cert-example",
artifact_type: "tls_server_cert",
artifact_name: "keycloak.guildhouse.dev",
artifact_runtime: "x509",
tier: "b",
content: %{
"subject" => "CN=keycloak.guildhouse.dev",
"not_before" => "2026-04-17T00:00:00Z",
"not_after" => "2027-04-17T00:00:00Z",
"fingerprint_sha256" => "abc...",
"ct_log_refs" => []
}
},
%{
cid: "sha256:oci-image-example",
artifact_type: "oci_image",
artifact_name: "ghcr.io/guildhouse/substrate-operator",
artifact_runtime: "oci",
tier: "b",
content: %{
"image_reference" => "ghcr.io/guildhouse/substrate-operator",
"digest" => "sha256:a1b2c3...",
"architectures" => ["linux/amd64", "linux/arm64"],
"sbom_cid" => "sha256:..."
}
}
]
inserted =
Enum.map(artifacts, fn attrs ->
%GovernedArtifact{accord_binding_id: accord.id, human_authored: true}
|> GovernedArtifact.changeset(attrs)
|> Repo.insert!()
end)
# ────────────────────────────────────────────────────────
# 3. One custody transition per artifact (proposed → ceremony_open)
# ────────────────────────────────────────────────────────
Enum.each(inserted, fn artifact ->
Repo.insert!(%CustodyTransition{
governed_artifact_id: artifact.id,
sequence_number: 1,
from_state: "proposed",
to_state: "ceremony_open",
actor_did: "did:web:guildhouse.dev:user:tking",
ceremony_id: "ceremony-dev-#{artifact.id}",
witness_sigs: [],
transitioned_at: now
})
end)
# ────────────────────────────────────────────────────────
# 4. Mix of deployment_states (healthy / drifted)
# ────────────────────────────────────────────────────────
inserted
|> Enum.with_index()
|> Enum.each(fn {artifact, idx} ->
drift = if rem(idx, 3) == 0, do: "drift", else: "match"
Repo.insert!(%DeploymentState{
governed_artifact_id: artifact.id,
target_kind: "dev-cluster",
target_identifier: "hetzner-talos",
deployed_cid: artifact.cid,
desired_cid: artifact.cid,
last_deployed_at: now,
last_reconciled_at: now,
drift_status: drift
})
end)
# ────────────────────────────────────────────────────────
# 5. Recent verification results
# ────────────────────────────────────────────────────────
Enum.each(inserted, fn artifact ->
Repo.insert!(%VerificationResult{
governed_artifact_id: artifact.id,
verified_cid: artifact.cid,
target_kind: "dev-cluster",
target_identifier: "hetzner-talos",
layer: "layer1",
verdict: "match",
verified_at: now,
verifier_did: "did:web:guildhouse.dev:verifier:local",
verifier_infrastructure: "local",
evidence: %{"method" => "seed_data"}
})
end)
IO.puts("Seeded #{length(inserted)} governed artifacts under Accord #{accord.accord_name}.")