diff --git a/epiphany-core/src/bin/epiphany-repo-planning-brief-family-smoke.rs b/epiphany-core/src/bin/epiphany-repo-planning-brief-family-smoke.rs index bf53c895..a25d9cd9 100644 --- a/epiphany-core/src/bin/epiphany-repo-planning-brief-family-smoke.rs +++ b/epiphany-core/src/bin/epiphany-repo-planning-brief-family-smoke.rs @@ -1,9 +1,9 @@ +use anyhow::anyhow; use anyhow::Context; use anyhow::Result; -use anyhow::anyhow; use chrono::Utc; -use serde_json::Value; use serde_json::json; +use serde_json::Value; use std::env; use std::fs; use std::path::Path; @@ -204,6 +204,86 @@ fn run_smoke(args: Args) -> Result { &["closureReview", "sourceGrounding", "pathScopeMatched"], true, )?; + require_eq( + &close, + &[ + "closureReview", + "familyAssertions", + "safeFamilyPlanning", + "schemaVersion", + ], + "epiphany.repo_work_safe_family_planning_readback.v0", + )?; + require_eq( + &close, + &[ + "closureReview", + "familyAssertions", + "safeFamilyPlanning", + "sourceSafeFamily", + ], + "repo.planning_brief", + )?; + require_bool( + &close, + &[ + "closureReview", + "familyAssertions", + "safeFamilyPlanning", + "allExpectedCandidateFamiliesPresent", + ], + true, + )?; + require_bool( + &close, + &[ + "closureReview", + "familyAssertions", + "safeFamilyPlanning", + "allPlanningRequirementsPresent", + ], + true, + )?; + require_bool( + &close, + &[ + "closureReview", + "familyAssertions", + "safeFamilyPlanning", + "allRequiredGatesPresent", + ], + true, + )?; + require_bool( + &close, + &[ + "closureReview", + "familyAssertions", + "safeFamilyPlanning", + "authorityDenied", + ], + true, + )?; + require_bool( + &close, + &[ + "closureReview", + "familyAssertions", + "safeFamilyPlanning", + "privateStateExposed", + ], + false, + )?; + require_u64( + &close, + &[ + "closureReview", + "familyAssertions", + "safeFamilyPlanning", + "candidateNextSafeFamilyCount", + ], + 6, + )?; require_bool(&close, &["privateStateExposed"], false)?; require_text( &brief_text, @@ -223,12 +303,18 @@ fn run_smoke(args: Args) -> Result { require_text(&brief_text, "\"repo.work_order\"")?; require_text(&brief_text, "\"repo.verification_request\"")?; require_text(&brief_text, "\"repo.publication_request\"")?; - require_text(&brief_text, "candidate_items_must_name_requested_paths = true")?; + require_text( + &brief_text, + "candidate_items_must_name_requested_paths = true", + )?; require_text( &brief_text, "candidate_items_must_name_verification_asks = true", )?; - require_text(&brief_text, "candidate_items_must_name_evidence_needs = true")?; + require_text( + &brief_text, + "candidate_items_must_name_evidence_needs = true", + )?; require_text(&brief_text, "[gates]")?; require_text(&brief_text, "mind_interpreter_required = true")?; require_text(&brief_text, "self_queue_selection_required = true")?; @@ -269,6 +355,11 @@ fn run_smoke(args: Args) -> Result { "soulVerdict": close["soul"]["verdict"], "familyAssertionsStatus": close["closureReview"]["familyAssertions"]["status"], "pathScopeMatched": close["closureReview"]["sourceGrounding"]["pathScopeMatched"], + "safeFamilyPlanningSchema": close["closureReview"]["familyAssertions"]["safeFamilyPlanning"]["schemaVersion"], + "candidateNextSafeFamilyCount": close["closureReview"]["familyAssertions"]["safeFamilyPlanning"]["candidateNextSafeFamilyCount"], + "allExpectedCandidateFamiliesPresent": close["closureReview"]["familyAssertions"]["safeFamilyPlanning"]["allExpectedCandidateFamiliesPresent"], + "allRequiredGatesPresent": close["closureReview"]["familyAssertions"]["safeFamilyPlanning"]["allRequiredGatesPresent"], + "authorityDenied": close["closureReview"]["familyAssertions"]["safeFamilyPlanning"]["authorityDenied"], "briefIsDraft": true, "candidateActionsNonAuthoritative": true, "mindInterpreterRequired": true, @@ -393,6 +484,22 @@ fn require_bool(value: &Value, path: &[&str], expected: bool) -> Result<()> { } } +fn require_u64(value: &Value, path: &[&str], expected: u64) -> Result<()> { + let actual = path + .iter() + .try_fold(value, |current, key| current.get(*key)) + .and_then(Value::as_u64); + if actual == Some(expected) { + Ok(()) + } else { + Err(anyhow!( + "expected {} to be {expected}, got {:?}", + path.join("."), + actual + )) + } +} + fn require_text(haystack: &str, needle: &str) -> Result<()> { if haystack.contains(needle) { Ok(()) diff --git a/epiphany-core/src/bin/epiphany-work.rs b/epiphany-core/src/bin/epiphany-work.rs index e4b3a3c6..e4023d23 100644 --- a/epiphany-core/src/bin/epiphany-work.rs +++ b/epiphany-core/src/bin/epiphany-work.rs @@ -1,30 +1,8 @@ +use anyhow::anyhow; use anyhow::Context; use anyhow::Result; -use anyhow::anyhow; use chrono::DateTime; use chrono::Utc; -use epiphany_core::EPIPHANY_CULTMESH_LOCAL_AREA_VERSE_ID; -use epiphany_core::EPIPHANY_CULTMESH_REPO_WORK_MAP_ENTRY_LATEST_KEY; -use epiphany_core::EPIPHANY_CULTMESH_REPO_WORK_MAP_ENTRY_SCHEMA_VERSION; -use epiphany_core::EPIPHANY_CULTMESH_REPO_WORK_OVERVIEW_SCHEMA_VERSION; -use epiphany_core::EPIPHANY_CULTMESH_REPO_WORK_PUBLIC_PROOF_SCHEMA_VERSION; -use epiphany_core::EpiphanyCultMeshRepoWorkMapEntry; -use epiphany_core::EpiphanyCultMeshRepoWorkOverviewEntry; -use epiphany_core::EpiphanyCultMeshRepoWorkPublicProofEntry; -use epiphany_core::HANDS_ACTION_INTENT_SCHEMA_VERSION; -use epiphany_core::HANDS_COMMAND_RECEIPT_TYPE; -use epiphany_core::HANDS_COMMIT_RECEIPT_TYPE; -use epiphany_core::HANDS_PATCH_RECEIPT_TYPE; -use epiphany_core::HANDS_PR_RECEIPT_TYPE; -use epiphany_core::HandsActionIntent; -use epiphany_core::MIND_GATEWAY_REVIEW_SCHEMA_VERSION; -use epiphany_core::MindGatewayDecision; -use epiphany_core::MindGatewayReview; -use epiphany_core::RuntimeSpineInitOptions; -use epiphany_core::SOUL_VERDICT_RECEIPT_SCHEMA_VERSION; -use epiphany_core::SUBSTRATE_GATE_REPO_ACCESS_GRANT_RECEIPT_SCHEMA_VERSION; -use epiphany_core::SoulVerdictReceipt; -use epiphany_core::SubstrateGateRepoAccessGrantReceipt; use epiphany_core::hands_action_review_for_intent; use epiphany_core::hands_command_receipt_for_review; use epiphany_core::hands_commit_receipt_for_review; @@ -56,10 +34,32 @@ use epiphany_core::runtime_latest_hands_receipt_chain_after; use epiphany_core::write_epiphany_cultmesh_repo_work_map_entry; use epiphany_core::write_epiphany_cultmesh_repo_work_overview; use epiphany_core::write_epiphany_cultmesh_repo_work_public_proof; +use epiphany_core::EpiphanyCultMeshRepoWorkMapEntry; +use epiphany_core::EpiphanyCultMeshRepoWorkOverviewEntry; +use epiphany_core::EpiphanyCultMeshRepoWorkPublicProofEntry; +use epiphany_core::HandsActionIntent; +use epiphany_core::MindGatewayDecision; +use epiphany_core::MindGatewayReview; +use epiphany_core::RuntimeSpineInitOptions; +use epiphany_core::SoulVerdictReceipt; +use epiphany_core::SubstrateGateRepoAccessGrantReceipt; +use epiphany_core::EPIPHANY_CULTMESH_LOCAL_AREA_VERSE_ID; +use epiphany_core::EPIPHANY_CULTMESH_REPO_WORK_MAP_ENTRY_LATEST_KEY; +use epiphany_core::EPIPHANY_CULTMESH_REPO_WORK_MAP_ENTRY_SCHEMA_VERSION; +use epiphany_core::EPIPHANY_CULTMESH_REPO_WORK_OVERVIEW_SCHEMA_VERSION; +use epiphany_core::EPIPHANY_CULTMESH_REPO_WORK_PUBLIC_PROOF_SCHEMA_VERSION; +use epiphany_core::HANDS_ACTION_INTENT_SCHEMA_VERSION; +use epiphany_core::HANDS_COMMAND_RECEIPT_TYPE; +use epiphany_core::HANDS_COMMIT_RECEIPT_TYPE; +use epiphany_core::HANDS_PATCH_RECEIPT_TYPE; +use epiphany_core::HANDS_PR_RECEIPT_TYPE; +use epiphany_core::MIND_GATEWAY_REVIEW_SCHEMA_VERSION; +use epiphany_core::SOUL_VERDICT_RECEIPT_SCHEMA_VERSION; +use epiphany_core::SUBSTRATE_GATE_REPO_ACCESS_GRANT_RECEIPT_SCHEMA_VERSION; use serde::Deserialize; use serde::Serialize; -use serde_json::Value; use serde_json::json; +use serde_json::Value; use sha2::Digest; use sha2::Sha256; use std::env; @@ -1467,9 +1467,9 @@ fn run_accept(args: AcceptArgs) -> Result { .join("swarm-online") .join("repo-swarm-online-receipt.json") }); - let online_receipt = read_json(&online_receipt_path).with_context( - || "repo swarm online receipt is required; run epiphany-swarm online first", - )?; + let online_receipt = read_json(&online_receipt_path).with_context(|| { + "repo swarm online receipt is required; run epiphany-swarm online first" + })?; let local_verse_store = args.local_verse_store.unwrap_or_else(|| { path_from_json(&online_receipt, &["localVerseStore"]) .unwrap_or_else(|| workspace.join(".epiphany").join("local-verse.ccmp")) @@ -1630,9 +1630,9 @@ fn run_persona_intake(args: PersonaIntakeArgs) -> Result { .join("swarm-online") .join("repo-swarm-online-receipt.json") }); - let online_receipt = read_json(&online_receipt_path).with_context( - || "repo swarm online receipt is required; run epiphany-swarm online first", - )?; + let online_receipt = read_json(&online_receipt_path).with_context(|| { + "repo swarm online receipt is required; run epiphany-swarm online first" + })?; let local_verse_store = args.local_verse_store.clone().unwrap_or_else(|| { path_from_json(&online_receipt, &["localVerseStore"]) .unwrap_or_else(|| workspace.join(".epiphany").join("local-verse.ccmp")) @@ -5747,6 +5747,7 @@ fn closure_family_assertions( let item_slug = sanitize(item); let committed_content = read_committed_file(workspace, commit_sha, &target_path)?; let mut assertions = Vec::new(); + let mut safe_family_planning = Value::Null; push_assertion( &mut assertions, "target-blob-present", @@ -6452,6 +6453,7 @@ fn closure_family_assertions( "Committed planning brief preserves private-state and transcript seals." .to_string(), ); + safe_family_planning = planning_brief_safe_family_readback(&content); } "repo.objective_draft" => { push_assertion( @@ -8042,12 +8044,97 @@ fn closure_family_assertions( "safeActionFamily": safe_family, "targetPath": target_path, "planReceiptPath": plan_receipt_path, + "safeFamilyPlanning": safe_family_planning, "assertions": assertions }), passed, )) } +fn planning_brief_safe_family_readback(content: &str) -> Value { + let candidate_families = [ + "repo.consensus_brief", + "repo.objective_draft", + "repo.task_card", + "repo.work_order", + "repo.verification_request", + "repo.publication_request", + ]; + let candidate_rows: Vec = candidate_families + .iter() + .map(|family| { + json!({ + "safeActionFamily": family, + "present": content.contains(&format!("\"{family}\"")), + }) + }) + .collect(); + let gates = json!({ + "mindInterpreterRequired": content.contains("mind_interpreter_required = true"), + "mindAdoptionRequired": content.contains("mind_adoption_required = true"), + "selfQueueSelectionRequired": content.contains("self_queue_selection_required = true"), + "substrateGateRequiredBeforeHands": content.contains("substrate_gate_required_before_hands = true"), + "handsReceiptsRequiredBeforeSoul": content.contains("hands_receipts_required_before_soul = true"), + "soulVerdictRequiredBeforeMindMapAdmission": content.contains("soul_verdict_required_before_mind_map_admission = true"), + "bifrostRequiredBeforePublication": content.contains("bifrost_required_before_publication = true"), + "idunnRequiredBeforeDeploymentExecution": content.contains("idunn_required_before_deployment_execution = true"), + }); + let requirements = json!({ + "oneSafeFamilyPerActionItem": content.contains("one_safe_family_per_action_item = true"), + "requestedPathsRequired": content.contains("candidate_items_must_name_requested_paths = true"), + "verificationAsksRequired": content.contains("candidate_items_must_name_verification_asks = true"), + "evidenceNeedsRequired": content.contains("candidate_items_must_name_evidence_needs = true"), + "deterministicLoweringRequired": content.contains("shell_commands_must_be_deterministic_lowerings = true"), + }); + let authority_denials = json!({ + "objectiveAdoptionAuthorized": content.contains("objective_adoption_authorized = true"), + "selfSchedulingAuthorized": content.contains("self_scheduling_authorized = true"), + "substrateAccessAuthorized": content.contains("substrate_access_authorized = true"), + "handsActionAuthorized": content.contains("hands_action_authorized = true"), + "shellCommandAuthorized": content.contains("shell_command_authorized = true"), + "commitAuthorized": content.contains("commit_authorized = true"), + "publicationAuthorized": content.contains("publication_authorized = true"), + "deploymentExecutionAuthority": content.contains("deployment_execution_authority = true"), + "crossBodyMutationAuthorized": content.contains("cross_body_mutation_authorized = true"), + "privateVerseRummaging": content.contains("private_verse_rummaging = true"), + "privateStateExposed": content.contains("private_state_exposed = true"), + "privateWorkerTranscriptsAllowed": content.contains("private_worker_transcripts_allowed = true"), + "rawResultPayloadsAllowed": content.contains("raw_result_payloads_allowed = true"), + }); + let present_count = candidate_rows + .iter() + .filter(|row| row.get("present").and_then(Value::as_bool) == Some(true)) + .count(); + let all_required_gates_present = gates + .as_object() + .map(|fields| fields.values().all(|value| value.as_bool() == Some(true))) + .unwrap_or(false); + let all_requirements_present = requirements + .as_object() + .map(|fields| fields.values().all(|value| value.as_bool() == Some(true))) + .unwrap_or(false); + let authority_denied = authority_denials + .as_object() + .map(|fields| fields.values().all(|value| value.as_bool() == Some(false))) + .unwrap_or(false); + json!({ + "schemaVersion": "epiphany.repo_work_safe_family_planning_readback.v0", + "owner": "Soul", + "sourceSafeFamily": "repo.planning_brief", + "candidateNextSafeFamilies": candidate_rows, + "candidateNextSafeFamilyCount": present_count, + "allExpectedCandidateFamiliesPresent": present_count == candidate_families.len(), + "requirements": requirements, + "gates": gates, + "allRequiredGatesPresent": all_required_gates_present, + "authorityDenials": authority_denials, + "authorityDenied": authority_denied, + "allPlanningRequirementsPresent": all_requirements_present, + "privateStateExposed": false, + "nextSafeMove": "Self or Mind may choose one candidate safe family as a separate reviewed action item; this readback grants no Hands, scheduling, publication, deployment, or state-admission authority." + }) +} + fn push_assertion(assertions: &mut Vec, id: &str, passed: bool, summary: String) { assertions.push(json!({ "assertionId": id, @@ -13197,7 +13284,11 @@ fn string_array_field(value: &Value, field: &str) -> Vec { } fn default_if_empty(values: Vec, defaults: Vec) -> Vec { - if values.is_empty() { defaults } else { values } + if values.is_empty() { + defaults + } else { + values + } } fn adopted_action_item_from_plan(plan: &Value) -> Value { diff --git a/notes/epiphany-repo-swarm-mvp-contract.md b/notes/epiphany-repo-swarm-mvp-contract.md index 868bf692..cf11f877 100644 --- a/notes/epiphany-repo-swarm-mvp-contract.md +++ b/notes/epiphany-repo-swarm-mvp-contract.md @@ -532,15 +532,22 @@ adoption/action/publication/cross-body authority, and `privateStateExposed=false`. The next family-friendly Imagination planning smoke proved safe-family -decomposition cargo: `.epiphany-smoke\repo-planning-brief-family-20260620-231539` -ran init -> online -> accept -> `derive-plan --action-family -repo-planning-brief --model-ref -repo-planning-brief-family-smoke-imagination-v1 --model-authored` -> tick -through run/adopt/execute/close on a fresh repo. The plan carried +decomposition cargo, and its closure readback now exposes the planning family +instead of only a generic pass bit: +`.epiphany-smoke\repo-planning-brief-family-20260620-235939` ran init -> +online -> accept -> `derive-plan --action-family repo-planning-brief +--model-ref repo-planning-brief-family-smoke-imagination-v1 --model-authored` +-> tick through run/adopt/execute/close on a fresh repo. The plan carried `safeActionFamily=repo.planning_brief`; Hands committed only `.epiphany/planning-briefs/repo-planning-brief-family.toml`; Soul passed with -`pathScopeMatched=true` and `familyAssertions.status=passed`; the committed -brief carried `schema_version = "epiphany.repo_planning_brief.v0"`, draft +`pathScopeMatched=true` and `familyAssertions.status=passed`; the closure +packet carried +`safeFamilyPlanning.schemaVersion=epiphany.repo_work_safe_family_planning_readback.v0`, +`candidateNextSafeFamilyCount=6`, +`allExpectedCandidateFamiliesPresent=true`, +`allPlanningRequirementsPresent=true`, `allRequiredGatesPresent=true`, +`authorityDenied=true`, and `privateStateExposed=false`. The committed brief +still carries `schema_version = "epiphany.repo_planning_brief.v0"`, draft Imagination decomposition state, candidate next safe families, requested-path / verification-ask / evidence-need requirements, Mind/Self/Substrate/Hands/Soul / Bifrost/Idunn gate ordering, denied objective adoption, scheduling, substrate @@ -1718,7 +1725,7 @@ temptation wearing clean robes. | Repo Body birth | `epiphany-repo init` exists and writes repo-local stores plus branch workbench intent. | Keep birth startup-only, review-gated, and branch-oriented. | | Local Verse online | `epiphany-swarm online` seeds repo-local CultMesh, standing-faculty SoA, topology, liveness, Eve, and tool sight. | Keep private Verse sealed while exposing operator-safe repo status. | | Persona/Bifrost intake | `epiphany-work accept` records pressure and candidate action refs without Hands authority. `epiphany-work persona-intake` now invokes the Persona bubble speech-audit path, records public discussion and candidate-action refs, then delegates to `accept`; wrapper mode `repo-persona-intake` exposes the operator mouth. | Deepen the intake-to-Imagination interpreter so richer model-authored action items can be proposed without granting Hands, publication, or durable-state authority at the mouth edge. | -| Imagination planning | `derive-plan` now writes a typed `epiphany.repo_work_imagination_action_items_receipt.v0` before the executable plan receipt. The action-item receipt can carry model provenance, allowed safe family, requested paths, verification asks, stop conditions, escalation reasons, planning facets (assumptions, constraints, non-goals, open questions, decision points, and evidence needs), and private-state seals; command text remains deterministic safe-family lowering for `append-worklog`, `planning-note`, `checklist-note`, `section-note` / `repo.markdown_managed_section`, `repo-status-section` / `repo.status_section`, `task-card` / `repo.task_card`, `repo-manifest` / `repo.body_manifest`, `repo-tool-capabilities` / `repo.tool_capabilities`, `repo-tool-request` / `repo.tool_request`, `repo-eve-surface` / `repo.eve_surface`, `repo-collaboration-policy` / `repo.collaboration_policy`, `repo-collaboration-topic` / `repo.collaboration_topic`, `repo-consensus-brief` / `repo.consensus_brief`, `repo-planning-brief` / `repo.planning_brief`, `repo-objective-draft` / `repo.objective_draft`, `repo-adoption-request` / `repo.adoption_request`, `repo-scheduling-request` / `repo.scheduling_request`, `repo-work-order` / `repo.work_order`, `repo-verification-request` / `repo.verification_request`, `repo-publication-request` / `repo.publication_request`, `repo-sync-request` / `repo.sync_request`, `repo-maintainer-review-request` / `repo.maintainer_review_request`, `repo-pr-request` / `repo.pr_request`, `repo-credit-request` / `repo.credit_request`, `repo-artifact-acceptance-request` / `repo.artifact_acceptance_request`, `repo-metrics-request` / `repo.metrics_request`, `repo-doctrine-update-request` / `repo.doctrine_update_request`, `repo-secret-policy-request` / `repo.secret_policy_request`, `repo-deployment-config` / `repo.deployment_config`, and `repo-deployment-request` / `repo.deployment_request`. `repo.planning_brief` is the rough-pressure decomposition family: it names candidate next safe families, requested-path / verification-ask / evidence-need requirements, and Mind/Self/Substrate/Hands/Soul/Bifrost/Idunn gates while granting no action authority. `adopt` now writes `epiphany.repo_work_mind_adoption_decision.v0` before the main adoption receipt cites the decision and grants branch-local Hands authority, and refuses plan-derived items that lack explicit verification asks or planning evidence needs. `plan` remains manual quarantine scaffolding. | Deepen further interpreter behavior and semantic closure/map readback without turning model text into arbitrary shell authority. | +| Imagination planning | `derive-plan` now writes a typed `epiphany.repo_work_imagination_action_items_receipt.v0` before the executable plan receipt. The action-item receipt can carry model provenance, allowed safe family, requested paths, verification asks, stop conditions, escalation reasons, planning facets (assumptions, constraints, non-goals, open questions, decision points, and evidence needs), and private-state seals; command text remains deterministic safe-family lowering for `append-worklog`, `planning-note`, `checklist-note`, `section-note` / `repo.markdown_managed_section`, `repo-status-section` / `repo.status_section`, `task-card` / `repo.task_card`, `repo-manifest` / `repo.body_manifest`, `repo-tool-capabilities` / `repo.tool_capabilities`, `repo-tool-request` / `repo.tool_request`, `repo-eve-surface` / `repo.eve_surface`, `repo-collaboration-policy` / `repo.collaboration_policy`, `repo-collaboration-topic` / `repo.collaboration_topic`, `repo-consensus-brief` / `repo.consensus_brief`, `repo-planning-brief` / `repo.planning_brief`, `repo-objective-draft` / `repo.objective_draft`, `repo-adoption-request` / `repo.adoption_request`, `repo-scheduling-request` / `repo.scheduling_request`, `repo-work-order` / `repo.work_order`, `repo-verification-request` / `repo.verification_request`, `repo-publication-request` / `repo.publication_request`, `repo-sync-request` / `repo.sync_request`, `repo-maintainer-review-request` / `repo.maintainer_review_request`, `repo-pr-request` / `repo.pr_request`, `repo-credit-request` / `repo.credit_request`, `repo-artifact-acceptance-request` / `repo.artifact_acceptance_request`, `repo-metrics-request` / `repo.metrics_request`, `repo-doctrine-update-request` / `repo.doctrine_update_request`, `repo-secret-policy-request` / `repo.secret_policy_request`, `repo-deployment-config` / `repo.deployment_config`, and `repo-deployment-request` / `repo.deployment_request`. `repo.planning_brief` is the rough-pressure decomposition family: it names candidate next safe families, requested-path / verification-ask / evidence-need requirements, and Mind/Self/Substrate/Hands/Soul/Bifrost/Idunn gates while granting no action authority; Soul closure now emits `epiphany.repo_work_safe_family_planning_readback.v0` for that family with candidate-family counts, gate/readiness flags, authority denials, and private-state seal. `adopt` writes `epiphany.repo_work_mind_adoption_decision.v0` before the main adoption receipt cites the decision and grants branch-local Hands authority, and refuses plan-derived items that lack explicit verification asks or planning evidence needs. `plan` remains manual quarantine scaffolding. | Deepen further interpreter behavior and semantic closure/map readback without turning model text into arbitrary shell authority. | | Self scheduling | `tick` and `serve` prove one-step branch-local advancement, brake refusal, active-turn refusal, cooldown, and stale-turn recovery; `tick` now routes executed branch-local work through the existing Soul/Modeling/Mind `close` gate; `queue-run` selects tick-actionable rows from the typed repo-work queue and delegates to `tick`; `epiphany-swarm run` is the bounded operator mouth over that queue/tick physiology; `repo-work-service-plan` and `repo-work-service-runbook` write Idunn lifecycle receipts/artifacts for the same queue-run command without launching it. | Keep any future queue-run service launch/install behind Idunn and explicit operator authority. | | Branch-local Hands work | `adopt` and `execute` create approved Hands gates, run planned commands, stage declared paths, commit on `epiphany/*`, and write receipts. | Keep mutation branch-contained and receipt-backed; broaden only through typed plan families, not ad hoc shell freedom. | | Soul/Modeling/Mind closure | `close` verifies the Hands commit, writes `epiphany.repo_work_closure_review.v0`, refuses path-scope mismatches, refuses missing/tampered/non-affirmative Mind adoption proof, runs known safe-family content assertions, optionally gates on model-authored closure verdicts, can require verification output to cite declared changed paths with `--require-source-grounding`, writes Soul/Modeling/Mind receipts, admits a compact typed repo map entry into `.epiphany/state/repo-work-map.msgpack`, and mirrors that admitted fact into local Verse as `epiphany.cultmesh.repo_work_map_entry.v0`. | Keep extending closure toward source-grounded semantic review and richer semantic map lenses, while preserving deterministic local closure for simple mechanical work. | diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index 61045b90..498041a2 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -155,7 +155,7 @@ remembers doctrine; the branch remembers the blade. - 2026-06-20: `repo-deployment-request` is now live as Idunn-facing deployment request cargo. `epiphany-work derive-plan --action-family repo-deployment-request` writes `.epiphany/deployment-requests/.toml` with safe family `repo.deployment_request`, status `awaiting-idunn-review`, git-push-observed-by-Idunn trigger, Idunn/Maintainer ownership, target environment, git ref/branch, deployment script ref, script hash or review ref, host access policy, secret policy, rollback plan, aftercare checks, Eyes/Mind/Soul/maintainer/secret-policy/Bifrost/Idunn deployment/aftercare receipt requirements, and denials for direct deployment, SSH, git push, service lifecycle, Hands, publication, merge, cross-body mutation, private Verse rummaging, and private-state exposure. Soul closure assertions inspect schema, family, summary, request state, antecedents, receipt contract, deployment packet, authority gates, and private-state seal. Focused smoke `.epiphany-smoke\repo-deployment-request-family-20260620-195605` ran init -> online -> accept -> repo-deployment-request derive-plan -> tick run/adopt/execute/close; Hands committed only `.epiphany/deployment-requests/repo-deployment-request-family.toml`, Soul passed with `pathScopeMatched=true`, `familyAssertions.status=passed`, `awaitingIdunnReview=true`, `deploymentTrigger=git-push-observed-by-idunn`, `deploymentAuthority=false`, `sshAuthority=false`, `gitPushAuthority=false`, `serviceLifecycleAuthority=false`, and `privateStateExposed=false`. Current remaining repo-swarm MVP organs are deeper interpreter semantics, further reviewed config/action request families, richer closure depth, and explicit Idunn deployment execution/audit under operator authority. - 2026-06-20: `repo-deployment-config` is now live as repo-owned Idunn deployment configuration cargo. `epiphany-work derive-plan --action-family repo-deployment-config` writes `.epiphany/deployment.toml` with safe family `repo.deployment_config`, `enabled=false`, owner `Idunn`, trigger `git-push-observed-by-idunn`, watched ref `refs/heads/main`, deployment script ref, script hash/review requirement, host policy, secret policy, rollback, aftercare checks, Idunn CultMesh intent/receipt/aftercare contracts, daemon-owned execution, and denials for direct deployment, SSH, git push, service lifecycle, Hands, publication, merge, cross-body mutation, private Verse rummaging, and private-state exposure. Focused smoke `.epiphany-smoke\repo-deployment-config-family-20260620-211809` ran init -> online -> accept -> repo-deployment-config derive-plan -> tick run/adopt/execute/close; Hands committed only `.epiphany/deployment.toml`, Soul passed with `pathScopeMatched=true`, `familyAssertions.status=passed`, `deploymentConfigEnabled=false`, `daemonOwnsExecution=true`, and `privateStateExposed=false`. Current remaining repo-swarm MVP organs are deeper interpreter semantics, richer closure depth, and explicit Idunn deployment execution/audit under operator authority. - 2026-06-20: `derive-plan` action-item receipts now carry richer model-authored planning facets without widening command authority, and `adopt --from-plan` now preserves the chosen Imagination action item in the Mind adoption receipt. New CLI fields `--assumption`, `--constraint`, `--non-goal`, `--open-question`, `--decision-point`, and `--evidence-need` are recorded under `planningFacets` in `epiphany.repo_work_imagination_action_items_receipt.v0`, mirrored into the plan derivation's `actionItemReceipt`, then copied into `epiphany.repo_work_adoption_receipt.v0` as `adoptedActionItem`; deterministic defaults are emitted when a model does not supply them. Focused smoke `.epiphany-smoke\repo-planning-facets-20260620-164958` ran init -> online -> accept -> model-authored `derive-plan --action-family planning-note` with all facet fields -> tick run/adopt/execute/close; the action-item receipt preserved assumptions, constraints, non-goals, open questions, decision points, and evidence needs while `handsAuthorityGranted=false`, `durableStateAdmitted=false`, `handsCommandAuthority=false`, `durableStateAuthority=false`, and `privateStateExposed=false`; the adoption receipt preserved `adoptedActionItem.safeActionFamily=repo.markdown_planning_note`, planning facets, `adoptedActionItem.handsCommandAuthority=false`, `adoptedActionItem.durableStateAuthority=false`, `adoptedActionItem.publicationAuthorized=false`, `authority.handsAuthorityGranted=true`, `authority.durableStateAdmitted=false`, and `privateStateExposed=false`; Soul closure passed with family assertions and path scope matched. Current remaining repo-swarm MVP organs are deeper interpreter/adoption semantics, more useful repo-owned configuration/action families, and Idunn-owned queue-run service lifecycle under explicit operator authority. -- 2026-06-20: `repo-planning-brief` is now live as the family-friendly Imagination decomposition cargo. `epiphany-work derive-plan --action-family repo-planning-brief` writes `.epiphany/planning-briefs/.toml` with safe family `repo.planning_brief`, status `draft`, candidate next safe families, requested-path / verification-ask / evidence-need requirements, and Mind/Self/Substrate/Hands/Soul/Bifrost/Idunn gate ordering while denying objective adoption, scheduling, substrate access, Hands action, shell, commit, publication, deployment execution, service lifecycle, cross-body mutation, private transcripts, raw-result payloads, and private-state exposure. Soul closure assertions inspect schema, family, summary, decomposition contract, gate order, authority seals, and private-state seals. Focused smoke `.epiphany-smoke\repo-planning-brief-family-20260620-231539` ran init -> online -> accept -> repo-planning-brief derive-plan -> tick run/adopt/execute/close; Hands committed only `.epiphany/planning-briefs/repo-planning-brief-family.toml`, Soul passed with `pathScopeMatched=true`, `familyAssertions.status=passed`, `mindInterpreterRequired=true`, `soulEvidenceNeedsRequired=true`, `idunnDeploymentExecutionRequired=true`, and `privateStateExposed=false`. Current remaining repo-swarm MVP organs are deeper interpreter semantics, richer closure/map readback, and Idunn-owned queue-run service lifecycle under explicit operator authority. +- 2026-06-20: `repo-planning-brief` is live as the family-friendly Imagination decomposition cargo, and Soul closure now emits a typed safe-family planning readback for it. `epiphany-work derive-plan --action-family repo-planning-brief` writes `.epiphany/planning-briefs/.toml` with safe family `repo.planning_brief`, status `draft`, candidate next safe families, requested-path / verification-ask / evidence-need requirements, and Mind/Self/Substrate/Hands/Soul/Bifrost/Idunn gate ordering while denying objective adoption, scheduling, substrate access, Hands action, shell, commit, publication, deployment execution, service lifecycle, cross-body mutation, private transcripts, raw-result payloads, and private-state exposure. Closure `familyAssertions.safeFamilyPlanning` now carries `epiphany.repo_work_safe_family_planning_readback.v0` with candidate-family rows/count, planning requirement flags, gate flags, authority-denial flags, and the private-state seal. Focused smoke `.epiphany-smoke\repo-planning-brief-family-20260620-235939` ran init -> online -> accept -> repo-planning-brief derive-plan -> tick run/adopt/execute/close; Hands committed only `.epiphany/planning-briefs/repo-planning-brief-family.toml`, Soul passed with `pathScopeMatched=true`, `familyAssertions.status=passed`, `candidateNextSafeFamilyCount=6`, `allExpectedCandidateFamiliesPresent=true`, `allRequiredGatesPresent=true`, `authorityDenied=true`, and `privateStateExposed=false`. Current remaining repo-swarm MVP organs are deeper interpreter semantics, richer closure/map readback, and Idunn-owned queue-run service lifecycle under explicit operator authority. - 2026-06-20: Gjallar repo-work map sight now includes semantic stage lenses. `epiphany-verse-query gjallar`, swarm overview, and swarm triage expose `repoWorkMapStageLensRows` plus `REPO-WORK-MAP-STAGE` rows derived from Mind-admitted local Verse map entries, grouping safe families into stages and owning organs such as `imagination-planning` / `Imagination`, `hands-execution-request` / `Hands`, `soul-verification-request` / `Soul`, `bifrost-publication-accounting` / `Bifrost`, and `idunn-deployment` / `Idunn`. Focused smoke `.epiphany-smoke\repo-close-mind-adoption-guard-20260620-232414` proves the stage lens for accepted `repo.markdown_planning_note` work reports `stage=imagination-planning`, `owner=Imagination`, latest item/commit/Mind commit receipt, Bifrost gate, and `privateStateExposed=false`. This is sight only; Gjallar still does not schedule, publish, merge, deploy, keep daemons alive, or admit Mind state. - 2026-06-20: Gjallar repo-work map sight now includes next-publication-gate lenses. `epiphany-verse-query gjallar`, swarm overview, and swarm triage expose `repoWorkMapGateLensRows` plus `REPO-WORK-MAP-GATE` rows derived from the same Mind-admitted local Verse map entries, grouping accepted consequences by publication gate and naming the owning gate organ. Focused smoke `.epiphany-smoke\repo-close-mind-adoption-guard-20260620-233353` proves accepted `repo.markdown_planning_note` work reports `gate=Bifrost`, `owner=Bifrost`, latest item/commit/Mind commit receipt, `sightOnly=true`, `publicationAuthorized=false`, and `privateStateExposed=false`. This is sight only; Bifrost still owns publication/credit/upstream review and Gjallar does not schedule, publish, merge, deploy, keep daemons alive, or admit Mind state. - 2026-06-20: Gjallar repo-work map sight now includes per-entry semantic readback rows. `epiphany-verse-query gjallar`, swarm overview, and swarm triage expose `repoWorkMapSemanticRows` plus `REPO-WORK-MAP-SEMANTIC` rows derived from Mind-admitted local Verse map entries, combining durable modeling summary, safe family, stage owner, publication gate owner, latest commit, and Mind commit receipt for each accepted item. Focused smoke `.epiphany-smoke\repo-close-mind-adoption-guard-20260620-234131` proves accepted `repo.markdown_planning_note` work reports `stage=imagination-planning`, `stageOwner=Imagination`, `gateOwner=Bifrost`, the durable modeling summary, `sightOnly=true`, `publicationAuthorized=false`, and `privateStateExposed=false` while counterfeit Mind adoption is still refused. This is compact meaning readback only; Gjallar still does not schedule, publish, merge, deploy, keep daemons alive, or admit Mind state. diff --git a/state/ledgers.msgpack b/state/ledgers.msgpack index 4d2cad49..ce39ed9f 100644 Binary files a/state/ledgers.msgpack and b/state/ledgers.msgpack differ diff --git a/state/map.yaml b/state/map.yaml index a4b9aca0..03d3adc5 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -641,5 +641,5 @@ current_status: - `tools/epiphany_local_run.ps1 -Mode swarm-online-runbook` now emits an explicit Idunn preflight summary before the operator elevation boundary. Its JSON and one-line summary report `preflightStatus`, child artifact present/hash-verified/mismatch/missing counts, aggregate service execution failed/missing check counts, child preflight rows with expected/actual SHA-256s, and private-state exposure. Live proof `local-20260619-025627-410-9724e2f6` generated the non-mutating parent artifact with `preflightStatus=ready-for-elevated-operator`, two child runbooks present, two hashes verified, zero mismatches, zero missing artifacts, eleven failed sealed service checks, zero missing checks, explicit aftercare audits, and `privateStateExposed=false`. The remaining scar is still explicit elevated operator execution followed by complete Idunn audits, not missing parent/child artifact readiness. - 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: The local wrapper mouth now forwards Rust-owned Gjallar repo-work map sight for `gjallar` and `swarm-triage`. Live wrapper proofs `local-20260621-004816-315-24fe14d4` and `local-20260621-004815-947-b647d7a9` printed `repoWorkMapRows`, `repoWorkSemanticRows`, family/path/branch/stage/gate lens rows, `repoWorkOverviewRows`, and `repoWorkPublicProofRows` in the one-line operator summary while `privateStateExposed=false`; the current live store had no accepted repo-work rows, so the fields rendered `none`. PowerShell only lowers existing Rust TUI arrays and does not reinterpret repo-work truth or gain scheduler, publication, merge, deployment, daemon lifecycle, or Mind-admission authority. + last_completed_repo_swarm_cut: Soul closure now emits a typed safe-family planning readback for `repo.planning_brief` work instead of only a generic family-assertions pass bit. The packet `epiphany.repo_work_safe_family_planning_readback.v0` carries candidate next safe-family rows, candidate count, planning requirement flags, Mind/Self/Substrate/Hands/Soul/Bifrost/Idunn gate flags, authority-denial flags, and the private-state seal while granting no Hands, scheduling, publication, deployment, or state-admission authority. Focused proof `.epiphany-smoke\repo-planning-brief-family-20260620-235939` ran init -> online -> accept -> derive-plan -> tick run/adopt/execute/close and passed with `candidateNextSafeFamilyCount=6`, `allExpectedCandidateFamiliesPresent=true`, `allPlanningRequirementsPresent=true`, `allRequiredGatesPresent=true`, `authorityDenied=true`, and `privateStateExposed=false`. next_action: Continue repo-swarm MVP work from the documented Epiphany Online cut order in `notes/epiphany-repo-swarm-mvp-contract.md`. Typed Gjallar repo-work history/queue sight, peer-readable Persona Eve lowering, Self-owned `epiphany-work queue-run`, bounded `epiphany-swarm run`, execute-to-close scheduler handoff through `close-from-execute`, deterministic `derive-plan` families `append-worklog`, `planning-note`, `checklist-note`, `section-note` / `repo.markdown_managed_section`, `task-card` / `repo.task_card`, `repo-status-section` / `repo.status_section`, `repo-manifest` / `repo.body_manifest`, `repo-tool-capabilities` / `repo.tool_capabilities`, `repo-tool-request` / `repo.tool_request`, `repo-eve-surface` / `repo.eve_surface`, `repo-collaboration-policy` / `repo.collaboration_policy`, `repo-collaboration-topic` / `repo.collaboration_topic`, `repo-consensus-brief` / `repo.consensus_brief`, `repo-planning-brief` / `repo.planning_brief`, `repo-objective-draft` / `repo.objective_draft`, `repo-adoption-request` / `repo.adoption_request`, `repo-scheduling-request` / `repo.scheduling_request`, `repo-work-order` / `repo.work_order`, `repo-verification-request` / `repo.verification_request`, `repo-publication-request` / `repo.publication_request`, `repo-sync-request` / `repo.sync_request`, `repo-maintainer-review-request` / `repo.maintainer_review_request`, `repo-pr-request` / `repo.pr_request`, `repo-credit-request` / `repo.credit_request`, `repo-artifact-acceptance-request` / `repo.artifact_acceptance_request`, `repo-metrics-request` / `repo.metrics_request`, `repo.doctrine_update_request`, `repo.secret_policy_request`, `repo.deployment_config`, and `repo.deployment_request`, typed Imagination action-item receipts over allowlisted safe families, `epiphany.repo_work_mind_interpretation.v0` plus `epiphany.repo_work_mind_adoption_decision.v0` Mind interpreter receipts, explicit safe-family allowlist refusal, explicit requested-path/plan-changed-path mismatch refusal, explicit missing verification/evidence-needs refusal, Soul closure's Mind-adoption proof guard, explicit verification-output source-grounding closure guard, durable repo-work map admission before branch-local Hands consequences reach publication gates, local Verse `epiphany.cultmesh.repo_work_map_entry.v0` Gjallar readback for Mind-admitted map facts, hash-backed local proof bundles with Bifrost/GitHub/credit/PR/upstream-main publication rows, redacted `epiphany-work export-proof` public bundles plus local Verse `epiphany.cultmesh.repo_work_public_proof.v0` Gjallar readback, Bifrost-owned `gamecult.bifrost.public_proof_publication_receipt.v0` closure plus wrapper `bifrost-public-proof` for redacted public proofs, Idunn-hosted non-mutating queue-run lifecycle plan/runbook receipts including native proof `.epiphany-smoke\repo-work-service-lifecycle-20260620-185853`, deployment config/audit/runbook/aftercare CultMesh-ref ingestion plus Gjallar Idunn receipt discovery proof `.epiphany-smoke\repo-deployment-config-family-20260620-223203`, and the speech-audited `epiphany-work persona-intake` mouth plus wrapper `repo-persona-intake` are live with `privateStateExposed=false`; proofs `.epiphany-smoke\fresh-repo-mvp-20260620-180024`, `.epiphany-smoke\swarm-stop-classification-20260620-184717`, `.epiphany-smoke\repo-planning-brief-family-20260620-231539`, `.epiphany-smoke\repo-mind-safe-family-guard-20260620-194425`, `.epiphany-smoke\repo-mind-path-guard-20260620-194239`, `.epiphany-smoke\repo-mind-evidence-guard-20260620-224426`, `.epiphany-smoke\repo-planning-facets-20260620-224428`, `.epiphany-smoke\repo-closure-source-grounding-20260620-230626`, `.epiphany-smoke\repo-doctrine-update-request-family-20260620-192140`, `.epiphany-smoke\repo-secret-policy-request-family-20260620-193046`, `.epiphany-smoke\repo-deployment-config-family-20260620-223203`, `.epiphany-smoke\repo-deployment-request-family-20260620-195605`, `.epiphany-smoke\repo-close-mind-adoption-guard-20260620-201153`, `.epiphany-smoke\repo-close-mind-adoption-guard-20260620-202113`, and `.epiphany-smoke\repo-close-mind-adoption-guard-20260620-203717` show fresh-repo iteration-limit stop classification, empty-queue Gjallar classification, dry-run planning-preview Self classification, family-friendly Imagination safe-family decomposition cargo, Bifrost publication-gate classification, Bifrost/GitHub upstream-sync gate classification, Mind refusal for unsupported safe-family cargo, mismatched requested paths, and missing verification/evidence needs, Soul refusal for proofless verification output under required source grounding, reviewed doctrine/security/deployment config/request cargo, deployment-config audit readiness for Idunn review, deployment execution runbook readiness for explicit operator git-push handoff, deployment aftercare receipt ingestion from local Verse/CultMesh refs, Gjallar Idunn deployment/aftercare receipt rows, closure refusal for counterfeit Mind adoption, durable repo-map admission only after passing closure, local Verse/Gjallar map projection, closure, publication receipts, upstream-main sync, public-proof export, and private-state sealing. The contract note now explicitly answers that Epiphany is headed toward a functional repo swarm but is not fully online until the typed artery runs as a living repo organism. The next cut is deeper interpreter/closure depth or repo-work semantic map readback; Idunn deployment receipt refs are now visible through Gjallar/Odin sight without opening private state. Preserve Idunn service lifecycle ownership and existing CultMesh/Odin/Eve tool directories; service install/start/deployment execution still requires explicit elevated operator authority.