Delete dead publication artifact authority
This commit is contained in:
parent
57e73cb774
commit
3c3c2ddb4b
5 changed files with 36 additions and 443 deletions
|
|
@ -59,8 +59,6 @@ use epiphany_core::load_epiphany_cultmesh_idunn_aftercare_audit_receipt;
|
|||
use epiphany_core::load_epiphany_cultmesh_idunn_deployment_receipt;
|
||||
use epiphany_core::load_epiphany_cultmesh_repo_work_overviews;
|
||||
use epiphany_core::load_epiphany_cultmesh_swarm_brake;
|
||||
use epiphany_core::load_latest_epiphany_cultmesh_bifrost_body_change_publication_receipt;
|
||||
use epiphany_core::load_latest_epiphany_cultmesh_bifrost_github_publication_receipt;
|
||||
use epiphany_core::load_latest_epiphany_cultmesh_idunn_aftercare_audit_receipt;
|
||||
use epiphany_core::load_latest_epiphany_cultmesh_idunn_deployment_receipt;
|
||||
use epiphany_core::load_latest_epiphany_cultmesh_repo_work_overview;
|
||||
|
|
@ -11694,8 +11692,6 @@ fn run_overview(args: OverviewArgs) -> Result<Value> {
|
|||
let close_receipt_path = work_receipt_path(&workspace, "close", &item);
|
||||
let close_review_receipt_path =
|
||||
artifact_dir.join(format!("work-close-{item_slug}-review.json"));
|
||||
let publish_receipt_path = work_receipt_path(&workspace, "publish", &item);
|
||||
let sync_receipt_path = work_receipt_path(&workspace, "sync", &item);
|
||||
let overview_receipt_path = artifact_dir.join(format!("work-overview-{item_slug}.json"));
|
||||
|
||||
let plan_receipt = read_json_if_exists(&plan_receipt_path)?;
|
||||
|
|
@ -11703,8 +11699,6 @@ fn run_overview(args: OverviewArgs) -> Result<Value> {
|
|||
let adopt_receipt = read_json_if_exists(&adopt_receipt_path)?;
|
||||
let execute_receipt = read_json_if_exists(&execute_receipt_path)?;
|
||||
let close_receipt = read_json_if_exists(&close_receipt_path)?;
|
||||
let publish_receipt = read_json_if_exists(&publish_receipt_path)?;
|
||||
let sync_receipt = read_json_if_exists(&sync_receipt_path)?;
|
||||
|
||||
let branch = git_output(&workspace, &["rev-parse", "--abbrev-ref", "HEAD"])?;
|
||||
let commit_sha = execute_receipt
|
||||
|
|
@ -11727,27 +11721,14 @@ fn run_overview(args: OverviewArgs) -> Result<Value> {
|
|||
.as_ref()
|
||||
.and_then(|receipt| string_from_json(receipt, &["soul", "verdict"]))
|
||||
.unwrap_or_else(|| "missing".to_string());
|
||||
let publication_status = publish_receipt
|
||||
.as_ref()
|
||||
.and_then(|receipt| receipt.get("publicationStatus").and_then(Value::as_str))
|
||||
.or_else(|| {
|
||||
publish_receipt
|
||||
.as_ref()
|
||||
.and_then(|receipt| receipt.get("status").and_then(Value::as_str))
|
||||
})
|
||||
.unwrap_or("missing");
|
||||
let sync_status = sync_receipt
|
||||
.as_ref()
|
||||
.and_then(|receipt| receipt.get("status").and_then(Value::as_str))
|
||||
.unwrap_or("missing");
|
||||
let publication_status = "provider-evidence-not-resolved";
|
||||
let sync_status = "provider-evidence-not-resolved";
|
||||
let (gate, blocker, next_safe_move) = repo_work_overview_gate(
|
||||
plan_receipt.as_ref(),
|
||||
run_receipt.as_ref(),
|
||||
adopt_receipt.as_ref(),
|
||||
execute_receipt.as_ref(),
|
||||
close_receipt.as_ref(),
|
||||
publish_receipt.as_ref(),
|
||||
sync_receipt.as_ref(),
|
||||
);
|
||||
let public_discussion_refs =
|
||||
string_array_from_json(&accept_receipt, &["feedback", "publicDiscussionRefs"]);
|
||||
|
|
@ -11847,8 +11828,6 @@ fn run_overview(args: OverviewArgs) -> Result<Value> {
|
|||
("execute", &execute_receipt_path),
|
||||
("close-review", &close_review_receipt_path),
|
||||
("close", &close_receipt_path),
|
||||
("publish", &publish_receipt_path),
|
||||
("sync", &sync_receipt_path),
|
||||
]);
|
||||
let changed_paths_for_entry = changed_paths.clone();
|
||||
let commit_sha_for_entry = commit_sha.clone().unwrap_or_default();
|
||||
|
|
@ -11860,8 +11839,6 @@ fn run_overview(args: OverviewArgs) -> Result<Value> {
|
|||
&adopt_receipt_path,
|
||||
&execute_receipt_path,
|
||||
&close_receipt_path,
|
||||
&publish_receipt_path,
|
||||
&sync_receipt_path,
|
||||
);
|
||||
let proof_artifacts = repo_work_proof_artifact_rows(&[
|
||||
("accept", &accept_receipt_path),
|
||||
|
|
@ -11871,11 +11848,8 @@ fn run_overview(args: OverviewArgs) -> Result<Value> {
|
|||
("execute", &execute_receipt_path),
|
||||
("close-review", &close_review_receipt_path),
|
||||
("close", &close_receipt_path),
|
||||
("publish", &publish_receipt_path),
|
||||
("sync", &sync_receipt_path),
|
||||
])?;
|
||||
let proof_publication_rows =
|
||||
repo_work_proof_publication_rows(publish_receipt.as_ref(), sync_receipt.as_ref());
|
||||
let proof_publication_rows = Vec::<Value>::new();
|
||||
let proof_bundle_tui_rows = repo_work_proof_bundle_tui_rows(
|
||||
&item,
|
||||
&branch,
|
||||
|
|
@ -11908,16 +11882,14 @@ fn run_overview(args: OverviewArgs) -> Result<Value> {
|
|||
"executeReceiptPath": existing_path_value(&execute_receipt_path),
|
||||
"closeReviewReceiptPath": existing_path_value(&close_review_receipt_path),
|
||||
"closeReceiptPath": existing_path_value(&close_receipt_path),
|
||||
"publishReceiptPath": existing_path_value(&publish_receipt_path),
|
||||
"syncReceiptPath": existing_path_value(&sync_receipt_path),
|
||||
"changedPaths": changed_paths,
|
||||
"commitSha": commit_sha,
|
||||
"intakeConsensus": intake_consensus_readback,
|
||||
"soulVerdict": soul_verdict,
|
||||
"mindStateCommitReceiptId": close_receipt.as_ref().and_then(|receipt| string_from_json(receipt, &["mind", "stateCommitReceiptId"])),
|
||||
"bifrostPublicationReceiptId": publish_receipt.as_ref().and_then(|receipt| string_from_json(receipt, &["bifrost", "publicationReceiptId"])),
|
||||
"githubPublicationReceiptId": publish_receipt.as_ref().and_then(|receipt| string_from_json(receipt, &["github", "publicationReceiptId"])),
|
||||
"upstreamMainSynced": sync_receipt.as_ref().and_then(sync_receipt_upstream_main_synced).unwrap_or(false),
|
||||
"bifrostPublicationReceiptId": null,
|
||||
"githubPublicationReceiptId": null,
|
||||
"upstreamMainSynced": false,
|
||||
"artifactRows": proof_artifacts,
|
||||
"publicationRows": proof_publication_rows,
|
||||
"tuiRows": proof_bundle_tui_rows,
|
||||
|
|
@ -12053,8 +12025,6 @@ fn run_readiness(args: ReadinessArgs) -> Result<Value> {
|
|||
let execute_receipt_path = work_receipt_path(&workspace, "execute", &item);
|
||||
let close_receipt_path = work_receipt_path(&workspace, "close", &item);
|
||||
let queue_run_receipt_path = artifact_dir.join("work-queue-run.json");
|
||||
let publish_receipt_path = work_receipt_path(&workspace, "publish", &item);
|
||||
let sync_receipt_path = work_receipt_path(&workspace, "sync", &item);
|
||||
let init_receipt_path = workspace
|
||||
.join(".epiphany")
|
||||
.join("repo-init")
|
||||
|
|
@ -12094,8 +12064,6 @@ fn run_readiness(args: ReadinessArgs) -> Result<Value> {
|
|||
.as_ref()
|
||||
.and_then(|receipt| string_from_json(receipt, &["mind", "stateCommitReceiptId"]))
|
||||
.is_some();
|
||||
let publish_receipt = read_json_if_exists(&publish_receipt_path)?;
|
||||
let sync_receipt = read_json_if_exists(&sync_receipt_path)?;
|
||||
|
||||
let mut rows = vec![
|
||||
readiness_path_row(
|
||||
|
|
@ -12171,13 +12139,18 @@ fn run_readiness(args: ReadinessArgs) -> Result<Value> {
|
|||
public_proof_path.exists(),
|
||||
"Redacted public proof bundle exists.",
|
||||
)?,
|
||||
bifrost_publication_readiness_row(&publish_receipt_path, publish_receipt.as_ref())?,
|
||||
upstream_main_sync_readiness_row(
|
||||
&workspace,
|
||||
&sync_receipt_path,
|
||||
sync_receipt.as_ref(),
|
||||
publish_receipt.as_ref(),
|
||||
)?,
|
||||
readiness_missing_row(
|
||||
"bifrost-publication",
|
||||
"Bifrost/GitHub",
|
||||
"provider-authored publication receipts",
|
||||
"Wait for Bifrost and the GitHub publication adapter; legacy local publish aggregates are not authority.",
|
||||
),
|
||||
readiness_missing_row(
|
||||
"upstream-main-sync",
|
||||
"Bifrost/GitHub/Maintainer",
|
||||
"provider-authored merge evidence + Git ancestry",
|
||||
"Wait for provider-authored merge evidence, then inspect upstream ancestry; legacy local sync aggregates are not authority.",
|
||||
),
|
||||
];
|
||||
let default_idunn_lifecycle_receipt = artifact_dir.join("repo-work-service-audit.json");
|
||||
let idunn_lifecycle_path = args.idunn_lifecycle_receipt.as_ref().or_else(|| {
|
||||
|
|
@ -13716,8 +13689,6 @@ fn run_tick(args: TickArgs) -> Result<Value> {
|
|||
let adopt_receipt_path = work_receipt_path(&workspace, "adopt", &item);
|
||||
let execute_receipt_path = work_receipt_path(&workspace, "execute", &item);
|
||||
let close_receipt_path = work_receipt_path(&workspace, "close", &item);
|
||||
let publish_receipt_path = work_receipt_path(&workspace, "publish", &item);
|
||||
let sync_receipt_path = work_receipt_path(&workspace, "sync", &item);
|
||||
|
||||
let before_receipts = repo_work_receipt_state(
|
||||
&accept_receipt_path,
|
||||
|
|
@ -13726,8 +13697,6 @@ fn run_tick(args: TickArgs) -> Result<Value> {
|
|||
&adopt_receipt_path,
|
||||
&execute_receipt_path,
|
||||
&close_receipt_path,
|
||||
&publish_receipt_path,
|
||||
&sync_receipt_path,
|
||||
);
|
||||
|
||||
if let Some(brake_store) = local_verse_store.as_ref() {
|
||||
|
|
@ -13742,8 +13711,6 @@ fn run_tick(args: TickArgs) -> Result<Value> {
|
|||
&adopt_receipt_path,
|
||||
&execute_receipt_path,
|
||||
&close_receipt_path,
|
||||
&publish_receipt_path,
|
||||
&sync_receipt_path,
|
||||
);
|
||||
let now = Utc::now().to_rfc3339_opts(chrono::SecondsFormat::Secs, true);
|
||||
let receipt = json!({
|
||||
|
|
@ -13830,8 +13797,6 @@ fn run_tick(args: TickArgs) -> Result<Value> {
|
|||
&adopt_receipt_path,
|
||||
&execute_receipt_path,
|
||||
&close_receipt_path,
|
||||
&publish_receipt_path,
|
||||
&sync_receipt_path,
|
||||
);
|
||||
let now = Utc::now().to_rfc3339_opts(chrono::SecondsFormat::Secs, true);
|
||||
let receipt = json!({
|
||||
|
|
@ -13915,8 +13880,6 @@ fn run_tick(args: TickArgs) -> Result<Value> {
|
|||
&adopt_receipt_path,
|
||||
&execute_receipt_path,
|
||||
&close_receipt_path,
|
||||
&publish_receipt_path,
|
||||
&sync_receipt_path,
|
||||
);
|
||||
let now = Utc::now().to_rfc3339_opts(chrono::SecondsFormat::Secs, true);
|
||||
let receipt = json!({
|
||||
|
|
@ -14010,20 +13973,7 @@ fn run_tick(args: TickArgs) -> Result<Value> {
|
|||
let next_safe_move;
|
||||
let mut advanced_result = Value::Null;
|
||||
|
||||
if sync_receipt_path.exists() {
|
||||
action = "none".to_string();
|
||||
status = "noop".to_string();
|
||||
reason = "work item already has an upstream sync receipt".to_string();
|
||||
next_safe_move = "No branch-local scheduler action remains for this item.".to_string();
|
||||
} else if publish_receipt_path.exists() {
|
||||
action = "none".to_string();
|
||||
status = "noop".to_string();
|
||||
reason =
|
||||
"publication receipt exists; scheduler stops before merge/sync authority".to_string();
|
||||
next_safe_move =
|
||||
"Wait for provider-authored merge evidence, then inspect upstream Git ancestry."
|
||||
.to_string();
|
||||
} else if close_receipt_path.exists()
|
||||
if close_receipt_path.exists()
|
||||
&& read_json(&close_receipt_path)?
|
||||
.get("status")
|
||||
.and_then(Value::as_str)
|
||||
|
|
@ -14317,8 +14267,6 @@ fn run_tick(args: TickArgs) -> Result<Value> {
|
|||
&adopt_receipt_path,
|
||||
&execute_receipt_path,
|
||||
&close_receipt_path,
|
||||
&publish_receipt_path,
|
||||
&sync_receipt_path,
|
||||
);
|
||||
let now = Utc::now().to_rfc3339_opts(chrono::SecondsFormat::Secs, true);
|
||||
let receipt = json!({
|
||||
|
|
@ -14486,8 +14434,6 @@ fn repo_work_receipt_state(
|
|||
adopt: &Path,
|
||||
execute: &Path,
|
||||
close: &Path,
|
||||
publish: &Path,
|
||||
sync: &Path,
|
||||
) -> Value {
|
||||
json!({
|
||||
"accept": receipt_path_state(accept),
|
||||
|
|
@ -14496,8 +14442,6 @@ fn repo_work_receipt_state(
|
|||
"adopt": receipt_path_state(adopt),
|
||||
"execute": receipt_path_state(execute),
|
||||
"close": receipt_path_state(close),
|
||||
"publish": receipt_path_state(publish),
|
||||
"sync": receipt_path_state(sync),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -14564,292 +14508,6 @@ fn readiness_missing_row(kind: &str, owner: &str, required_schema: &str, note: &
|
|||
})
|
||||
}
|
||||
|
||||
fn bifrost_publication_readiness_row(path: &Path, receipt: Option<&Value>) -> Result<Value> {
|
||||
let Some(receipt) = receipt else {
|
||||
return Ok(readiness_missing_row(
|
||||
"bifrost-publication",
|
||||
"Bifrost/GitHub",
|
||||
"epiphany.repo_work_publish_receipt.v0 + gamecult.bifrost.body_change_publication_receipt.v0 + gamecult.bifrost.github_publication_receipt.v0",
|
||||
"Wait for Bifrost and the GitHub adapter to publish their receipts before readiness review.",
|
||||
));
|
||||
};
|
||||
|
||||
let schema_ok = string_from_json(receipt, &["schemaVersion"]).as_deref()
|
||||
== Some("epiphany.repo_work_publish_receipt.v0");
|
||||
let status_ok =
|
||||
string_from_json(receipt, &["status"]).as_deref() == Some("publication-receipts-recorded");
|
||||
let publication_authorized =
|
||||
bool_from_json(receipt, &["authority", "publicationAuthorized"]) == Some(true);
|
||||
let upstream_not_claimed =
|
||||
bool_from_json(receipt, &["authority", "upstreamMainSynced"]) == Some(false);
|
||||
let merge_not_claimed =
|
||||
bool_from_json(receipt, &["authority", "mergeAuthorized"]) == Some(false);
|
||||
let private_sealed = bool_from_json(receipt, &["authority", "privateStateExposed"])
|
||||
== Some(false)
|
||||
&& bool_from_json(receipt, &["privateStateExposed"]).unwrap_or(false) == false;
|
||||
let local_verse_store = path_from_json(receipt, &["localVerseStore"]);
|
||||
let runtime_id =
|
||||
string_from_json(receipt, &["runtimeId"]).unwrap_or_else(|| "repo-swarm-local".to_string());
|
||||
let bifrost_publication_receipt_id =
|
||||
string_from_json(receipt, &["bifrost", "publicationReceiptId"]);
|
||||
let github_publication_receipt_id =
|
||||
string_from_json(receipt, &["bifrost", "githubPublicationReceiptId"]);
|
||||
let ledger_entry_id = string_from_json(receipt, &["bifrost", "ledgerEntryId"]);
|
||||
let pull_request_url = string_from_json(receipt, &["bifrost", "pullRequestUrl"]);
|
||||
let credit_receipt_count = receipt
|
||||
.get("bifrost")
|
||||
.and_then(|bifrost| bifrost.get("creditReceiptIds"))
|
||||
.and_then(Value::as_array)
|
||||
.map(Vec::len)
|
||||
.unwrap_or(0);
|
||||
let changed_path_count = receipt
|
||||
.get("changedPaths")
|
||||
.and_then(Value::as_array)
|
||||
.map(Vec::len)
|
||||
.unwrap_or(0);
|
||||
|
||||
let mut bifrost_latest_matches = false;
|
||||
let mut github_latest_matches = false;
|
||||
let mut bifrost_private_sealed = false;
|
||||
let mut github_private_sealed = false;
|
||||
let mut github_links_bifrost = false;
|
||||
let mut publication_status = "missing".to_string();
|
||||
let mut github_publication_status = "missing".to_string();
|
||||
|
||||
if let (Some(store), Some(bifrost_id), Some(github_id)) = (
|
||||
local_verse_store.as_ref(),
|
||||
bifrost_publication_receipt_id.as_ref(),
|
||||
github_publication_receipt_id.as_ref(),
|
||||
) {
|
||||
let latest_bifrost = load_latest_epiphany_cultmesh_bifrost_body_change_publication_receipt(
|
||||
store,
|
||||
runtime_id.clone(),
|
||||
)?;
|
||||
let latest_github = load_latest_epiphany_cultmesh_bifrost_github_publication_receipt(
|
||||
store,
|
||||
runtime_id.clone(),
|
||||
)?;
|
||||
if let Some(latest) = latest_bifrost.as_ref() {
|
||||
bifrost_latest_matches = latest.receipt_id == *bifrost_id
|
||||
&& latest.github_publication_receipt_id == *github_id
|
||||
&& latest.bifrost_ledger_entry_id == ledger_entry_id.clone().unwrap_or_default()
|
||||
&& !latest.accepted_changed_paths.is_empty()
|
||||
&& !latest.credit_receipt_ids.is_empty();
|
||||
bifrost_private_sealed = !latest.private_state_exposed;
|
||||
publication_status = latest.status.clone();
|
||||
}
|
||||
if let Some(latest) = latest_github.as_ref() {
|
||||
github_latest_matches = latest.receipt_id == *github_id
|
||||
&& latest.bifrost_publication_receipt_id == *bifrost_id
|
||||
&& latest.hands_pr_receipt_id
|
||||
== string_from_json(receipt, &["handsReceipts", "prReceiptId"])
|
||||
.unwrap_or_default()
|
||||
&& latest.pull_request_url == pull_request_url.clone().unwrap_or_default()
|
||||
&& !latest.changed_paths.is_empty()
|
||||
&& !latest.ledger_entry_id.trim().is_empty();
|
||||
github_links_bifrost = latest.bifrost_publication_receipt_id == *bifrost_id;
|
||||
github_private_sealed = !latest.private_state_exposed;
|
||||
github_publication_status = latest.publication_status.clone();
|
||||
}
|
||||
}
|
||||
|
||||
let satisfied = schema_ok
|
||||
&& status_ok
|
||||
&& publication_authorized
|
||||
&& upstream_not_claimed
|
||||
&& merge_not_claimed
|
||||
&& private_sealed
|
||||
&& local_verse_store.is_some()
|
||||
&& bifrost_latest_matches
|
||||
&& github_latest_matches
|
||||
&& bifrost_private_sealed
|
||||
&& github_private_sealed
|
||||
&& github_links_bifrost
|
||||
&& credit_receipt_count > 0
|
||||
&& changed_path_count > 0
|
||||
&& ledger_entry_id
|
||||
.as_ref()
|
||||
.is_some_and(|id| !id.trim().is_empty())
|
||||
&& pull_request_url
|
||||
.as_ref()
|
||||
.is_some_and(|url| !url.trim().is_empty());
|
||||
|
||||
Ok(json!({
|
||||
"kind": "bifrost-publication",
|
||||
"owner": "Bifrost/GitHub",
|
||||
"requiredSchema": "epiphany.repo_work_publish_receipt.v0 + gamecult.bifrost.body_change_publication_receipt.v0 + gamecult.bifrost.github_publication_receipt.v0",
|
||||
"evidenceRef": existing_path_value(path),
|
||||
"artifactStatus": if path.exists() { "present" } else { "missing" },
|
||||
"schemaVersion": string_from_json(receipt, &["schemaVersion"]).unwrap_or_else(|| "missing".to_string()),
|
||||
"documentStatus": string_from_json(receipt, &["status"]).unwrap_or_else(|| "missing".to_string()),
|
||||
"bifrostPublicationReceiptId": bifrost_publication_receipt_id.unwrap_or_else(|| "missing".to_string()),
|
||||
"githubPublicationReceiptId": github_publication_receipt_id.unwrap_or_else(|| "missing".to_string()),
|
||||
"ledgerEntryId": ledger_entry_id.unwrap_or_else(|| "missing".to_string()),
|
||||
"creditReceiptCount": credit_receipt_count,
|
||||
"changedPathCount": changed_path_count,
|
||||
"publicationStatus": publication_status,
|
||||
"githubPublicationStatus": github_publication_status,
|
||||
"bifrostLatestMatches": bifrost_latest_matches,
|
||||
"githubLatestMatches": github_latest_matches,
|
||||
"githubLinksBifrost": github_links_bifrost,
|
||||
"publicationAuthorized": publication_authorized,
|
||||
"upstreamMainSynced": !upstream_not_claimed,
|
||||
"mergeAuthorized": !merge_not_claimed,
|
||||
"privateStateExposed": !(private_sealed && bifrost_private_sealed && github_private_sealed),
|
||||
"satisfied": satisfied,
|
||||
"status": if satisfied { "satisfied" } else { "missing" },
|
||||
"note": "Bifrost and GitHub publication receipts are present in repo-local CultMesh and match the repo publish artifact without claiming upstream-main sync.",
|
||||
"readinessApprovalAuthorized": false,
|
||||
"serviceLifecycleAuthority": false,
|
||||
"handsActionAuthorized": false
|
||||
}))
|
||||
}
|
||||
|
||||
fn upstream_main_sync_readiness_row(
|
||||
workspace: &Path,
|
||||
path: &Path,
|
||||
receipt: Option<&Value>,
|
||||
publish_receipt: Option<&Value>,
|
||||
) -> Result<Value> {
|
||||
let Some(receipt) = receipt else {
|
||||
return Ok(readiness_missing_row(
|
||||
"upstream-main-sync",
|
||||
"Bifrost/GitHub",
|
||||
"epiphany.repo_work_sync_receipt.v0 + git merge-base ancestry proof",
|
||||
"Inspect provider-authored merge evidence and upstream Git ancestry.",
|
||||
));
|
||||
};
|
||||
|
||||
let schema_ok = string_from_json(receipt, &["schemaVersion"]).as_deref()
|
||||
== Some("epiphany.repo_work_sync_receipt.v0");
|
||||
let status_synced =
|
||||
string_from_json(receipt, &["status"]).as_deref() == Some("upstream-main-synced");
|
||||
let upstream_main_synced = bool_from_json(receipt, &["authority", "upstreamMainSynced"])
|
||||
== Some(true)
|
||||
|| bool_from_json(receipt, &["upstreamMainSynced"]) == Some(true);
|
||||
let publication_authorized =
|
||||
bool_from_json(receipt, &["authority", "publicationAuthorized"]) == Some(true);
|
||||
let merge_authorized = bool_from_json(receipt, &["authority", "mergeAuthorized"]) == Some(true);
|
||||
let private_sealed = bool_from_json(receipt, &["authority", "privateStateExposed"])
|
||||
== Some(false)
|
||||
&& bool_from_json(receipt, &["privateStateExposed"]).unwrap_or(false) == false;
|
||||
let upstream_ref = string_from_json(receipt, &["upstreamRef"]);
|
||||
let upstream_commit_sha = string_from_json(receipt, &["upstreamCommitSha"]);
|
||||
let published_commit_sha = string_from_json(receipt, &["publishedCommitSha"]);
|
||||
let merge_receipt_count = receipt
|
||||
.get("mergeReceipts")
|
||||
.and_then(Value::as_array)
|
||||
.map(Vec::len)
|
||||
.unwrap_or(0);
|
||||
let commit_receipt_id = string_from_json(receipt, &["handsReceipts", "commitReceiptId"]);
|
||||
let pr_receipt_id = string_from_json(receipt, &["handsReceipts", "prReceiptId"]);
|
||||
let bifrost_publication_receipt_id =
|
||||
string_from_json(receipt, &["bifrost", "publicationReceiptId"]);
|
||||
let github_publication_receipt_id =
|
||||
string_from_json(receipt, &["bifrost", "githubPublicationReceiptId"]);
|
||||
let ledger_entry_id = string_from_json(receipt, &["bifrost", "ledgerEntryId"]);
|
||||
|
||||
let mut upstream_ref_resolved = false;
|
||||
let mut upstream_ref_matches_receipt = false;
|
||||
let mut published_commit_resolved = false;
|
||||
let mut ancestry_proved = false;
|
||||
if let (Some(upstream_ref), Some(upstream_commit_sha), Some(published_commit_sha)) = (
|
||||
upstream_ref.as_ref(),
|
||||
upstream_commit_sha.as_ref(),
|
||||
published_commit_sha.as_ref(),
|
||||
) {
|
||||
let resolved_upstream = git_output(workspace, &["rev-parse", "--verify", upstream_ref]);
|
||||
if let Ok(resolved) = resolved_upstream {
|
||||
upstream_ref_resolved = true;
|
||||
upstream_ref_matches_receipt = resolved == *upstream_commit_sha;
|
||||
}
|
||||
published_commit_resolved =
|
||||
git_status_success(workspace, &["cat-file", "-e", published_commit_sha])?;
|
||||
ancestry_proved = git_status_success(
|
||||
workspace,
|
||||
&[
|
||||
"merge-base",
|
||||
"--is-ancestor",
|
||||
published_commit_sha,
|
||||
upstream_ref,
|
||||
],
|
||||
)?;
|
||||
}
|
||||
|
||||
let publish_receipt_matches = publish_receipt.is_some_and(|publish| {
|
||||
string_from_json(publish, &["handsReceipts", "commitSha"]) == published_commit_sha
|
||||
&& string_from_json(publish, &["handsReceipts", "commitReceiptId"]) == commit_receipt_id
|
||||
&& string_from_json(publish, &["handsReceipts", "prReceiptId"]) == pr_receipt_id
|
||||
&& string_from_json(publish, &["bifrost", "publicationReceiptId"])
|
||||
== bifrost_publication_receipt_id
|
||||
&& string_from_json(publish, &["bifrost", "githubPublicationReceiptId"])
|
||||
== github_publication_receipt_id
|
||||
&& string_from_json(publish, &["bifrost", "ledgerEntryId"]) == ledger_entry_id
|
||||
});
|
||||
|
||||
let satisfied = schema_ok
|
||||
&& status_synced
|
||||
&& upstream_main_synced
|
||||
&& publication_authorized
|
||||
&& merge_authorized
|
||||
&& private_sealed
|
||||
&& merge_receipt_count > 0
|
||||
&& upstream_ref_resolved
|
||||
&& upstream_ref_matches_receipt
|
||||
&& published_commit_resolved
|
||||
&& ancestry_proved
|
||||
&& publish_receipt_matches
|
||||
&& commit_receipt_id
|
||||
.as_ref()
|
||||
.is_some_and(|id| !id.trim().is_empty())
|
||||
&& pr_receipt_id
|
||||
.as_ref()
|
||||
.is_some_and(|id| !id.trim().is_empty())
|
||||
&& bifrost_publication_receipt_id
|
||||
.as_ref()
|
||||
.is_some_and(|id| !id.trim().is_empty())
|
||||
&& github_publication_receipt_id
|
||||
.as_ref()
|
||||
.is_some_and(|id| !id.trim().is_empty())
|
||||
&& ledger_entry_id
|
||||
.as_ref()
|
||||
.is_some_and(|id| !id.trim().is_empty());
|
||||
|
||||
Ok(json!({
|
||||
"kind": "upstream-main-sync",
|
||||
"owner": "Bifrost/GitHub",
|
||||
"requiredSchema": "epiphany.repo_work_sync_receipt.v0 + git merge-base ancestry proof",
|
||||
"evidenceRef": existing_path_value(path),
|
||||
"artifactStatus": if path.exists() { "present" } else { "missing" },
|
||||
"schemaVersion": string_from_json(receipt, &["schemaVersion"]).unwrap_or_else(|| "missing".to_string()),
|
||||
"documentStatus": string_from_json(receipt, &["status"]).unwrap_or_else(|| "missing".to_string()),
|
||||
"upstreamRef": upstream_ref.unwrap_or_else(|| "missing".to_string()),
|
||||
"upstreamCommitSha": upstream_commit_sha.unwrap_or_else(|| "missing".to_string()),
|
||||
"publishedCommitSha": published_commit_sha.unwrap_or_else(|| "missing".to_string()),
|
||||
"mergeReceiptCount": merge_receipt_count,
|
||||
"commitReceiptId": commit_receipt_id.unwrap_or_else(|| "missing".to_string()),
|
||||
"prReceiptId": pr_receipt_id.unwrap_or_else(|| "missing".to_string()),
|
||||
"bifrostPublicationReceiptId": bifrost_publication_receipt_id.unwrap_or_else(|| "missing".to_string()),
|
||||
"githubPublicationReceiptId": github_publication_receipt_id.unwrap_or_else(|| "missing".to_string()),
|
||||
"ledgerEntryId": ledger_entry_id.unwrap_or_else(|| "missing".to_string()),
|
||||
"upstreamMainSynced": upstream_main_synced,
|
||||
"publicationAuthorized": publication_authorized,
|
||||
"mergeAuthorized": merge_authorized,
|
||||
"upstreamRefResolved": upstream_ref_resolved,
|
||||
"upstreamRefMatchesReceipt": upstream_ref_matches_receipt,
|
||||
"publishedCommitResolved": published_commit_resolved,
|
||||
"ancestryProved": ancestry_proved,
|
||||
"publishReceiptMatches": publish_receipt_matches,
|
||||
"privateStateExposed": !private_sealed,
|
||||
"satisfied": satisfied,
|
||||
"status": if satisfied { "satisfied" } else { "missing" },
|
||||
"note": "Sync receipt proves the published commit is contained by the named upstream ref after maintainer/Bifrost merge authority.",
|
||||
"readinessApprovalAuthorized": false,
|
||||
"serviceLifecycleAuthority": false,
|
||||
"handsActionAuthorized": false
|
||||
}))
|
||||
}
|
||||
|
||||
fn idunn_lifecycle_readiness_row(path: &Path) -> Result<Value> {
|
||||
let document = read_json_if_exists(path)?;
|
||||
let schema_version = document
|
||||
|
|
@ -15172,50 +14830,6 @@ fn repo_work_proof_artifact_rows(receipts: &[(&str, &Path)]) -> Result<Vec<Value
|
|||
.collect()
|
||||
}
|
||||
|
||||
fn repo_work_proof_publication_rows(publish: Option<&Value>, sync: Option<&Value>) -> Vec<Value> {
|
||||
let mut rows = Vec::new();
|
||||
if let Some(receipt) = publish {
|
||||
rows.push(json!({
|
||||
"kind": "bifrost",
|
||||
"status": receipt.get("status").and_then(Value::as_str).unwrap_or("unknown"),
|
||||
"intentId": string_from_json(receipt, &["bifrost", "intentId"]),
|
||||
"publicationReceiptId": string_from_json(receipt, &["bifrost", "publicationReceiptId"]),
|
||||
"githubPublicationReceiptId": string_from_json(receipt, &["bifrost", "githubPublicationReceiptId"]),
|
||||
"ledgerEntryId": string_from_json(receipt, &["bifrost", "ledgerEntryId"]),
|
||||
"creditReceiptIds": receipt.get("bifrost").and_then(|bifrost| bifrost.get("creditReceiptIds")).cloned().unwrap_or(Value::Array(Vec::new())),
|
||||
"pullRequestUrl": string_from_json(receipt, &["bifrost", "pullRequestUrl"]),
|
||||
"privateStateExposed": false
|
||||
}));
|
||||
rows.push(json!({
|
||||
"kind": "github",
|
||||
"status": receipt.get("status").and_then(Value::as_str).unwrap_or("unknown"),
|
||||
"commitReceiptId": string_from_json(receipt, &["handsReceipts", "commitReceiptId"]),
|
||||
"commitSha": string_from_json(receipt, &["handsReceipts", "commitSha"]),
|
||||
"prReceiptId": string_from_json(receipt, &["handsReceipts", "prReceiptId"]),
|
||||
"pullRequestUrl": string_from_json(receipt, &["handsReceipts", "pullRequestUrl"]),
|
||||
"pullRequestNumber": receipt
|
||||
.get("handsReceipts")
|
||||
.and_then(|hands| hands.get("pullRequestNumber"))
|
||||
.cloned()
|
||||
.unwrap_or(Value::Null),
|
||||
"pullRequestTitle": string_from_json(receipt, &["handsReceipts", "pullRequestTitle"]),
|
||||
"privateStateExposed": false
|
||||
}));
|
||||
}
|
||||
if let Some(receipt) = sync {
|
||||
rows.push(json!({
|
||||
"kind": "upstream-main",
|
||||
"status": receipt.get("status").and_then(Value::as_str).unwrap_or("unknown"),
|
||||
"upstreamRef": string_from_json(receipt, &["upstreamRef"]),
|
||||
"publishedCommitSha": string_from_json(receipt, &["publishedCommitSha"]),
|
||||
"upstreamCommitSha": string_from_json(receipt, &["upstreamCommitSha"]),
|
||||
"upstreamMainSynced": sync_receipt_upstream_main_synced(receipt).unwrap_or(false),
|
||||
"privateStateExposed": false
|
||||
}));
|
||||
}
|
||||
rows
|
||||
}
|
||||
|
||||
fn repo_work_public_proof_bundle(overview: &Value) -> Result<Value> {
|
||||
let proof = overview
|
||||
.get("proofBundle")
|
||||
|
|
@ -15308,18 +14922,6 @@ fn repo_work_public_proof_tui_rows(
|
|||
)]
|
||||
}
|
||||
|
||||
fn sync_receipt_upstream_main_synced(receipt: &Value) -> Option<bool> {
|
||||
receipt
|
||||
.get("upstreamMainSynced")
|
||||
.and_then(Value::as_bool)
|
||||
.or_else(|| {
|
||||
receipt
|
||||
.get("authority")
|
||||
.and_then(|authority| authority.get("upstreamMainSynced"))
|
||||
.and_then(Value::as_bool)
|
||||
})
|
||||
}
|
||||
|
||||
fn repo_work_proof_bundle_tui_rows(
|
||||
item: &str,
|
||||
branch: &str,
|
||||
|
|
@ -15344,22 +14946,8 @@ fn repo_work_overview_gate(
|
|||
adopt: Option<&Value>,
|
||||
execute: Option<&Value>,
|
||||
close: Option<&Value>,
|
||||
publish: Option<&Value>,
|
||||
sync: Option<&Value>,
|
||||
) -> (&'static str, &'static str, &'static str) {
|
||||
if sync.is_some() {
|
||||
(
|
||||
"complete-or-awaiting-new-work",
|
||||
"none",
|
||||
"No local branch-work action remains for this item.",
|
||||
)
|
||||
} else if publish.is_some() {
|
||||
(
|
||||
"awaiting-upstream-sync",
|
||||
"merge-or-sync-receipt-missing",
|
||||
"After provider-authored merge evidence arrives, inspect upstream Git ancestry.",
|
||||
)
|
||||
} else if close
|
||||
if close
|
||||
.and_then(|receipt| receipt.get("status"))
|
||||
.and_then(Value::as_str)
|
||||
== Some("closed")
|
||||
|
|
@ -15779,16 +15367,6 @@ fn git_output(workspace: &Path, args: &[&str]) -> Result<String> {
|
|||
Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
|
||||
}
|
||||
|
||||
fn git_status_success(workspace: &Path, args: &[&str]) -> Result<bool> {
|
||||
let output = Command::new("git")
|
||||
.arg("-C")
|
||||
.arg(workspace)
|
||||
.args(args)
|
||||
.output()
|
||||
.with_context(|| format!("failed to run git {}", args.join(" ")))?;
|
||||
Ok(output.status.success())
|
||||
}
|
||||
|
||||
fn git_add_paths(workspace: &Path, paths: &[String]) -> Result<()> {
|
||||
let mut command = Command::new("git");
|
||||
command.arg("-C").arg(workspace).arg("add").arg("--");
|
||||
|
|
|
|||
|
|
@ -340,3 +340,14 @@ strings and promoted Git ancestry into `mergeAuthorized=true`. Both commands
|
|||
and the whole-path stop-classification smoke that depended on them are deleted.
|
||||
The coherent split is Bifrost intent submission, provider-authored publication
|
||||
and review receipts, and read-only Git ancestry inspection.
|
||||
|
||||
## Dead-writer artifacts as living readiness authority
|
||||
|
||||
Overview, readiness, scheduler, and public-proof assembly still read legacy
|
||||
`work-publish-*.json` and `work-sync-*.json` aggregates after their writers were
|
||||
deleted. A preexisting or forged file could therefore advance gates, populate
|
||||
publication rows, satisfy readiness, or stop scheduling. Those readers,
|
||||
receipt-chain slots, artifact rows, gate parameters, and readiness functions
|
||||
are deleted. Repo work now stops honestly at `awaiting-publication`; provider
|
||||
publication and merge evidence need a new owner-aligned ingest/projection path
|
||||
before readiness can advance.
|
||||
|
|
|
|||
|
|
@ -80,6 +80,10 @@ The confirmed conceptual substitutions have been cut:
|
|||
receipt strings into publication authority; the second promoted arbitrary
|
||||
merge strings plus Git ancestry into merge authority. Bifrost intent,
|
||||
provider receipts, and read-only ancestry are separate paths.
|
||||
- legacy `work-publish-*.json` and `work-sync-*.json` are no longer read by
|
||||
overview, readiness, scheduling, receipt-chain, or proof-bundle paths. Dead
|
||||
writer artifacts cannot remain living authority; closed work waits at
|
||||
`awaiting-publication` until an owner-aligned provider projection exists.
|
||||
|
||||
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.
|
||||
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -660,4 +660,4 @@ current_status:
|
|||
- Service lifecycle receipt history is now event-only: `load_epiphany_cultmesh_daemon_service_lifecycle_receipts` filters out the `epiphany-local/daemon-service-lifecycle-receipt/latest` mirror, while `load_latest_epiphany_cultmesh_daemon_service_lifecycle_receipt` remains the latest-state reader. Focused unit test `service_lifecycle_receipt_history_excludes_latest_mirror` proves two per-receipt writes return exactly two history records and latest points at the second. Fresh smoke `verse-query-lifecycle-history-filter-smoke` and live overview/triage `local-20260618-145632-497-efac6f0d` / `local-20260618-145632-321-867947af` prove compact swarm sights still expose service lifecycle attention plus the present elevated runbook artifact without daemon pokes or service mutation. Do not use a broad unscoped cargo test filter for this check on Windows; it fans out across bin harnesses and hit a broken pipe during this pass.
|
||||
- `epiphany-verse-query seed-compact` is the compact seed receipt for wrappers and read-only rites. The older `seed` command still prints the full local Verse context for explicit debugging, but compact wrapper modes now avoid full `seed`/final `query` readback after the combined overview proof exposed Windows debug stack overflow from full-context serialization pressure.
|
||||
last_completed_repo_swarm_cut: Huginn live-fire has crossed the first real repo Body from Persona pressure to branch-local Hands commit and Soul/Mind closure, and now has repeatable closure and redacted-public-proof mouths. On `E:\Projects\Huginn` branch `epiphany/huginn/first-awakening`, `tools/epiphany_local_run.ps1 -Mode repo-persona-intake` accepted item `huginn-inspection-readback-livefire`, Weksa/Persona intake remained sealed, and `epiphany-work derive-plan` lowered it to model-authored safe family `repo.status_section` for `README.md` only. `tools/epiphany_local_run.ps1 -Mode repo-swarm-run` advanced four bounded pulses: run-from-plan, adopt-from-plan, execute-from-plan, and close-from-execute. Huginn commit `e9b07c38fceabbdc89ea35c2156326c80c0393a2` updated only `README.md`; closure receipt `.epiphany\work\work-close-huginn-inspection-readback-livefire.json` records status `closed`, Soul verdict `passed`, Mind state commit `repo-work-close-huginn-inspection-readback-livefire-mind-commit`, safe family `repo.status_section`, path scope `README.md`, Bifrost publication gate, and `privateStateExposed=false`. Verification also ran Huginn's TypeScript compiler through concrete Node path: `C:\Program Files\nodejs\node.exe E:\Projects\Huginn\node_modules\typescript\bin\tsc -p tsconfig.json` passed. Native verifier `epiphany-repo-livefire-closure-smoke --workspace E:\Projects\Huginn --item huginn-inspection-readback-livefire --expected-path README.md --expected-family repo.status_section --expected-gate awaiting-publication --expected-blocker bifrost-publication-missing` checks closure receipt, Mind map entry, overview gate/blocker, authority seals, and `git show` changed paths, returning `status=ok`, `soulVerdict=passed`, `publicationGate=Bifrost`, and `privateStateExposed=false`. Wrapper `tools/epiphany_local_run.ps1 -Mode repo-livefire-closure -Workspace E:\Projects\Huginn -RepoWorkItem huginn-inspection-readback-livefire -SkipBuild` exposes the same read-only proof through the local operator mouth; artifact `local-20260621-190156-803-2f85ba15` printed commit, path, gate, blocker, Soul verdict, Mind commit receipt, and `privateStateExposed=False` without push, merge, publication, or target mutation. New wrapper `tools/epiphany_local_run.ps1 -Mode repo-work-public-proof -Workspace E:\Projects\Huginn -RepoWorkItem huginn-inspection-readback-livefire -SkipBuild` exports the redacted proof bundle and repo-local Verse index without publishing; artifact `local-20260621-190645-345-4555b1dc` wrote `.epiphany\public\proof-bundles\repo-work-public-proof-huginn-inspection-readback-livefire.json`, proof id `repo-work-public-proof-huginn-inspection-readback-livefire`, SHA-256 `857545b199f3e37eb06c2e757e5cfc201958e46667bb1f8403fd333a22620f63`, nine artifact rows, zero publication rows, and `privateStateExposed=False`. swarm overview readback `local-20260621-190701-140-b9519ec6` sees the `REPO-WORK-PUBLIC-PROOF` row and action row from Huginn's repo-local Verse with the same SHA-256 while Bifrost publication remains missing. Launcher compact modes are now named compact operator-context modes instead of read-only modes, and `bifrost-public-proof` summaries print item, target public Verse, room, proof SHA-256, review receipts, and credit receipts so publication receipts are auditable without claiming upstream sync.
|
||||
next_action: Continue the conceptual-substitution modeling pass beyond receipt writers. Fresh-repo MVP proof plus `epiphany-work publish`/`sync` are deleted: caller strings can no longer become PR, review, Bifrost, Soul, or merge authority, and Git ancestry remains read-only substrate evidence. Audit legacy publish/sync artifact readers so old local aggregates cannot remain readiness owners. Then inventory remaining projections, caches, adapters, schedulers, coordinators, and compatibility surfaces that assert facts owned elsewhere.
|
||||
next_action: Continue the conceptual-substitution modeling pass beyond receipt writers. Fresh-repo proof, `epiphany-work publish`/`sync`, and every legacy publish/sync aggregate reader are deleted; dead-writer JSON can no longer advance overview, readiness, scheduler, receipt-chain, or proof state. Design owner-aligned Bifrost/GitHub/maintainer evidence projection only when the real ingest boundary is known. Meanwhile inventory remaining projections, caches, adapters, schedulers, coordinators, and compatibility surfaces that assert facts owned elsewhere.
|
||||
|
|
|
|||
Reference in a new issue