Delete synthetic Idunn completion
This commit is contained in:
parent
43ec46df36
commit
90e14c3dc6
10 changed files with 31 additions and 867 deletions
|
|
@ -1,716 +0,0 @@
|
|||
use anyhow::Context;
|
||||
use anyhow::Result;
|
||||
use anyhow::anyhow;
|
||||
use chrono::Utc;
|
||||
use epiphany_core::EpiphanyCultMeshIdunnAftercareAuditReceiptEntry;
|
||||
use epiphany_core::EpiphanyCultMeshIdunnDeploymentReceiptEntry;
|
||||
use epiphany_core::write_epiphany_cultmesh_idunn_aftercare_audit_receipt;
|
||||
use epiphany_core::write_epiphany_cultmesh_idunn_deployment_receipt;
|
||||
use serde_json::Value;
|
||||
use serde_json::json;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let args = Args::parse()?;
|
||||
let result = run_smoke(args)?;
|
||||
println!("{}", serde_json::to_string_pretty(&result)?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct Args {
|
||||
root: PathBuf,
|
||||
}
|
||||
|
||||
impl Args {
|
||||
fn parse() -> Result<Self> {
|
||||
let mut root = env::current_dir().context("failed to resolve current directory")?;
|
||||
let mut args = env::args().skip(1).peekable();
|
||||
while let Some(arg) = args.next() {
|
||||
match arg.as_str() {
|
||||
"--root" => root = take_path(&mut args, "--root")?,
|
||||
other => return Err(anyhow!("unexpected argument {other:?}")),
|
||||
}
|
||||
}
|
||||
Ok(Self { root })
|
||||
}
|
||||
}
|
||||
|
||||
fn run_smoke(args: Args) -> Result<Value> {
|
||||
let root = args
|
||||
.root
|
||||
.canonicalize()
|
||||
.with_context(|| format!("failed to resolve {}", args.root.display()))?;
|
||||
let manifest = root.join("epiphany-core").join("Cargo.toml");
|
||||
if !manifest.exists() {
|
||||
return Err(anyhow!(
|
||||
"could not find epiphany-core manifest at {}",
|
||||
manifest.display()
|
||||
));
|
||||
}
|
||||
let smoke_root = root.join(".epiphany-smoke");
|
||||
fs::create_dir_all(&smoke_root)
|
||||
.with_context(|| format!("failed to create {}", smoke_root.display()))?;
|
||||
let stamp = Utc::now().format("%Y%m%d-%H%M%S").to_string();
|
||||
let smoke_dir = smoke_root.join(format!("repo-deployment-config-family-{stamp}"));
|
||||
if smoke_dir.exists() {
|
||||
fs::remove_dir_all(&smoke_dir)
|
||||
.with_context(|| format!("failed to clear {}", smoke_dir.display()))?;
|
||||
}
|
||||
fs::create_dir_all(&smoke_dir)
|
||||
.with_context(|| format!("failed to create {}", smoke_dir.display()))?;
|
||||
|
||||
let repo = smoke_dir.join("repo-body");
|
||||
fs::create_dir_all(&repo).with_context(|| format!("failed to create {}", repo.display()))?;
|
||||
git(["init"], &repo)?;
|
||||
git(
|
||||
["config", "user.email", "epiphany-smoke@example.invalid"],
|
||||
&repo,
|
||||
)?;
|
||||
git(["config", "user.name", "Epiphany Smoke"], &repo)?;
|
||||
fs::write(
|
||||
repo.join("README.md"),
|
||||
"# Repo Deployment Config Family Smoke\n\nThis repository proves branch-local Idunn deployment config cargo without deploy authority.\n",
|
||||
)
|
||||
.with_context(|| format!("failed to seed {}", repo.join("README.md").display()))?;
|
||||
fs::create_dir_all(repo.join("deploy"))
|
||||
.with_context(|| format!("failed to create {}", repo.join("deploy").display()))?;
|
||||
fs::write(
|
||||
repo.join("deploy").join("idunn-deploy.ps1"),
|
||||
"# reviewed by Idunn before use\nWrite-Output 'deployment script placeholder'\n",
|
||||
)
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"failed to seed {}",
|
||||
repo.join("deploy").join("idunn-deploy.ps1").display()
|
||||
)
|
||||
})?;
|
||||
git(["add", "README.md", "deploy/idunn-deploy.ps1"], &repo)?;
|
||||
git(
|
||||
["commit", "-m", "Seed repo deployment config smoke body"],
|
||||
&repo,
|
||||
)?;
|
||||
git(
|
||||
["switch", "-c", "epiphany/repo-deployment-config-family"],
|
||||
&repo,
|
||||
)?;
|
||||
|
||||
let item = "repo-deployment-config-family";
|
||||
let target_path = ".epiphany/deployment.toml";
|
||||
let local_verse = repo.join(".epiphany").join("local-verse.ccmp");
|
||||
cargo_json(
|
||||
&manifest,
|
||||
"epiphany-repo",
|
||||
&[
|
||||
"init",
|
||||
"--workspace",
|
||||
path_str(&repo)?,
|
||||
"--epiphany-root",
|
||||
path_str(&root)?,
|
||||
"--swarm-id",
|
||||
"repo-deployment-config-family-smoke",
|
||||
"--topic",
|
||||
"repo-deployment-config-family",
|
||||
],
|
||||
&root,
|
||||
)?;
|
||||
cargo_json(
|
||||
&manifest,
|
||||
"epiphany-swarm",
|
||||
&[
|
||||
"online",
|
||||
"--workspace",
|
||||
path_str(&repo)?,
|
||||
"--epiphany-root",
|
||||
path_str(&root)?,
|
||||
"--runtime-id",
|
||||
"repo-deployment-config-family-smoke",
|
||||
"--local-verse-store",
|
||||
path_str(&local_verse)?,
|
||||
],
|
||||
&root,
|
||||
)?;
|
||||
cargo_json(
|
||||
&manifest,
|
||||
"epiphany-work",
|
||||
&[
|
||||
"accept",
|
||||
"--workspace",
|
||||
path_str(&repo)?,
|
||||
"--from",
|
||||
"persona",
|
||||
"--item",
|
||||
item,
|
||||
"--summary",
|
||||
"Configure an Idunn-watched git-push deployment contract without granting deployment authority.",
|
||||
"--candidate-action-ref",
|
||||
"candidate-action://repo-deployment-config-family/idunn-config",
|
||||
"--public-discussion-ref",
|
||||
"epiphany-global/persona-collaboration/repo-deployment-config-family",
|
||||
],
|
||||
&root,
|
||||
)?;
|
||||
let plan = cargo_json(
|
||||
&manifest,
|
||||
"epiphany-work",
|
||||
&[
|
||||
"derive-plan",
|
||||
"--workspace",
|
||||
path_str(&repo)?,
|
||||
"--item",
|
||||
item,
|
||||
"--action-family",
|
||||
"repo-deployment-config",
|
||||
"--model-ref",
|
||||
"repo-deployment-config-family-smoke-imagination-v1",
|
||||
"--model-authored",
|
||||
],
|
||||
&root,
|
||||
)?;
|
||||
for _ in 0..4 {
|
||||
cargo_json(
|
||||
&manifest,
|
||||
"epiphany-work",
|
||||
&[
|
||||
"tick",
|
||||
"--workspace",
|
||||
path_str(&repo)?,
|
||||
"--epiphany-root",
|
||||
path_str(&root)?,
|
||||
"--item",
|
||||
item,
|
||||
"--cooldown-seconds",
|
||||
"0",
|
||||
],
|
||||
&root,
|
||||
)?;
|
||||
}
|
||||
|
||||
let close = read_json(
|
||||
&repo
|
||||
.join(".epiphany")
|
||||
.join("work")
|
||||
.join(format!("work-close-{item}.json")),
|
||||
)?;
|
||||
let config_text = fs::read_to_string(repo.join(target_path))
|
||||
.with_context(|| format!("failed to read {}", repo.join(target_path).display()))?;
|
||||
let deploy_script_text = fs::read_to_string(repo.join("deploy").join("idunn-deploy.ps1"))
|
||||
.with_context(|| {
|
||||
format!(
|
||||
"failed to read {}",
|
||||
repo.join("deploy").join("idunn-deploy.ps1").display()
|
||||
)
|
||||
})?;
|
||||
let audit = cargo_json(
|
||||
&manifest,
|
||||
"epiphany-work",
|
||||
&["deployment-config-audit", "--workspace", path_str(&repo)?],
|
||||
&root,
|
||||
)?;
|
||||
let runbook = cargo_json(
|
||||
&manifest,
|
||||
"epiphany-work",
|
||||
&[
|
||||
"deployment-execution-runbook",
|
||||
"--workspace",
|
||||
path_str(&repo)?,
|
||||
],
|
||||
&root,
|
||||
)?;
|
||||
let current_commit = git_output(["rev-parse", "HEAD"], &repo)?;
|
||||
let idunn_deployment_receipt_id = "fixture-idunn-deployment";
|
||||
let idunn_aftercare_receipt_id = "fixture-idunn-aftercare";
|
||||
write_epiphany_cultmesh_idunn_deployment_receipt(
|
||||
&local_verse,
|
||||
"repo-deployment-config-family-smoke",
|
||||
EpiphanyCultMeshIdunnDeploymentReceiptEntry {
|
||||
schema_version: "gamecult.idunn.deployment_receipt.v0".to_string(),
|
||||
receipt_id: idunn_deployment_receipt_id.to_string(),
|
||||
runtime_id: "repo-deployment-config-family-smoke".to_string(),
|
||||
verse_id: "gamecult-local".to_string(),
|
||||
status: "deployed".to_string(),
|
||||
trigger: "git-push-observed-by-idunn".to_string(),
|
||||
watched_ref: "refs/heads/main".to_string(),
|
||||
source_commit: current_commit,
|
||||
result_ref: "idunn://deployment/fixture-idunn-deployment".to_string(),
|
||||
result_summary:
|
||||
"Fixture Idunn deployment receipt proves the repo audit can ingest sealed CultMesh receipt refs."
|
||||
.to_string(),
|
||||
private_state_exposed: false,
|
||||
notes: vec![
|
||||
"Idunn owns deployment execution; this local Verse row is an operator-safe receipt projection."
|
||||
.to_string(),
|
||||
],
|
||||
},
|
||||
)?;
|
||||
write_epiphany_cultmesh_idunn_aftercare_audit_receipt(
|
||||
&local_verse,
|
||||
"repo-deployment-config-family-smoke",
|
||||
EpiphanyCultMeshIdunnAftercareAuditReceiptEntry {
|
||||
schema_version: "gamecult.idunn.deployment_aftercare_audit.v0".to_string(),
|
||||
receipt_id: idunn_aftercare_receipt_id.to_string(),
|
||||
runtime_id: "repo-deployment-config-family-smoke".to_string(),
|
||||
verse_id: "gamecult-local".to_string(),
|
||||
status: "complete".to_string(),
|
||||
checked_ref: "refs/heads/main".to_string(),
|
||||
deployment_receipt_id: idunn_deployment_receipt_id.to_string(),
|
||||
audit_ref: "idunn://deployment-aftercare/fixture-idunn-aftercare".to_string(),
|
||||
result_summary:
|
||||
"Fixture Idunn aftercare audit receipt proves the repo audit can close from sealed CultMesh receipt refs."
|
||||
.to_string(),
|
||||
private_state_exposed: false,
|
||||
notes: vec![
|
||||
"Idunn owns aftercare; this local Verse row exposes status without private deployment state."
|
||||
.to_string(),
|
||||
],
|
||||
},
|
||||
)?;
|
||||
let aftercare = cargo_json(
|
||||
&manifest,
|
||||
"epiphany-work",
|
||||
&[
|
||||
"deployment-aftercare-audit",
|
||||
"--workspace",
|
||||
path_str(&repo)?,
|
||||
"--local-verse-store",
|
||||
path_str(&local_verse)?,
|
||||
"--runtime-id",
|
||||
"repo-deployment-config-family-smoke",
|
||||
"--idunn-deployment-receipt-ref",
|
||||
"latest",
|
||||
"--aftercare-audit-receipt-ref",
|
||||
"latest",
|
||||
],
|
||||
&root,
|
||||
)?;
|
||||
let swarm_overview = cargo_json(
|
||||
&manifest,
|
||||
"epiphany-verse-query",
|
||||
&[
|
||||
"swarm-overview",
|
||||
"--store",
|
||||
path_str(&local_verse)?,
|
||||
"--runtime-id",
|
||||
"repo-deployment-config-family-smoke",
|
||||
],
|
||||
&root,
|
||||
)?;
|
||||
|
||||
require_eq(
|
||||
&plan,
|
||||
&["derivation", "safeActionFamily"],
|
||||
"repo.deployment_config",
|
||||
)?;
|
||||
require_eq(&close, &["status"], "closed")?;
|
||||
require_eq(&close, &["soul", "verdict"], "passed")?;
|
||||
require_eq(
|
||||
&close,
|
||||
&["closureReview", "familyAssertions", "status"],
|
||||
"passed",
|
||||
)?;
|
||||
require_bool(
|
||||
&close,
|
||||
&["closureReview", "sourceGrounding", "pathScopeMatched"],
|
||||
true,
|
||||
)?;
|
||||
require_bool(&close, &["privateStateExposed"], false)?;
|
||||
require_text(
|
||||
&config_text,
|
||||
"schema_version = \"epiphany.repo_deployment_config.v0\"",
|
||||
)?;
|
||||
require_text(
|
||||
&config_text,
|
||||
"safe_action_family = \"repo.deployment_config\"",
|
||||
)?;
|
||||
require_text(&config_text, "enabled = false")?;
|
||||
require_text(&config_text, "owner = \"Idunn\"")?;
|
||||
require_text(&config_text, "trigger = \"git-push-observed-by-idunn\"")?;
|
||||
require_text(&config_text, "watched_ref = \"refs/heads/main\"")?;
|
||||
require_text(
|
||||
&config_text,
|
||||
"deployment_script_ref = \"deploy/idunn-deploy.ps1\"",
|
||||
)?;
|
||||
require_text(&config_text, "deployment_script_hash_required = true")?;
|
||||
require_text(&config_text, "deployment_script_review_required = true")?;
|
||||
require_text(&config_text, "host_access_policy_ref_required = true")?;
|
||||
require_text(&config_text, "secret_values_embedded = false")?;
|
||||
require_text(&config_text, "rollback_plan_ref_required = true")?;
|
||||
require_text(&config_text, "aftercare_checks_required = true")?;
|
||||
require_text(&config_text, "idunn_receipt_required = true")?;
|
||||
require_text(&config_text, "aftercare_audit_required = true")?;
|
||||
require_text(
|
||||
&config_text,
|
||||
"capability_family = \"gamecult.idunn.deployment\"",
|
||||
)?;
|
||||
require_text(
|
||||
&config_text,
|
||||
"intent_contract = \"gamecult.idunn.deployment_intent.v0\"",
|
||||
)?;
|
||||
require_text(
|
||||
&config_text,
|
||||
"receipt_contract = \"gamecult.idunn.deployment_receipt.v0\"",
|
||||
)?;
|
||||
require_text(
|
||||
&config_text,
|
||||
"aftercare_contract = \"gamecult.idunn.deployment_aftercare_audit.v0\"",
|
||||
)?;
|
||||
require_text(&config_text, "daemon_owns_execution = true")?;
|
||||
require_text(&config_text, "configuration_only = true")?;
|
||||
require_text(&config_text, "direct_deployment_authority = false")?;
|
||||
require_text(&config_text, "direct_ssh_authority = false")?;
|
||||
require_text(&config_text, "direct_git_push_authority = false")?;
|
||||
require_text(&config_text, "direct_service_lifecycle_authority = false")?;
|
||||
require_text(&config_text, "direct_hands_authority = false")?;
|
||||
require_text(&config_text, "publication_authorized = false")?;
|
||||
require_text(&config_text, "cross_body_mutation_authorized = false")?;
|
||||
require_text(&config_text, "private_verse_rummaging = false")?;
|
||||
require_text(&config_text, "private_state_exposed = false")?;
|
||||
require_text(&deploy_script_text, "deployment script placeholder")?;
|
||||
require_eq(
|
||||
&audit,
|
||||
&["schemaVersion"],
|
||||
"epiphany.repo_deployment_config_audit.v0",
|
||||
)?;
|
||||
require_eq(&audit, &["status"], "ready-for-idunn-review")?;
|
||||
require_bool(&audit, &["readyForIdunnReview"], true)?;
|
||||
require_bool(&audit, &["executionAuthorized"], false)?;
|
||||
require_bool(&audit, &["deploymentAuthority"], false)?;
|
||||
require_bool(&audit, &["sshAuthority"], false)?;
|
||||
require_bool(&audit, &["gitPushAuthority"], false)?;
|
||||
require_bool(&audit, &["serviceLifecycleAuthority"], false)?;
|
||||
require_bool(&audit, &["handsAuthority"], false)?;
|
||||
require_bool(&audit, &["publicationAuthorized"], false)?;
|
||||
require_bool(&audit, &["mergeAuthorized"], false)?;
|
||||
require_bool(&audit, &["daemonOwnsExecution"], true)?;
|
||||
require_bool(&audit, &["privateStateExposed"], false)?;
|
||||
require_eq(
|
||||
&runbook,
|
||||
&["schemaVersion"],
|
||||
"epiphany.repo_deployment_execution_runbook.v0",
|
||||
)?;
|
||||
require_eq(&runbook, &["status"], "ready-for-operator-git-push")?;
|
||||
require_bool(&runbook, &["runbookWritten"], true)?;
|
||||
require_bool(&runbook, &["requiresExplicitOperatorAuthority"], true)?;
|
||||
require_bool(&runbook, &["mutatesRemoteWhenRun"], true)?;
|
||||
require_bool(&runbook, &["executionAuthorized"], false)?;
|
||||
require_bool(&runbook, &["deploymentAuthority"], false)?;
|
||||
require_bool(&runbook, &["sshAuthority"], false)?;
|
||||
require_bool(&runbook, &["gitPushAuthority"], false)?;
|
||||
require_bool(&runbook, &["serviceLifecycleAuthority"], false)?;
|
||||
require_bool(&runbook, &["handsAuthority"], false)?;
|
||||
require_bool(&runbook, &["publicationAuthorized"], false)?;
|
||||
require_bool(&runbook, &["mergeAuthorized"], false)?;
|
||||
require_bool(&runbook, &["daemonOwnsExecution"], true)?;
|
||||
require_bool(&runbook, &["privateStateExposed"], false)?;
|
||||
require_eq(&runbook, &["watchedRef"], "refs/heads/main")?;
|
||||
let runbook_path = value_at_path(&runbook, &["runbookPath"])
|
||||
.and_then(Value::as_str)
|
||||
.ok_or_else(|| anyhow!("missing runbook path"))?;
|
||||
let runbook_text = fs::read_to_string(runbook_path)
|
||||
.with_context(|| format!("failed to read runbook {runbook_path}"))?;
|
||||
require_text(
|
||||
&runbook_text,
|
||||
"schema_version = \"epiphany.repo_deployment_execution_runbook.v0\"",
|
||||
)?;
|
||||
require_text(&runbook_text, "git push $Remote HEAD:refs/heads/main")?;
|
||||
require_text(
|
||||
&runbook_text,
|
||||
"gamecult.idunn.deployment_aftercare_audit.v0",
|
||||
)?;
|
||||
require_eq(
|
||||
&aftercare,
|
||||
&["schemaVersion"],
|
||||
"epiphany.repo_deployment_aftercare_audit.v0",
|
||||
)?;
|
||||
require_eq(&aftercare, &["status"], "complete")?;
|
||||
require_bool(&aftercare, &["deploymentComplete"], true)?;
|
||||
require_bool(&aftercare, &["mutatesRemoteWhenRun"], false)?;
|
||||
require_bool(&aftercare, &["executionAuthorized"], false)?;
|
||||
require_bool(&aftercare, &["deploymentAuthority"], false)?;
|
||||
require_bool(&aftercare, &["sshAuthority"], false)?;
|
||||
require_bool(&aftercare, &["gitPushAuthority"], false)?;
|
||||
require_bool(&aftercare, &["serviceLifecycleAuthority"], false)?;
|
||||
require_bool(&aftercare, &["handsAuthority"], false)?;
|
||||
require_bool(&aftercare, &["publicationAuthorized"], false)?;
|
||||
require_bool(&aftercare, &["mergeAuthorized"], false)?;
|
||||
require_bool(&aftercare, &["daemonOwnsExecution"], true)?;
|
||||
require_bool(&aftercare, &["privateStateExposed"], false)?;
|
||||
require_eq(
|
||||
&aftercare,
|
||||
&["idunnDeploymentReceipt", "source"],
|
||||
"cultmesh",
|
||||
)?;
|
||||
require_eq(
|
||||
&aftercare,
|
||||
&["idunnDeploymentReceipt", "receiptId"],
|
||||
idunn_deployment_receipt_id,
|
||||
)?;
|
||||
require_eq(
|
||||
&aftercare,
|
||||
&["idunnAftercareAuditReceipt", "source"],
|
||||
"cultmesh",
|
||||
)?;
|
||||
require_eq(
|
||||
&aftercare,
|
||||
&["idunnAftercareAuditReceipt", "receiptId"],
|
||||
idunn_aftercare_receipt_id,
|
||||
)?;
|
||||
require_eq(
|
||||
&aftercare,
|
||||
&["idunnDeploymentReceipt", "schemaVersion"],
|
||||
"gamecult.idunn.deployment_receipt.v0",
|
||||
)?;
|
||||
require_eq(
|
||||
&aftercare,
|
||||
&["idunnAftercareAuditReceipt", "schemaVersion"],
|
||||
"gamecult.idunn.deployment_aftercare_audit.v0",
|
||||
)?;
|
||||
require_eq(
|
||||
&swarm_overview,
|
||||
&["latestIdunnDeploymentReceipt"],
|
||||
idunn_deployment_receipt_id,
|
||||
)?;
|
||||
require_eq(
|
||||
&swarm_overview,
|
||||
&["latestIdunnAftercareAuditReceipt"],
|
||||
idunn_aftercare_receipt_id,
|
||||
)?;
|
||||
require_u64(&swarm_overview, &["idunnDeploymentReceiptCount"], 2)?;
|
||||
require_bool(&swarm_overview, &["privateStateExposed"], false)?;
|
||||
require_array_contains(
|
||||
&swarm_overview,
|
||||
&["idunnDeploymentReceiptTuiRows"],
|
||||
"IDUNN-DEPLOYMENT",
|
||||
)?;
|
||||
require_array_contains(
|
||||
&swarm_overview,
|
||||
&["idunnDeploymentReceiptTuiRows"],
|
||||
idunn_deployment_receipt_id,
|
||||
)?;
|
||||
require_array_contains(
|
||||
&swarm_overview,
|
||||
&["idunnDeploymentReceiptTuiRows"],
|
||||
idunn_aftercare_receipt_id,
|
||||
)?;
|
||||
|
||||
let summary = json!({
|
||||
"schemaVersion": "epiphany.repo_deployment_config_family_smoke.v0",
|
||||
"status": "ok",
|
||||
"smokeDir": smoke_dir,
|
||||
"repo": repo,
|
||||
"branch": git_output(["branch", "--show-current"], &repo)?,
|
||||
"item": item,
|
||||
"safeActionFamily": plan["derivation"]["safeActionFamily"],
|
||||
"targetPath": target_path,
|
||||
"closeStatus": close["status"],
|
||||
"soulVerdict": close["soul"]["verdict"],
|
||||
"familyAssertionsStatus": close["closureReview"]["familyAssertions"]["status"],
|
||||
"pathScopeMatched": close["closureReview"]["sourceGrounding"]["pathScopeMatched"],
|
||||
"deploymentConfigEnabled": false,
|
||||
"deploymentConfigAuditStatus": audit["status"],
|
||||
"deploymentConfigAuditReceiptPath": audit["receiptPath"],
|
||||
"readyForIdunnReview": audit["readyForIdunnReview"],
|
||||
"deploymentExecutionRunbookStatus": runbook["status"],
|
||||
"deploymentExecutionRunbookPath": runbook["runbookPath"],
|
||||
"deploymentExecutionRunbookSha256": runbook["runbookSha256"],
|
||||
"requiresExplicitOperatorAuthority": runbook["requiresExplicitOperatorAuthority"],
|
||||
"mutatesRemoteWhenRun": runbook["mutatesRemoteWhenRun"],
|
||||
"deploymentAftercareAuditStatus": aftercare["status"],
|
||||
"deploymentComplete": aftercare["deploymentComplete"],
|
||||
"idunnDeploymentReceiptSource": aftercare["idunnDeploymentReceipt"]["source"],
|
||||
"idunnAftercareAuditReceiptSource": aftercare["idunnAftercareAuditReceipt"]["source"],
|
||||
"idunnDeploymentReceiptId": aftercare["idunnDeploymentReceipt"]["receiptId"],
|
||||
"idunnAftercareAuditReceiptId": aftercare["idunnAftercareAuditReceipt"]["receiptId"],
|
||||
"swarmOverviewIdunnDeploymentReceiptCount": swarm_overview["idunnDeploymentReceiptCount"],
|
||||
"swarmOverviewLatestIdunnDeploymentReceipt": swarm_overview["latestIdunnDeploymentReceipt"],
|
||||
"swarmOverviewLatestIdunnAftercareAuditReceipt": swarm_overview["latestIdunnAftercareAuditReceipt"],
|
||||
"deploymentTrigger": "git-push-observed-by-idunn",
|
||||
"deploymentOwner": "Idunn",
|
||||
"daemonOwnsExecution": true,
|
||||
"deploymentAuthority": false,
|
||||
"sshAuthority": false,
|
||||
"gitPushAuthority": false,
|
||||
"serviceLifecycleAuthority": false,
|
||||
"privateStateExposed": false,
|
||||
});
|
||||
write_json(&smoke_dir.join("summary.json"), &summary)?;
|
||||
Ok(summary)
|
||||
}
|
||||
|
||||
fn cargo_json(manifest: &Path, bin: &str, args: &[&str], cwd: &Path) -> Result<Value> {
|
||||
let output = Command::new("cargo")
|
||||
.arg("run")
|
||||
.arg("--quiet")
|
||||
.arg("--manifest-path")
|
||||
.arg(manifest)
|
||||
.arg("--bin")
|
||||
.arg(bin)
|
||||
.arg("--")
|
||||
.args(args)
|
||||
.current_dir(cwd)
|
||||
.output()
|
||||
.with_context(|| format!("failed to run cargo bin {bin}"))?;
|
||||
if !output.status.success() {
|
||||
return Err(anyhow!(
|
||||
"{bin} failed with status {:?}\nstdout:\n{}\nstderr:\n{}",
|
||||
output.status.code(),
|
||||
String::from_utf8_lossy(&output.stdout),
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
));
|
||||
}
|
||||
serde_json::from_slice(&output.stdout).with_context(|| {
|
||||
format!(
|
||||
"{bin} did not emit JSON on stdout:\n{}",
|
||||
String::from_utf8_lossy(&output.stdout)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn git<const N: usize>(args: [&str; N], cwd: &Path) -> Result<()> {
|
||||
let output = Command::new("git")
|
||||
.args(args)
|
||||
.current_dir(cwd)
|
||||
.output()
|
||||
.with_context(|| format!("failed to run git in {}", cwd.display()))?;
|
||||
if output.status.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(anyhow!(
|
||||
"git {:?} failed in {}\nstdout:\n{}\nstderr:\n{}",
|
||||
args,
|
||||
cwd.display(),
|
||||
String::from_utf8_lossy(&output.stdout),
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn git_output<const N: usize>(args: [&str; N], cwd: &Path) -> Result<String> {
|
||||
let output = Command::new("git")
|
||||
.args(args)
|
||||
.current_dir(cwd)
|
||||
.output()
|
||||
.with_context(|| format!("failed to run git in {}", cwd.display()))?;
|
||||
if output.status.success() {
|
||||
Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
|
||||
} else {
|
||||
Err(anyhow!(
|
||||
"git {:?} failed in {}\nstdout:\n{}\nstderr:\n{}",
|
||||
args,
|
||||
cwd.display(),
|
||||
String::from_utf8_lossy(&output.stdout),
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn read_json(path: &Path) -> Result<Value> {
|
||||
let bytes = fs::read(path).with_context(|| format!("failed to read {}", path.display()))?;
|
||||
serde_json::from_slice(&bytes).with_context(|| format!("failed to parse {}", path.display()))
|
||||
}
|
||||
|
||||
fn write_json(path: &Path, value: &Value) -> Result<()> {
|
||||
let bytes = serde_json::to_vec_pretty(value)?;
|
||||
fs::write(path, bytes).with_context(|| format!("failed to write {}", path.display()))
|
||||
}
|
||||
|
||||
fn require_eq(value: &Value, path: &[&str], expected: &str) -> Result<()> {
|
||||
let actual = value_at_path(value, path)
|
||||
.and_then(Value::as_str)
|
||||
.ok_or_else(|| anyhow!("missing string at {}", path.join(".")))?;
|
||||
if actual == expected {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(anyhow!(
|
||||
"expected {} at {}, got {}",
|
||||
expected,
|
||||
path.join("."),
|
||||
actual
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn require_bool(value: &Value, path: &[&str], expected: bool) -> Result<()> {
|
||||
let actual = value_at_path(value, path)
|
||||
.and_then(Value::as_bool)
|
||||
.ok_or_else(|| anyhow!("missing bool at {}", path.join(".")))?;
|
||||
if actual == expected {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(anyhow!(
|
||||
"expected {} at {}, got {}",
|
||||
expected,
|
||||
path.join("."),
|
||||
actual
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn require_u64(value: &Value, path: &[&str], expected: u64) -> Result<()> {
|
||||
let actual = value_at_path(value, path)
|
||||
.and_then(Value::as_u64)
|
||||
.ok_or_else(|| anyhow!("missing unsigned integer at {}", path.join(".")))?;
|
||||
if actual == expected {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(anyhow!(
|
||||
"expected {} at {}, got {}",
|
||||
expected,
|
||||
path.join("."),
|
||||
actual
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn require_array_contains(value: &Value, path: &[&str], needle: &str) -> Result<()> {
|
||||
let array = value_at_path(value, path)
|
||||
.and_then(Value::as_array)
|
||||
.ok_or_else(|| anyhow!("missing array at {}", path.join(".")))?;
|
||||
if array
|
||||
.iter()
|
||||
.filter_map(Value::as_str)
|
||||
.any(|item| item.contains(needle))
|
||||
{
|
||||
Ok(())
|
||||
} else {
|
||||
Err(anyhow!(
|
||||
"expected array at {} to contain {:?}",
|
||||
path.join("."),
|
||||
needle
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn require_text(text: &str, needle: &str) -> Result<()> {
|
||||
if text.contains(needle) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(anyhow!("expected generated text to contain {needle:?}"))
|
||||
}
|
||||
}
|
||||
|
||||
fn value_at_path<'a>(value: &'a Value, path: &[&str]) -> Option<&'a Value> {
|
||||
let mut cursor = value;
|
||||
for segment in path {
|
||||
cursor = cursor.get(*segment)?;
|
||||
}
|
||||
Some(cursor)
|
||||
}
|
||||
|
||||
fn take_path<I>(args: &mut std::iter::Peekable<I>, flag: &str) -> Result<PathBuf>
|
||||
where
|
||||
I: Iterator<Item = String>,
|
||||
{
|
||||
args.next()
|
||||
.map(PathBuf::from)
|
||||
.ok_or_else(|| anyhow!("{flag} requires a value"))
|
||||
}
|
||||
|
||||
fn path_str(path: &Path) -> Result<&str> {
|
||||
path.to_str()
|
||||
.ok_or_else(|| anyhow!("path is not valid UTF-8: {}", path.display()))
|
||||
}
|
||||
|
|
@ -53,7 +53,6 @@ struct Args {
|
|||
fresh_repo_summary: Option<PathBuf>,
|
||||
readiness_summary: Option<PathBuf>,
|
||||
bifrost_accounting_summary: Option<PathBuf>,
|
||||
deployment_handoff_summary: Option<PathBuf>,
|
||||
daemon_survival_summary: Option<PathBuf>,
|
||||
}
|
||||
|
||||
|
|
@ -64,7 +63,6 @@ impl Args {
|
|||
let mut fresh_repo_summary = None;
|
||||
let mut readiness_summary = None;
|
||||
let mut bifrost_accounting_summary = None;
|
||||
let mut deployment_handoff_summary = None;
|
||||
let mut daemon_survival_summary = None;
|
||||
let mut args = env::args().skip(1).peekable();
|
||||
while let Some(arg) = args.next() {
|
||||
|
|
@ -81,10 +79,6 @@ impl Args {
|
|||
bifrost_accounting_summary =
|
||||
Some(take_path(&mut args, "--bifrost-accounting-summary")?)
|
||||
}
|
||||
"--deployment-handoff-summary" => {
|
||||
deployment_handoff_summary =
|
||||
Some(take_path(&mut args, "--deployment-handoff-summary")?)
|
||||
}
|
||||
"--daemon-survival-summary" => {
|
||||
daemon_survival_summary =
|
||||
Some(take_path(&mut args, "--daemon-survival-summary")?)
|
||||
|
|
@ -98,7 +92,6 @@ impl Args {
|
|||
fresh_repo_summary,
|
||||
readiness_summary,
|
||||
bifrost_accounting_summary,
|
||||
deployment_handoff_summary,
|
||||
daemon_survival_summary,
|
||||
})
|
||||
}
|
||||
|
|
@ -136,9 +129,6 @@ fn run_smoke(args: Args) -> Result<Value> {
|
|||
let bifrost_accounting_summary = args
|
||||
.bifrost_accounting_summary
|
||||
.unwrap_or_else(|| latest_summary(&args.smoke_root, "repo-bifrost-accounting-bundle-"));
|
||||
let deployment_handoff_summary = args
|
||||
.deployment_handoff_summary
|
||||
.unwrap_or_else(|| latest_summary(&args.smoke_root, "repo-deployment-config-family-"));
|
||||
let daemon_survival_summary = args
|
||||
.daemon_survival_summary
|
||||
.unwrap_or_else(|| latest_summary(&args.smoke_root, "daemon-survival-rehearsal-"));
|
||||
|
|
@ -146,13 +136,11 @@ fn run_smoke(args: Args) -> Result<Value> {
|
|||
let fresh = read_json(&fresh_repo_summary)?;
|
||||
let readiness = read_json(&readiness_summary)?;
|
||||
let bifrost = read_json(&bifrost_accounting_summary)?;
|
||||
let deployment_handoff = read_json(&deployment_handoff_summary)?;
|
||||
let daemon_survival = read_json(&daemon_survival_summary)?;
|
||||
|
||||
verify_fresh_repo(&fresh)?;
|
||||
verify_readiness(&readiness)?;
|
||||
verify_bifrost_accounting(&bifrost)?;
|
||||
verify_deployment_handoff(&deployment_handoff)?;
|
||||
verify_daemon_survival(&daemon_survival)?;
|
||||
let weksa_interlingua = verify_weksa_interlingua()?;
|
||||
let persona_memory_recall = verify_persona_memory_recall()?;
|
||||
|
|
@ -215,11 +203,6 @@ fn run_smoke(args: Args) -> Result<Value> {
|
|||
"Bifrost",
|
||||
"readiness, artifact acceptance, and metrics accounting rows are closed",
|
||||
),
|
||||
green(
|
||||
"idunn-deployment-handoff",
|
||||
"Idunn",
|
||||
"deployment config, operator runbook, and aftercare receipt readback are sealed",
|
||||
),
|
||||
green(
|
||||
"long-running-daemon-proof",
|
||||
"Idunn",
|
||||
|
|
@ -263,12 +246,10 @@ fn run_smoke(args: Args) -> Result<Value> {
|
|||
"freshRepoSummary": fresh_repo_summary,
|
||||
"readinessSummary": readiness_summary,
|
||||
"bifrostAccountingSummary": bifrost_accounting_summary,
|
||||
"deploymentHandoffSummary": deployment_handoff_summary,
|
||||
"daemonSurvivalSummary": daemon_survival_summary,
|
||||
"freshRepoSmokeDir": fresh["smokeDir"],
|
||||
"readinessSmokeDir": readiness["smokeDir"],
|
||||
"bifrostAccountingSmokeDir": bifrost["smokeDir"],
|
||||
"deploymentHandoffSmokeDir": deployment_handoff["smokeDir"],
|
||||
"daemonSurvivalSmokeDir": daemon_survival["smokeDir"],
|
||||
"weksaInterlingua": weksa_interlingua,
|
||||
"personaMemoryRecall": persona_memory_recall,
|
||||
|
|
@ -399,35 +380,6 @@ fn verify_daemon_survival(value: &Value) -> Result<()> {
|
|||
require_bool(value, &["privateStateExposed"], false)
|
||||
}
|
||||
|
||||
fn verify_deployment_handoff(value: &Value) -> Result<()> {
|
||||
require_eq(
|
||||
value,
|
||||
&["schemaVersion"],
|
||||
"epiphany.repo_deployment_config_family_smoke.v0",
|
||||
)?;
|
||||
require_eq(value, &["status"], "ok")?;
|
||||
require_bool(value, &["deploymentConfigEnabled"], false)?;
|
||||
require_eq(
|
||||
value,
|
||||
&["deploymentConfigAuditStatus"],
|
||||
"ready-for-idunn-review",
|
||||
)?;
|
||||
require_bool(value, &["readyForIdunnReview"], true)?;
|
||||
require_eq(
|
||||
value,
|
||||
&["deploymentExecutionRunbookStatus"],
|
||||
"ready-for-operator-git-push",
|
||||
)?;
|
||||
require_eq(value, &["deploymentAftercareAuditStatus"], "complete")?;
|
||||
require_bool(value, &["deploymentComplete"], true)?;
|
||||
require_eq(value, &["idunnDeploymentReceiptSource"], "cultmesh")?;
|
||||
require_eq(value, &["idunnAftercareAuditReceiptSource"], "cultmesh")?;
|
||||
require_eq(value, &["deploymentTrigger"], "git-push-observed-by-idunn")?;
|
||||
require_eq(value, &["deploymentOwner"], "Idunn")?;
|
||||
require_bool(value, &["deploymentAuthority"], false)?;
|
||||
require_bool(value, &["privateStateExposed"], false)
|
||||
}
|
||||
|
||||
fn verify_weksa_interlingua() -> Result<Value> {
|
||||
let packet = build_weksa_interlingua_packet(WeksaInterlinguaInput {
|
||||
packet_id: "repo-swarm-mvp-gate-weksa-packet".to_string(),
|
||||
|
|
|
|||
|
|
@ -3574,23 +3574,6 @@ pub fn load_epiphany_cultmesh_managed_service_policies(
|
|||
.collect())
|
||||
}
|
||||
|
||||
pub fn write_epiphany_cultmesh_idunn_deployment_receipt(
|
||||
store_path: impl AsRef<Path>,
|
||||
runtime_id: impl Into<String>,
|
||||
receipt: EpiphanyCultMeshIdunnDeploymentReceiptEntry,
|
||||
) -> Result<EpiphanyCultMeshIdunnDeploymentReceiptEntry> {
|
||||
validate_idunn_deployment_receipt(&receipt)?;
|
||||
let mut node = open_epiphany_cultmesh_node(store_path, runtime_id)?;
|
||||
let receipt_key = epiphany_cultmesh_idunn_deployment_receipt_key(&receipt.receipt_id);
|
||||
let written = node.put(receipt_key.as_str(), &receipt)?;
|
||||
node.put(
|
||||
EPIPHANY_CULTMESH_IDUNN_DEPLOYMENT_RECEIPT_LATEST_KEY,
|
||||
&written,
|
||||
)?;
|
||||
node.flush()?;
|
||||
Ok(written)
|
||||
}
|
||||
|
||||
pub fn load_epiphany_cultmesh_idunn_deployment_receipt(
|
||||
store_path: impl AsRef<Path>,
|
||||
runtime_id: impl Into<String>,
|
||||
|
|
@ -3609,23 +3592,6 @@ pub fn load_latest_epiphany_cultmesh_idunn_deployment_receipt(
|
|||
node.get(EPIPHANY_CULTMESH_IDUNN_DEPLOYMENT_RECEIPT_LATEST_KEY)
|
||||
}
|
||||
|
||||
pub fn write_epiphany_cultmesh_idunn_aftercare_audit_receipt(
|
||||
store_path: impl AsRef<Path>,
|
||||
runtime_id: impl Into<String>,
|
||||
receipt: EpiphanyCultMeshIdunnAftercareAuditReceiptEntry,
|
||||
) -> Result<EpiphanyCultMeshIdunnAftercareAuditReceiptEntry> {
|
||||
validate_idunn_aftercare_audit_receipt(&receipt)?;
|
||||
let mut node = open_epiphany_cultmesh_node(store_path, runtime_id)?;
|
||||
let receipt_key = epiphany_cultmesh_idunn_aftercare_audit_receipt_key(&receipt.receipt_id);
|
||||
let written = node.put(receipt_key.as_str(), &receipt)?;
|
||||
node.put(
|
||||
EPIPHANY_CULTMESH_IDUNN_AFTERCARE_AUDIT_RECEIPT_LATEST_KEY,
|
||||
&written,
|
||||
)?;
|
||||
node.flush()?;
|
||||
Ok(written)
|
||||
}
|
||||
|
||||
pub fn load_epiphany_cultmesh_idunn_aftercare_audit_receipt(
|
||||
store_path: impl AsRef<Path>,
|
||||
runtime_id: impl Into<String>,
|
||||
|
|
@ -4029,69 +3995,6 @@ fn validate_daemon_service_lifecycle_receipt(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_idunn_deployment_receipt(
|
||||
receipt: &EpiphanyCultMeshIdunnDeploymentReceiptEntry,
|
||||
) -> Result<()> {
|
||||
if receipt.private_state_exposed {
|
||||
return Err(anyhow!(
|
||||
"Idunn deployment receipts must not expose private state"
|
||||
));
|
||||
}
|
||||
if receipt.schema_version != EPIPHANY_CULTMESH_IDUNN_DEPLOYMENT_RECEIPT_SCHEMA_VERSION {
|
||||
return Err(anyhow!(
|
||||
"Idunn deployment receipt schema_version must be {:?}",
|
||||
EPIPHANY_CULTMESH_IDUNN_DEPLOYMENT_RECEIPT_SCHEMA_VERSION
|
||||
));
|
||||
}
|
||||
for (label, value) in [
|
||||
("receipt id", receipt.receipt_id.as_str()),
|
||||
("runtime id", receipt.runtime_id.as_str()),
|
||||
("verse id", receipt.verse_id.as_str()),
|
||||
("status", receipt.status.as_str()),
|
||||
("trigger", receipt.trigger.as_str()),
|
||||
("watched ref", receipt.watched_ref.as_str()),
|
||||
("result ref", receipt.result_ref.as_str()),
|
||||
] {
|
||||
if value.trim().is_empty() {
|
||||
return Err(anyhow!("Idunn deployment receipt missing {label}"));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_idunn_aftercare_audit_receipt(
|
||||
receipt: &EpiphanyCultMeshIdunnAftercareAuditReceiptEntry,
|
||||
) -> Result<()> {
|
||||
if receipt.private_state_exposed {
|
||||
return Err(anyhow!(
|
||||
"Idunn aftercare audit receipts must not expose private state"
|
||||
));
|
||||
}
|
||||
if receipt.schema_version != EPIPHANY_CULTMESH_IDUNN_AFTERCARE_AUDIT_RECEIPT_SCHEMA_VERSION {
|
||||
return Err(anyhow!(
|
||||
"Idunn aftercare audit receipt schema_version must be {:?}",
|
||||
EPIPHANY_CULTMESH_IDUNN_AFTERCARE_AUDIT_RECEIPT_SCHEMA_VERSION
|
||||
));
|
||||
}
|
||||
for (label, value) in [
|
||||
("receipt id", receipt.receipt_id.as_str()),
|
||||
("runtime id", receipt.runtime_id.as_str()),
|
||||
("verse id", receipt.verse_id.as_str()),
|
||||
("status", receipt.status.as_str()),
|
||||
("checked ref", receipt.checked_ref.as_str()),
|
||||
(
|
||||
"deployment receipt id",
|
||||
receipt.deployment_receipt_id.as_str(),
|
||||
),
|
||||
("audit ref", receipt.audit_ref.as_str()),
|
||||
] {
|
||||
if value.trim().is_empty() {
|
||||
return Err(anyhow!("Idunn aftercare audit receipt missing {label}"));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn epiphany_cultmesh_daemon_tool_invocation_intent_from_capability(
|
||||
intent_id: impl Into<String>,
|
||||
requesting_agent_id: impl Into<String>,
|
||||
|
|
|
|||
|
|
@ -500,8 +500,6 @@ pub use cultmesh_integration::write_epiphany_cultmesh_eyes_contracts;
|
|||
pub use cultmesh_integration::write_epiphany_cultmesh_global_room_policies;
|
||||
pub use cultmesh_integration::write_epiphany_cultmesh_hands_action_gate;
|
||||
pub use cultmesh_integration::write_epiphany_cultmesh_hands_contracts;
|
||||
pub use cultmesh_integration::write_epiphany_cultmesh_idunn_aftercare_audit_receipt;
|
||||
pub use cultmesh_integration::write_epiphany_cultmesh_idunn_deployment_receipt;
|
||||
#[cfg(test)]
|
||||
pub use cultmesh_integration::write_epiphany_cultmesh_imagination_consensus_receipt;
|
||||
pub use cultmesh_integration::write_epiphany_cultmesh_managed_service_policy;
|
||||
|
|
|
|||
|
|
@ -264,3 +264,18 @@ The smoke persists the requester intent, requires the host receipt to remain
|
|||
absent, and verifies the directory reports a missing response. The typed schema
|
||||
and reader remain the host-daemon/ingest contract; no shipped generic CLI can
|
||||
author the daemon's answer.
|
||||
|
||||
## Fixture-authored Idunn completion
|
||||
|
||||
Idunn deployment and aftercare writers had no Idunn production caller. Their
|
||||
only shipped caller was `epiphany-repo-deployment-config-family-smoke`, which
|
||||
created `deployed` and `complete` receipts, fed them into aftercare, and then
|
||||
advertised deployment completion through swarm overview. The aggregate MVP gate
|
||||
accepted that smoke summary as a green Idunn deployment handoff.
|
||||
|
||||
The entire synthetic deployment-config family smoke is deleted, along with the
|
||||
orphaned local Idunn deployment/aftercare writers and validators. The aggregate
|
||||
MVP gate no longer accepts its summary or publishes a green deployment row.
|
||||
Deployment config audit and operator runbook commands remain requester/operator
|
||||
surfaces; typed Idunn schemas/readers remain ingest contracts. Only an actual
|
||||
Idunn body may make deployment or aftercare complete.
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
|
||||
- Eve connection requests remain pending until a real target provider daemon or authenticated ingest boundary supplies the typed response. The former generic `epiphany-eve-provider` CLI is deleted because caller-supplied provider identity and status did not constitute provider participation; local response construction/writing is test-only.
|
||||
- Daemon-tool invocation requests likewise remain pending until the advertised host daemon or authenticated ingest boundary supplies the typed response. Local response construction/writing/validation is test-only; aggregate smoke and receipt-directory projection prove intent-present/receipt-missing instead of manufacturing host acceptance.
|
||||
- Idunn deployment and aftercare outcomes have no local production writer. The synthetic deployment-config family smoke and its green aggregate MVP-gate handoff are deleted; config audit/runbook remain pre-deployment surfaces, while typed Idunn readers await genuine daemon-authored ingest.
|
||||
- Persona owner: `collaboration-feedback` writes public, bounded feedback only after that provider receipt exists.
|
||||
- Imagination owner: consensus participant selection, packet reference, receipt status/id, and adoption gate.
|
||||
- Persona output: `pending-imagination` with null consensus fields and `responseOwner=Imagination`.
|
||||
|
|
|
|||
|
|
@ -60,6 +60,10 @@ The confirmed conceptual substitutions have been cut:
|
|||
- daemon-tool response construction/writing is also test-only. No shipped host
|
||||
daemon currently responds; the aggregate smoke proves a pending intent and a
|
||||
missing host receipt rather than fabricating Hands acceptance.
|
||||
- the deployment-config family smoke and its aggregate MVP-gate row are deleted:
|
||||
they fabricated Idunn `deployed`/`complete` receipts. Epiphany exposes config
|
||||
audit/runbook requests and typed Idunn readers, but no local deployment or
|
||||
aftercare response writer.
|
||||
|
||||
The presentation boundary is now plain: `swarm overview` is a generic compact read-only projection. Gjallar is a downstream TUI application on Nightwing and is not an Epiphany organ, provider, owner, runtime, or architectural dependency. Eve/CultUI graphs may be lowered or composited downstream without Epiphany caring which presentation client does it.
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@ Inventory every production call to `write_*receipt`, then ask whether the execut
|
|||
smoke was the only shipped caller and manufactured host acceptance; response
|
||||
constructor/writer/validator/key are test-only pending a real host-daemon or
|
||||
authenticated ingest boundary.
|
||||
- Idunn deployment and aftercare receipts: no production local writers. The
|
||||
deployment-config family smoke was their only caller and fabricated a closed
|
||||
deployment chain; the smoke, writers, and validators are deleted. Typed
|
||||
schemas/readers remain for genuine Idunn-authored ingest.
|
||||
- `epiphany-operator-run`: owner-aligned for operator-run receipts and coordinator receipts derived from the run it executes.
|
||||
- smoke binaries and the `epiphany-verse-query smoke` arm: fixtures, not runtime evidence. They remain a quarantine risk if permitted to target canonical stores.
|
||||
- `epiphany-work` Weksa lowering: a lowering projection receipt, explicitly non-publication authority; no substitution confirmed in this pass.
|
||||
|
|
@ -46,7 +50,10 @@ Negative proof passed both directions: a plan command given hostile `--execute-i
|
|||
|
||||
## Standalone receipt-smoke quarantine update
|
||||
|
||||
The two standalone smoke binaries found writing canonical receipt schemas no longer accept receipt-store destinations. `epiphany-repo-deployment-config-family-smoke` accepts only `--root` and derives its entire disposable repo/Verse body under `<root>/.epiphany-smoke`; `--smoke-root` is rejected. `epiphany-weksa-interlingua-smoke` accepts no arguments and writes only `.epiphany-smoke/weksa-interlingua/local-verse.ccmp`. Attempts to redirect either at live state fail before fixture construction.
|
||||
The remaining standalone Weksa receipt smoke accepts no arguments and writes
|
||||
only `.epiphany-smoke/weksa-interlingua/local-verse.ccmp`. The former Idunn
|
||||
deployment-config receipt smoke is deleted rather than preserved behind path
|
||||
quarantine because its claimed lifecycle never occurred.
|
||||
|
||||
## Orphaned provider response API quarantine
|
||||
|
||||
|
|
|
|||
Binary file not shown.
File diff suppressed because one or more lines are too long
Reference in a new issue