83 lines
3.6 KiB
Text
83 lines
3.6 KiB
Text
|
|
{
|
||
|
|
id = "validate-radicle-governance",
|
||
|
|
strategy = 'Override,
|
||
|
|
description = "Verify each workspace has the three required Radicle repos (policy, desired, state) with correct delegation profiles and M-of-N quorum (ADR-038).",
|
||
|
|
version = "1.0",
|
||
|
|
params = {
|
||
|
|
workspace | String | doc "Workspace name (e.g. 'libre-wuji')" | default = "libre-wuji",
|
||
|
|
radicle_home | String | doc "Path to Radicle home directory" | default = "~/.radicle",
|
||
|
|
ops_controller_key | String | doc "Expected public key fingerprint for the ops-controller delegate on the state repo" | default = "",
|
||
|
|
expected_quorum | Number | doc "Expected M threshold for policy/desired repo delegation" | default = 2,
|
||
|
|
},
|
||
|
|
steps = [
|
||
|
|
{
|
||
|
|
id = "check_radicle_node_running",
|
||
|
|
actor = 'Agent,
|
||
|
|
name = "Radicle node (radicled) is running",
|
||
|
|
cmd = "rad self --json | jq -e '.node.status == \"running\"'",
|
||
|
|
depends_on = [],
|
||
|
|
on_error = "abort",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id = "check_policy_repo_exists",
|
||
|
|
actor = 'Agent,
|
||
|
|
name = "policy-{workspace} Radicle repo exists locally",
|
||
|
|
cmd = "rad inspect --json $(rad ls --json | jq -r '.[] | select(.name == \"policy-{workspace}\") | .rid') | jq -e '.rid'",
|
||
|
|
depends_on = ["check_radicle_node_running"],
|
||
|
|
on_error = "abort",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id = "check_desired_repo_exists",
|
||
|
|
actor = 'Agent,
|
||
|
|
name = "{workspace}-desired Radicle repo exists locally",
|
||
|
|
cmd = "rad inspect --json $(rad ls --json | jq -r '.[] | select(.name == \"{workspace}-desired\") | .rid') | jq -e '.rid'",
|
||
|
|
depends_on = ["check_radicle_node_running"],
|
||
|
|
on_error = "abort",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id = "check_state_repo_exists",
|
||
|
|
actor = 'Agent,
|
||
|
|
name = "{workspace}-state Radicle repo exists locally",
|
||
|
|
cmd = "rad inspect --json $(rad ls --json | jq -r '.[] | select(.name == \"{workspace}-state\") | .rid') | jq -e '.rid'",
|
||
|
|
depends_on = ["check_radicle_node_running"],
|
||
|
|
on_error = "abort",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id = "check_policy_repo_quorum",
|
||
|
|
actor = 'Agent,
|
||
|
|
name = "policy-{workspace} delegation threshold meets expected quorum",
|
||
|
|
cmd = "rad inspect --json $(rad ls --json | jq -r '.[] | select(.name == \"policy-{workspace}\") | .rid') | jq -e '.delegates | length >= {expected_quorum}'",
|
||
|
|
depends_on = ["check_policy_repo_exists"],
|
||
|
|
on_error = "abort",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id = "check_state_repo_sole_delegate",
|
||
|
|
actor = 'Agent,
|
||
|
|
name = "{workspace}-state repo has exactly one delegate (ops-controller key)",
|
||
|
|
cmd = "rad inspect --json $(rad ls --json | jq -r '.[] | select(.name == \"{workspace}-state\") | .rid') | jq -e '.delegates | length == 1 and .[0].key == \"{ops_controller_key}\"'",
|
||
|
|
depends_on = ["check_state_repo_exists"],
|
||
|
|
on_error = "abort",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id = "check_audit_commits_signed",
|
||
|
|
actor = 'Agent,
|
||
|
|
name = "Recent commits on {workspace}-state are GPG/SSH-signed by ops-controller",
|
||
|
|
cmd = "git -C {radicle_home}/storage/$(rad ls --json | jq -r '.[] | select(.name == \"{workspace}-state\") | .rid') log --show-signature -5 | grep -c 'Good signature'",
|
||
|
|
depends_on = ["check_state_repo_sole_delegate"],
|
||
|
|
on_error = "warn",
|
||
|
|
},
|
||
|
|
{
|
||
|
|
id = "summary_report",
|
||
|
|
actor = 'Agent,
|
||
|
|
name = "Emit governance validation summary for workspace={workspace}",
|
||
|
|
cmd = "echo 'radicle-governance validation complete: policy/desired/state repos confirmed, quorum={expected_quorum}, sole-delegate verified'",
|
||
|
|
depends_on = [
|
||
|
|
"check_policy_repo_quorum",
|
||
|
|
"check_state_repo_sole_delegate",
|
||
|
|
"check_audit_commits_signed",
|
||
|
|
],
|
||
|
|
on_error = "warn",
|
||
|
|
},
|
||
|
|
],
|
||
|
|
}
|