From 3e29458aa84443ae2920e22d5ad2efd2e529efb3 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sun, 12 Jul 2026 12:32:56 +0100 Subject: [PATCH] Project reviewed Modeling launch authority --- epiphany-core/src/bin/epiphany-work.rs | 156 ++++++++++++++++++++++ notes/epiphany-current-algorithmic-map.md | 9 ++ notes/fresh-workspace-handoff.md | 11 ++ state/ledgers.msgpack | Bin 422997 -> 423324 bytes state/map.yaml | 2 +- 5 files changed, 177 insertions(+), 1 deletion(-) diff --git a/epiphany-core/src/bin/epiphany-work.rs b/epiphany-core/src/bin/epiphany-work.rs index 861441c2..b219fd08 100644 --- a/epiphany-core/src/bin/epiphany-work.rs +++ b/epiphany-core/src/bin/epiphany-work.rs @@ -15075,6 +15075,17 @@ fn run_tick(args: TickArgs) -> Result { status = "would-advance".to_string(); reason = "typed Modeling request is ready for the existing worker runtime" .to_string(); + advanced_result = json!({ + "schemaVersion": "epiphany.repo_work_modeling_launch_projection.v0", + "status": "launch-ready", + "routeId": route.route_id, + "generation": route.generation, + "requestId": request.request_id, + "jobId": job_id, + "preflightRequired": true, + "lifecycleOwner": "Idunn", + "privateStateExposed": false + }); next_safe_move = "Rerun without --dry-run to launch the repo-work Modeling worker." .to_string(); @@ -17273,6 +17284,151 @@ mod authority_tests { assert!(advance_repo_work_modeling_route(&store, &request1, &route1, &review).is_err()); Ok(()) } + + #[test] + fn public_revision_mouth_routes_scheduler_to_generation_one() -> Result<()> { + let temp = tempfile::tempdir()?; + let workspace = temp.path().join("repo"); + fs::create_dir_all(&workspace)?; + let git = Command::new("git") + .arg("init") + .arg("--quiet") + .arg(&workspace) + .status()?; + assert!(git.success()); + let artifact_dir = workspace.join(".epiphany").join("work"); + fs::create_dir_all(&artifact_dir)?; + let store = workspace.join("runtime.msgpack"); + initialize_runtime_spine( + &store, + RuntimeSpineInitOptions { + runtime_id: "process-retry-smoke".to_string(), + display_name: "Process Retry Smoke".to_string(), + created_at: "2026-07-12T00:00:00Z".to_string(), + }, + )?; + let soul = SoulVerdictReceipt { + schema_version: SOUL_VERDICT_RECEIPT_SCHEMA_VERSION.to_string(), + receipt_id: "process-retry-soul".to_string(), + source_result_id: "process-retry-result".to_string(), + source_job_id: "process-retry-job".to_string(), + verdict: "passed".to_string(), + summary: "Verified consequence.".to_string(), + evidence_ids: vec!["commit-abc".to_string()], + risks: Vec::new(), + emitted_at: "2026-07-12T00:00:00Z".to_string(), + contract: "test".to_string(), + }; + put_soul_verdict_receipt(&store, &soul)?; + let request0 = RepoWorkModelingRequest { + schema_version: REPO_WORK_MODELING_REQUEST_SCHEMA_VERSION.to_string(), + request_id: "repo-work-close-process-retry-modeling-request-g0".to_string(), + item: "process-retry".to_string(), + requester: "self".to_string(), + soul_verdict_receipt_id: soul.receipt_id.clone(), + commit_sha: "abc123".to_string(), + changed_paths: vec!["README.md".to_string()], + instruction: "Model generation zero.".to_string(), + requested_at: "2026-07-12T00:00:01Z".to_string(), + private_state_exposed: false, + contract: "test".to_string(), + }; + let route0 = RepoWorkModelingRoute { + schema_version: REPO_WORK_MODELING_ROUTE_SCHEMA_VERSION.to_string(), + route_id: "repo-work-modeling-route-process-retry".to_string(), + item: request0.item.clone(), + generation: 0, + request_id: request0.request_id.clone(), + previous_finding_receipt_id: String::new(), + authority_owner: "soul".to_string(), + authority_witness_id: soul.receipt_id.clone(), + updated_at: "2026-07-12T00:00:01Z".to_string(), + private_state_exposed: false, + contract: "test".to_string(), + }; + commit_initial_repo_work_modeling_route(&store, &request0, &route0)?; + let finding0 = RepoWorkModelingFinding { + schema_version: REPO_WORK_MODELING_FINDING_SCHEMA_VERSION.to_string(), + receipt_id: format!("{}-finding", request0.request_id), + item: request0.item.clone(), + model_ref: "runtime-generation-zero".to_string(), + soul_verdict_receipt_id: soul.receipt_id.clone(), + verdict: "needs-work".to_string(), + finding: "Reviewed context is required.".to_string(), + summary: "Generation zero incomplete.".to_string(), + changed_paths: request0.changed_paths.clone(), + commit_sha: request0.commit_sha.clone(), + emitted_at: "2026-07-12T00:00:02Z".to_string(), + private_state_exposed: false, + contract: "test".to_string(), + request_id: request0.request_id.clone(), + }; + put_repo_work_modeling_finding(&store, &finding0)?; + write_json( + &artifact_dir.join("work-accept-process-retry.json"), + &json!({ + "schemaVersion": "epiphany.repo_work_accept.v0", + "status": "accepted", + "item": "process-retry", + "privateStateExposed": false + }), + )?; + write_json( + &artifact_dir.join("work-close-process-retry.json"), + &json!({ + "schemaVersion": "epiphany.repo_work_closure_receipt.v0", + "status": "awaiting-modeling", + "item": "process-retry", + "runtimeStore": store, + "privateStateExposed": false + }), + )?; + + let revised = run_revise_modeling(ReviseModelingArgs { + workspace: workspace.clone(), + item: "process-retry".to_string(), + runtime_store: Some(store.clone()), + rationale: "The operator reviewed the missing context.".to_string(), + review_ref: "review://process-retry/g1".to_string(), + })?; + assert_eq!(revised["generation"], 1); + assert_eq!( + revised["requestId"], + "repo-work-close-process-retry-modeling-request-g1" + ); + + let tick = run_tick(TickArgs { + workspace: workspace.clone(), + epiphany_root: env::current_dir()?, + item: Some("process-retry".to_string()), + local_verse_store: None, + artifact_dir: Some(artifact_dir), + runtime_store: Some(store.clone()), + cooldown_seconds: 0, + active_timeout_seconds: 900, + dry_run: true, + })?; + let tick_receipt = read_json(Path::new(tick["receiptPath"].as_str().unwrap()))?; + assert_eq!(tick_receipt["action"], "launch-modeling"); + assert_eq!(tick_receipt["advancedResult"]["generation"], 1); + assert_eq!( + tick_receipt["advancedResult"]["requestId"], + "repo-work-close-process-retry-modeling-request-g1" + ); + assert_eq!( + tick_receipt["advancedResult"]["jobId"], + "repo-work-modeling-process-retry-g1" + ); + assert_eq!(tick_receipt["advancedResult"]["preflightRequired"], true); + assert_eq!(tick_receipt["advancedResult"]["lifecycleOwner"], "Idunn"); + assert_eq!( + runtime_repo_work_modeling_route(&store, &route0.route_id)? + .expect("current route") + .generation, + 1 + ); + Ok(()) + } } fn adopted_action_item_from_plan(plan: &Value) -> Value { diff --git a/notes/epiphany-current-algorithmic-map.md b/notes/epiphany-current-algorithmic-map.md index 5b8a729a..7876554b 100644 --- a/notes/epiphany-current-algorithmic-map.md +++ b/notes/epiphany-current-algorithmic-map.md @@ -305,6 +305,15 @@ handoff and ownership without provider/network variance. The remaining smoke boundary is process composition through `epiphany-work revise-modeling`, the scheduler's consumer preflight, and Idunn's child lifecycle receipt. +Scheduler dry-run is now an authority projection rather than a vague promise. +When a current typed Modeling request has no finding or job, its +`advancedResult` names the current route, generation, request, generation-bound +job id, required preflight, and Idunn lifecycle ownership without opening a job +or spawning a process. A disposable authority test drives the production +revision mouth and scheduler and proves generation one is selected. The final +process proof must compare this projection with a real preflighted Idunn launch +receipt; it must not add a fake production runtime mode. + ## Current Cut Line Keep: diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index aff2c41a..ae6b91a6 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -2150,6 +2150,17 @@ What remains is process composition, not another state abstraction: drive this same chain through the public `revise-modeling` command and scheduler so the generation-one launch carries a passing consumer preflight into an Idunn-owned lifecycle receipt. +The public-command/scheduler selection half is now deterministic too. +`public_revision_mouth_routes_scheduler_to_generation_one` builds a disposable +repo and runtime store, invokes the production `run_revise_modeling` mouth over +a non-passing generation-zero finding, then pulses the production scheduler in +dry-run mode. The scheduler's launch projection now names route id, generation, +request id, generation-scoped job id, `preflightRequired=true`, and +`lifecycleOwner=Idunn`; the proof requires generation one throughout and the +typed route remains on generation one. The remaining proof is deliberately +physical: run the same fixture non-dry with built consumer/supervisor binaries +and verify the Idunn lifecycle receipt carries the projected request plus +passing schema preflight fingerprints. ## Immediate Re-entry Instruction diff --git a/state/ledgers.msgpack b/state/ledgers.msgpack index ba875291c59b98c5cc9c2329a54f6cf8c72ad321..ef71a1d30fdbda2d53f656dd1d419d76075cfc02 100644 GIT binary patch delta 317 zcmYk0Jx;?w5QVWZ76Q@ZG>nusTi8L0l!}59Ix4!&?qIL9*|qn_AxJ0%1t+lFa0n0u z4Fwf9-~e<;h&!nD5q&7O~=!)Y-;on3$Kq;CB>j+!X?d+6fFE{=kR zxf_%O?Y(tz`qA_k-|_yzjO4{tp3kR6|FTI&n-viVO5F1&yh)L1`wu|^~=y( P8@!RCtXzNpo}Byx0MT*D delta 57 zcmbR9TJq`($qf>W+(wpG28L0`7}$!9HY+n0GBUntp32ldm5C9EK{PWEvj8#c_Nh#4 G2MPf(91@lQ diff --git a/state/map.yaml b/state/map.yaml index 645ec374..b73148d5 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -659,4 +659,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`. Gjallar 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: Add the process-composition half of the native generation-one repo-work Modeling smoke. Reuse the now-proven deterministic runtime generation chain, but exercise the public Mind-reviewed revise-modeling mouth and scheduler launch so generation one carries a passing consumer schema preflight into an Idunn-owned lifecycle receipt; verify the receipt selects the generation-one request and preserve the existing canonical proof that generation zero cannot close or regain authority. + next_action: Run and seal the physical half of the native generation-one repo-work Modeling smoke. The deterministic public revise-modeling and scheduler projection now prove route/request/job selection for generation one. Pulse the same disposable fixture non-dry with built consumer and supervisor binaries, verify the Idunn lifecycle receipt carries generation one's request plus passing executable/schema fingerprints, then compare it to the dry-run projection without adding a fake production runtime mode.