diff --git a/epiphany-core/src/bin/epiphany-work.rs b/epiphany-core/src/bin/epiphany-work.rs index c7304773..b524a770 100644 --- a/epiphany-core/src/bin/epiphany-work.rs +++ b/epiphany-core/src/bin/epiphany-work.rs @@ -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 { 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 { 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 { .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 { ("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 { &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 { ("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::::new(); let proof_bundle_tui_rows = repo_work_proof_bundle_tui_rows( &item, &branch, @@ -11908,16 +11882,14 @@ fn run_overview(args: OverviewArgs) -> Result { "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 { 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 { .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 { 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 { 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 { &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 { &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 { &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 { &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 { 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 { &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 { - 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 { - 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 { 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, sync: Option<&Value>) -> Vec { - 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 { 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 { - 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 { Ok(String::from_utf8_lossy(&output.stdout).trim().to_string()) } -fn git_status_success(workspace: &Path, args: &[&str]) -> Result { - 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("--"); diff --git a/notes/conceptual-substitution-audit-2026-07-12.md b/notes/conceptual-substitution-audit-2026-07-12.md index fb83e273..5dfaf7f5 100644 --- a/notes/conceptual-substitution-audit-2026-07-12.md +++ b/notes/conceptual-substitution-audit-2026-07-12.md @@ -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. diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index 08b6f12a..a325d9d2 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -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. diff --git a/state/ledgers.msgpack b/state/ledgers.msgpack index 69025f13..eec81ed5 100644 Binary files a/state/ledgers.msgpack and b/state/ledgers.msgpack differ diff --git a/state/map.yaml b/state/map.yaml index 7c4a87ad..a540793b 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -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.