Separate Unity resolution from operability
This commit is contained in:
parent
53e5246896
commit
b2edd1f276
6 changed files with 33 additions and 19 deletions
|
|
@ -50,7 +50,7 @@ fn run_smoke() -> Result<Value> {
|
|||
require_artifact(&missing, "unity-bridge-inspection.md")?;
|
||||
|
||||
let exact_editor = create_fake_editor(&fake_roots, PROJECT_VERSION)?;
|
||||
let ready = run_bridge(
|
||||
let resolved = run_bridge(
|
||||
&root,
|
||||
&workspace,
|
||||
&artifact_root,
|
||||
|
|
@ -59,15 +59,15 @@ fn run_smoke() -> Result<Value> {
|
|||
true,
|
||||
)?;
|
||||
require(
|
||||
ready["status"] == "ready",
|
||||
"exact editor should satisfy pin",
|
||||
resolved["status"] == "resolved",
|
||||
"exact editor path should resolve the pin",
|
||||
)?;
|
||||
require(
|
||||
ready["editorPath"] == exact_editor.to_string_lossy().as_ref(),
|
||||
resolved["editorPath"] == exact_editor.to_string_lossy().as_ref(),
|
||||
"inspection should resolve exact editor",
|
||||
)?;
|
||||
require(
|
||||
ready
|
||||
resolved
|
||||
.pointer("/editorBridge/exists")
|
||||
.and_then(Value::as_bool)
|
||||
== Some(false),
|
||||
|
|
@ -89,7 +89,7 @@ fn run_smoke() -> Result<Value> {
|
|||
true,
|
||||
)?;
|
||||
require(
|
||||
planned["status"] == "ready",
|
||||
planned["status"] == "resolved",
|
||||
"dry run should still require exact editor",
|
||||
)?;
|
||||
require(
|
||||
|
|
@ -148,7 +148,7 @@ fn run_smoke() -> Result<Value> {
|
|||
true,
|
||||
)?;
|
||||
require(
|
||||
bridged["status"] == "ready",
|
||||
bridged["status"] == "resolved",
|
||||
"bridge project should still resolve exact editor",
|
||||
)?;
|
||||
require(
|
||||
|
|
@ -287,13 +287,13 @@ fn run_smoke() -> Result<Value> {
|
|||
"workspace": workspace,
|
||||
"artifactRoot": artifact_root,
|
||||
"missingStatus": missing["status"],
|
||||
"readyStatus": ready["status"],
|
||||
"editorResolutionStatus": resolved["status"],
|
||||
"plannedStatus": planned["runStatus"],
|
||||
"missingPackageStatus": missing_package["status"],
|
||||
"sceneProbeStatus": scene_probe["runStatus"],
|
||||
"testStatus": tests["runStatus"],
|
||||
"blockedStatus": blocked["runStatus"],
|
||||
"resolvedEditor": ready["editorPath"],
|
||||
"resolvedEditor": resolved["editorPath"],
|
||||
});
|
||||
write_json(&result_path, &result)?;
|
||||
Ok(result)
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ fn read_unity_project_version(project_path: &Path) -> serde_json::Value {
|
|||
.as_str()
|
||||
.is_some_and(|value| !value.is_empty())
|
||||
{
|
||||
result["status"] = json!("ready");
|
||||
result["status"] = json!("pinned");
|
||||
} else {
|
||||
result["status"] = json!("missingProjectVersion");
|
||||
result["note"] = json!("ProjectVersion.txt did not contain m_EditorVersion.");
|
||||
|
|
@ -364,7 +364,7 @@ fn resolve_unity_editor(project_path: &Path) -> Result<serde_json::Value> {
|
|||
.collect::<Vec<_>>()
|
||||
);
|
||||
if let Some(exact) = exact {
|
||||
result["status"] = json!("ready");
|
||||
result["status"] = json!("resolved");
|
||||
result["editorPath"] = json!(path_string(exact));
|
||||
result["note"] = json!(format!(
|
||||
"Project pins Unity {project_version}; exact editor resolved at {}.",
|
||||
|
|
@ -481,7 +481,7 @@ fn build_unity_command(
|
|||
Ok(command)
|
||||
}
|
||||
|
||||
fn editor_bridge_ready(summary: &serde_json::Value) -> bool {
|
||||
fn editor_bridge_present(summary: &serde_json::Value) -> bool {
|
||||
summary["editorBridge"]["exists"].as_bool() == Some(true)
|
||||
}
|
||||
|
||||
|
|
@ -619,7 +619,7 @@ fn run_unity(options: &UnityOptions) -> Result<serde_json::Value> {
|
|||
summary["operation"] = json!("run");
|
||||
summary["label"] = json!(options.label);
|
||||
summary["unityArgs"] = json!(options.unity_args);
|
||||
if summary["status"].as_str() != Some("ready") {
|
||||
if summary["status"].as_str() != Some("resolved") {
|
||||
summary["runStatus"] = json!("blocked");
|
||||
summary["note"] = json!(format!(
|
||||
"{} Runtime execution refused; install the exact pinned editor or use inspect artifacts as evidence of the missing runtime.",
|
||||
|
|
@ -701,7 +701,7 @@ fn run_named_probe(options: &UnityOptions, operation: &str) -> Result<serde_json
|
|||
"description": probe_description(operation),
|
||||
"expectedArtifacts": expected_artifacts(operation),
|
||||
});
|
||||
if summary["status"].as_str() != Some("ready") {
|
||||
if summary["status"].as_str() != Some("resolved") {
|
||||
summary["runStatus"] = json!("blocked");
|
||||
summary["note"] = json!(format!(
|
||||
"{} Runtime/editor probe refused; install the exact pinned editor or use inspect artifacts as evidence of the missing runtime.",
|
||||
|
|
@ -710,7 +710,7 @@ fn run_named_probe(options: &UnityOptions, operation: &str) -> Result<serde_json
|
|||
write_inspection_artifacts(&directory, &summary)?;
|
||||
return Ok(summary);
|
||||
}
|
||||
if !editor_bridge_ready(&summary) {
|
||||
if !editor_bridge_present(&summary) {
|
||||
let bridge_path = summary["editorBridge"]["path"]
|
||||
.as_str()
|
||||
.map(ToOwned::to_owned)
|
||||
|
|
@ -785,7 +785,7 @@ fn test_unity(options: &UnityOptions) -> Result<serde_json::Value> {
|
|||
summary["operation"] = json!("run-tests");
|
||||
summary["testPlatform"] = json!(options.platform);
|
||||
summary["testFilter"] = json!(options.filter);
|
||||
if summary["status"].as_str() != Some("ready") {
|
||||
if summary["status"].as_str() != Some("resolved") {
|
||||
summary["runStatus"] = json!("blocked");
|
||||
summary["note"] = json!(format!(
|
||||
"{} Unity tests refused; install the exact pinned editor or use inspect artifacts as evidence of the missing runtime.",
|
||||
|
|
@ -935,8 +935,8 @@ fn bridge_guidance(project_path: &Path) -> Result<String> {
|
|||
"`epiphany-unity-bridge inspect --project-path {}`",
|
||||
project_path.display()
|
||||
);
|
||||
if summary["status"].as_str() == Some("ready") {
|
||||
if editor_bridge_ready(&summary) {
|
||||
if summary["status"].as_str() == Some("resolved") {
|
||||
if editor_bridge_present(&summary) {
|
||||
Ok(format!(
|
||||
"- Unity bridge: project pins {} and the exact editor resolved to `{}`. If Unity execution is needed, use named bridge operations such as `epiphany-unity-bridge probe --project-path {} --operation scene-facts --scene <Assets/...unity>` or `epiphany-unity-bridge check-compilation --project-path {}`. The bridge owns -batchmode, -quit, -projectPath, -logFile, -executeMethod, and artifacts. Do not invoke `Unity`, `Unity.exe`, default installs, or PATH-resolved editors directly, and do not refactor Unity-owned scene/prefab state as raw text when the editor bridge can inspect it.",
|
||||
summary["projectVersion"].as_str().unwrap_or("unknown"),
|
||||
|
|
|
|||
|
|
@ -1487,3 +1487,12 @@ The Rider bridge called a discovered executable path, solution file, and Git
|
|||
branch `ready` without executing or validating any of them. These projections
|
||||
now report `discovered`, `found`, and `gitDetected`. Discovery owns topology;
|
||||
only an actual launch receipt may later claim operability.
|
||||
|
||||
## Editor resolution is not editor operability
|
||||
|
||||
Unity inspection called a parsed project version and an existing exact-editor
|
||||
path `ready`; its smoke proved that state with a fake text file named as the
|
||||
editor executable. The project version is now `pinned`, the editor path is
|
||||
`resolved`, and editor-bridge package existence is explicitly `present`.
|
||||
Commands may use resolution to choose what to execute, but only `runStatus`
|
||||
records planned, completed, failed, or blocked execution consequence.
|
||||
|
|
|
|||
|
|
@ -568,3 +568,8 @@ binary tests, and the all-bin check pass.
|
|||
Rider bridge topology no longer claims readiness from path existence. Rider is
|
||||
`discovered`, solutions are `found`, and repository topology is `gitDetected`;
|
||||
the native bridge smoke passes with the renamed evidence states.
|
||||
|
||||
Unity bridge uses the same boundary: project version parsing is `pinned`, exact
|
||||
editor path discovery is `resolved`, and the editor package predicate is named
|
||||
`present`. Operability belongs to the subsequent `runStatus` receipt. The
|
||||
native Unity bridge smoke, 259 library tests, and all-bin check pass.
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -660,4 +660,4 @@ current_status:
|
|||
- Service lifecycle receipt history is now event-only: `load_epiphany_cultmesh_daemon_service_lifecycle_receipts` filters out the `epiphany-local/daemon-service-lifecycle-receipt/latest` mirror, while `load_latest_epiphany_cultmesh_daemon_service_lifecycle_receipt` remains the latest-state reader. Focused unit test `service_lifecycle_receipt_history_excludes_latest_mirror` proves two per-receipt writes return exactly two history records and latest points at the second. Fresh smoke `verse-query-lifecycle-history-filter-smoke` and live overview/triage `local-20260618-145632-497-efac6f0d` / `local-20260618-145632-321-867947af` prove compact swarm sights still expose service lifecycle attention plus the present elevated runbook artifact without daemon pokes or service mutation. Do not use a broad unscoped cargo test filter for this check on Windows; it fans out across bin harnesses and hit a broken pipe during this pass.
|
||||
- `epiphany-verse-query seed-compact` is the compact seed receipt for wrappers and read-only rites. The older `seed` command still prints the full local Verse context for explicit debugging, but compact wrapper modes now avoid full `seed`/final `query` readback after the combined overview proof exposed Windows debug stack overflow from full-context serialization pressure.
|
||||
last_completed_repo_swarm_cut: Huginn live-fire has crossed the first real repo Body from Persona pressure to branch-local Hands commit and Soul/Mind closure, and now has repeatable closure and redacted-public-proof mouths. On `E:\Projects\Huginn` branch `epiphany/huginn/first-awakening`, `tools/epiphany_local_run.ps1 -Mode repo-persona-intake` accepted item `huginn-inspection-readback-livefire`, Weksa/Persona intake remained sealed, and `epiphany-work derive-plan` lowered it to model-authored safe family `repo.status_section` for `README.md` only. `tools/epiphany_local_run.ps1 -Mode repo-swarm-run` advanced four bounded pulses: run-from-plan, adopt-from-plan, execute-from-plan, and close-from-execute. Huginn commit `e9b07c38fceabbdc89ea35c2156326c80c0393a2` updated only `README.md`; closure receipt `.epiphany\work\work-close-huginn-inspection-readback-livefire.json` records status `closed`, Soul verdict `passed`, Mind state commit `repo-work-close-huginn-inspection-readback-livefire-mind-commit`, safe family `repo.status_section`, path scope `README.md`, Bifrost publication gate, and `privateStateExposed=false`. Verification also ran Huginn's TypeScript compiler through concrete Node path: `C:\Program Files\nodejs\node.exe E:\Projects\Huginn\node_modules\typescript\bin\tsc -p tsconfig.json` passed. Native verifier `epiphany-repo-livefire-closure-smoke --workspace E:\Projects\Huginn --item huginn-inspection-readback-livefire --expected-path README.md --expected-family repo.status_section --expected-gate awaiting-publication --expected-blocker bifrost-publication-missing` checks closure receipt, Mind map entry, overview gate/blocker, authority seals, and `git show` changed paths, returning `status=ok`, `soulVerdict=passed`, `publicationGate=Bifrost`, and `privateStateExposed=false`. Wrapper `tools/epiphany_local_run.ps1 -Mode repo-livefire-closure -Workspace E:\Projects\Huginn -RepoWorkItem huginn-inspection-readback-livefire -SkipBuild` exposes the same read-only proof through the local operator mouth; artifact `local-20260621-190156-803-2f85ba15` printed commit, path, gate, blocker, Soul verdict, Mind commit receipt, and `privateStateExposed=False` without push, merge, publication, or target mutation. New wrapper `tools/epiphany_local_run.ps1 -Mode repo-work-public-proof -Workspace E:\Projects\Huginn -RepoWorkItem huginn-inspection-readback-livefire -SkipBuild` exports the redacted proof bundle and repo-local Verse index without publishing; artifact `local-20260621-190645-345-4555b1dc` wrote `.epiphany\public\proof-bundles\repo-work-public-proof-huginn-inspection-readback-livefire.json`, proof id `repo-work-public-proof-huginn-inspection-readback-livefire`, SHA-256 `857545b199f3e37eb06c2e757e5cfc201958e46667bb1f8403fd333a22620f63`, nine artifact rows, zero publication rows, and `privateStateExposed=False`. swarm overview readback `local-20260621-190701-140-b9519ec6` sees the `REPO-WORK-PUBLIC-PROOF` row and action row from Huginn's repo-local Verse with the same SHA-256 while Bifrost publication remains missing. Launcher compact modes are now named compact operator-context modes instead of read-only modes, and `bifrost-public-proof` summaries print item, target public Verse, room, proof SHA-256, review receipts, and credit receipts so publication receipts are auditable without claiming upstream sync.
|
||||
next_action: Continue the observation-to-consequence audit. Heartbeat, operator-cache, and Rider topology projections no longer turn presence into readiness; Rider paths are discovered, solutions found, and Git topology detected. Next inspect provider-capability and editor-bridge projections for discovery or configuration standing in for verified operability. Keep closure's zero-substring invariant.
|
||||
next_action: Continue the observation-to-consequence audit. Heartbeat, operator-cache, Rider, and Unity projections no longer turn presence, parsing, or path resolution into readiness; Unity operability belongs to `runStatus`. Next inspect provider-capability/configuration projections and Persona bridge mouths for credentials or advertised surfaces standing in for verified transport. Keep closure's zero-substring invariant.
|
||||
|
|
|
|||
Reference in a new issue