Make service command identity own execution intent
This commit is contained in:
parent
2a797370f6
commit
b03ab6265f
7 changed files with 175 additions and 124 deletions
|
|
@ -3,27 +3,14 @@ use anyhow::Result;
|
|||
use chrono::DateTime;
|
||||
use chrono::Duration;
|
||||
use chrono::Utc;
|
||||
use epiphany_core::EPIPHANY_CULTMESH_DAEMON_RESTART_POLICY_SCHEMA_VERSION;
|
||||
use epiphany_core::EPIPHANY_CULTMESH_DAEMON_SCHEDULER_RECEIPT_SCHEMA_VERSION;
|
||||
use epiphany_core::EPIPHANY_CULTMESH_DAEMON_SERVICE_LIFECYCLE_RECEIPT_SCHEMA_VERSION;
|
||||
use epiphany_core::EPIPHANY_CULTMESH_MANAGED_SERVICE_POLICY_SCHEMA_VERSION;
|
||||
use epiphany_core::EpiphanyCultMeshDaemonRestartPolicyEntry;
|
||||
use epiphany_core::EpiphanyCultMeshDaemonSchedulerReceiptEntry;
|
||||
use epiphany_core::EpiphanyCultMeshDaemonServiceLifecycleReceiptEntry;
|
||||
use epiphany_core::EpiphanyCultMeshManagedServicePolicyEntry;
|
||||
use epiphany_core::EpiphanyCultMeshSwarmBrakeEntry;
|
||||
use epiphany_core::EpiphanyCultMeshDaemonStatusEntry;
|
||||
use epiphany_core::EpiphanyLocalVerseContext;
|
||||
use epiphany_core::EpiphanyProcessObservation as ProcessObservation;
|
||||
use epiphany_core::EpiphanyServiceExecutionAuditReport;
|
||||
use epiphany_core::epiphany_cluster_service_execution_audit_report;
|
||||
use epiphany_core::epiphany_cultmesh_daemon_poke_intent_from_status;
|
||||
use epiphany_core::epiphany_cultmesh_daemon_poke_receipt_for_intent;
|
||||
use epiphany_core::epiphany_service_execution_audit_report;
|
||||
use epiphany_core::load_epiphany_cultmesh_daemon_restart_policy;
|
||||
use epiphany_core::load_epiphany_cultmesh_daemon_service_lifecycle_receipts;
|
||||
use epiphany_core::load_epiphany_cultmesh_managed_service_policy;
|
||||
use epiphany_core::load_epiphany_cultmesh_managed_service_policies;
|
||||
use epiphany_core::load_epiphany_cultmesh_managed_service_policy;
|
||||
use epiphany_core::load_epiphany_cultmesh_swarm_brake;
|
||||
use epiphany_core::observe_native_process as observe_process;
|
||||
use epiphany_core::query_epiphany_local_verse_context;
|
||||
|
|
@ -33,10 +20,23 @@ use epiphany_core::write_epiphany_cultmesh_daemon_poke_receipt;
|
|||
use epiphany_core::write_epiphany_cultmesh_daemon_restart_policy;
|
||||
use epiphany_core::write_epiphany_cultmesh_daemon_scheduler_receipt;
|
||||
use epiphany_core::write_epiphany_cultmesh_daemon_service_lifecycle_receipt;
|
||||
use epiphany_core::write_epiphany_cultmesh_managed_service_policy;
|
||||
use epiphany_core::write_epiphany_cultmesh_daemon_status;
|
||||
use serde_json::Value;
|
||||
use epiphany_core::write_epiphany_cultmesh_managed_service_policy;
|
||||
use epiphany_core::EpiphanyCultMeshDaemonRestartPolicyEntry;
|
||||
use epiphany_core::EpiphanyCultMeshDaemonSchedulerReceiptEntry;
|
||||
use epiphany_core::EpiphanyCultMeshDaemonServiceLifecycleReceiptEntry;
|
||||
use epiphany_core::EpiphanyCultMeshDaemonStatusEntry;
|
||||
use epiphany_core::EpiphanyCultMeshManagedServicePolicyEntry;
|
||||
use epiphany_core::EpiphanyCultMeshSwarmBrakeEntry;
|
||||
use epiphany_core::EpiphanyLocalVerseContext;
|
||||
use epiphany_core::EpiphanyProcessObservation as ProcessObservation;
|
||||
use epiphany_core::EpiphanyServiceExecutionAuditReport;
|
||||
use epiphany_core::EPIPHANY_CULTMESH_DAEMON_RESTART_POLICY_SCHEMA_VERSION;
|
||||
use epiphany_core::EPIPHANY_CULTMESH_DAEMON_SCHEDULER_RECEIPT_SCHEMA_VERSION;
|
||||
use epiphany_core::EPIPHANY_CULTMESH_DAEMON_SERVICE_LIFECYCLE_RECEIPT_SCHEMA_VERSION;
|
||||
use epiphany_core::EPIPHANY_CULTMESH_MANAGED_SERVICE_POLICY_SCHEMA_VERSION;
|
||||
use serde_json::json;
|
||||
use serde_json::Value;
|
||||
use sha2::Digest;
|
||||
use sha2::Sha256;
|
||||
use std::env;
|
||||
|
|
@ -55,7 +55,7 @@ fn main() -> Result<()> {
|
|||
"tick" | "schedule" | "reconcile-all" => tick(args),
|
||||
"serve" | "loop" | "daemon" => serve(args),
|
||||
"managed-service-serve" | "service-desired-state-serve" => managed_service_serve(args),
|
||||
"service-plan" | "install-service" => service_plan(args),
|
||||
"service-plan" => service_plan(args),
|
||||
"service-launch" | "launch-service" | "start-service" => service_launch(args),
|
||||
"managed-service-policy" | "service-desired-state" => managed_service_policy(args),
|
||||
"managed-service-read" | "service-desired-state-read" => managed_service_read(args),
|
||||
|
|
@ -67,10 +67,16 @@ fn main() -> Result<()> {
|
|||
| "repo-work-service-readiness"
|
||||
| "repo-work-queue-runner-audit" => repo_work_service_audit(args),
|
||||
"cluster-service-runbook" | "cluster-daemon-runbook" => cluster_daemon_runbook(args),
|
||||
"cluster-windows-service-install"
|
||||
| "cluster-service-install-plan"
|
||||
| "cluster-service-install-execute"
|
||||
| "cluster-daemon-install-plan" => cluster_windows_service_install(args),
|
||||
"cluster-service-install-plan" | "cluster-daemon-install-plan" => {
|
||||
let mut args = args;
|
||||
args.execute_install = false;
|
||||
cluster_windows_service_install(args)
|
||||
}
|
||||
"cluster-service-install-execute" => {
|
||||
let mut args = args;
|
||||
args.execute_install = true;
|
||||
cluster_windows_service_install(args)
|
||||
}
|
||||
"cluster-windows-service-audit" | "cluster-service-audit" | "cluster-service-readiness" => {
|
||||
cluster_windows_service_audit(args)
|
||||
}
|
||||
|
|
@ -93,7 +99,14 @@ fn main() -> Result<()> {
|
|||
| "cluster-service-execution-audit-smoke" => {
|
||||
cluster_windows_service_execution_audit_smoke(args)
|
||||
}
|
||||
"windows-service-install" | "service-install-windows" | "service-install-plan" => {
|
||||
"service-install-plan" => {
|
||||
let mut args = args;
|
||||
args.execute_install = false;
|
||||
windows_service_install(args)
|
||||
}
|
||||
"service-install-execute" => {
|
||||
let mut args = args;
|
||||
args.execute_install = true;
|
||||
windows_service_install(args)
|
||||
}
|
||||
"windows-service-execution-readiness"
|
||||
|
|
@ -192,23 +205,24 @@ fn managed_service_serve(args: Args) -> Result<()> {
|
|||
let mut iteration = 0_u64;
|
||||
loop {
|
||||
iteration = iteration.saturating_add(1);
|
||||
let policies = load_epiphany_cultmesh_managed_service_policies(
|
||||
&args.store,
|
||||
args.runtime_id.clone(),
|
||||
)?;
|
||||
let policies =
|
||||
load_epiphany_cultmesh_managed_service_policies(&args.store, args.runtime_id.clone())?;
|
||||
for policy in &policies {
|
||||
let mut service_args = args.clone();
|
||||
service_args.service_id = policy.service_id.clone();
|
||||
managed_service_reconcile(service_args)?;
|
||||
}
|
||||
println!("{}", serde_json::to_string_pretty(&json!({
|
||||
"schemaVersion": "epiphany.cultmesh.managed_service_scheduler_pulse.v0",
|
||||
"status": "completed",
|
||||
"owner": "Idunn",
|
||||
"iteration": iteration,
|
||||
"policyCount": policies.len(),
|
||||
"privateStateExposed": false,
|
||||
}))?);
|
||||
println!(
|
||||
"{}",
|
||||
serde_json::to_string_pretty(&json!({
|
||||
"schemaVersion": "epiphany.cultmesh.managed_service_scheduler_pulse.v0",
|
||||
"status": "completed",
|
||||
"owner": "Idunn",
|
||||
"iteration": iteration,
|
||||
"policyCount": policies.len(),
|
||||
"privateStateExposed": false,
|
||||
}))?
|
||||
);
|
||||
if args.max_iterations != 0 && iteration >= args.max_iterations {
|
||||
break;
|
||||
}
|
||||
|
|
@ -374,10 +388,16 @@ fn managed_service_policy(args: Args) -> Result<()> {
|
|||
)?;
|
||||
let command = service_command_path(&args)?;
|
||||
let stdout_artifact = args.stdout_artifact.clone().unwrap_or_else(|| {
|
||||
PathBuf::from(format!(".epiphany-run/services/{}.stdout.log", args.service_id))
|
||||
PathBuf::from(format!(
|
||||
".epiphany-run/services/{}.stdout.log",
|
||||
args.service_id
|
||||
))
|
||||
});
|
||||
let stderr_artifact = args.stderr_artifact.clone().unwrap_or_else(|| {
|
||||
PathBuf::from(format!(".epiphany-run/services/{}.stderr.log", args.service_id))
|
||||
PathBuf::from(format!(
|
||||
".epiphany-run/services/{}.stderr.log",
|
||||
args.service_id
|
||||
))
|
||||
});
|
||||
let latest = load_epiphany_cultmesh_daemon_service_lifecycle_receipts(
|
||||
&args.store,
|
||||
|
|
@ -417,21 +437,24 @@ fn managed_service_policy(args: Args) -> Result<()> {
|
|||
args.runtime_id.clone(),
|
||||
policy,
|
||||
)?;
|
||||
println!("{}", serde_json::to_string_pretty(&json!({
|
||||
"schemaVersion": written.schema_version,
|
||||
"status": "written",
|
||||
"policyId": written.policy_id,
|
||||
"serviceId": written.service_id,
|
||||
"ownerDaemonId": written.owner_daemon_id,
|
||||
"enabled": written.enabled,
|
||||
"restartMode": written.restart_mode,
|
||||
"command": written.command,
|
||||
"args": written.args,
|
||||
"stdoutArtifact": written.stdout_artifact,
|
||||
"stderrArtifact": written.stderr_artifact,
|
||||
"latestLifecycleReceiptId": latest.as_ref().map(|receipt| receipt.receipt_id.as_str()),
|
||||
"privateStateExposed": written.private_state_exposed,
|
||||
}))?);
|
||||
println!(
|
||||
"{}",
|
||||
serde_json::to_string_pretty(&json!({
|
||||
"schemaVersion": written.schema_version,
|
||||
"status": "written",
|
||||
"policyId": written.policy_id,
|
||||
"serviceId": written.service_id,
|
||||
"ownerDaemonId": written.owner_daemon_id,
|
||||
"enabled": written.enabled,
|
||||
"restartMode": written.restart_mode,
|
||||
"command": written.command,
|
||||
"args": written.args,
|
||||
"stdoutArtifact": written.stdout_artifact,
|
||||
"stderrArtifact": written.stderr_artifact,
|
||||
"latestLifecycleReceiptId": latest.as_ref().map(|receipt| receipt.receipt_id.as_str()),
|
||||
"privateStateExposed": written.private_state_exposed,
|
||||
}))?
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -455,31 +478,34 @@ fn managed_service_read(args: Args) -> Result<()> {
|
|||
.map(observe_process)
|
||||
.transpose()?
|
||||
.unwrap_or(ProcessObservation::Missing);
|
||||
println!("{}", serde_json::to_string_pretty(&json!({
|
||||
"schemaVersion": "epiphany.cultmesh.managed_service_readback.v0",
|
||||
"status": "desired-state-ready",
|
||||
"serviceId": policy.service_id,
|
||||
"ownerDaemonId": policy.owner_daemon_id,
|
||||
"desired": {
|
||||
"enabled": policy.enabled,
|
||||
"restartMode": policy.restart_mode,
|
||||
"command": policy.command,
|
||||
"args": policy.args,
|
||||
"cwd": policy.cwd,
|
||||
"stdoutArtifact": policy.stdout_artifact,
|
||||
"stderrArtifact": policy.stderr_artifact,
|
||||
},
|
||||
"latestLifecycle": latest.as_ref().map(|receipt| json!({
|
||||
"receiptId": receipt.receipt_id,
|
||||
"status": receipt.status,
|
||||
"action": receipt.action,
|
||||
"processId": receipt.process_id,
|
||||
"startedAtUtc": receipt.started_at_utc,
|
||||
"completedAtUtc": receipt.completed_at_utc,
|
||||
})),
|
||||
"processObservation": process_observation.label(),
|
||||
"privateStateExposed": false,
|
||||
}))?);
|
||||
println!(
|
||||
"{}",
|
||||
serde_json::to_string_pretty(&json!({
|
||||
"schemaVersion": "epiphany.cultmesh.managed_service_readback.v0",
|
||||
"status": "desired-state-ready",
|
||||
"serviceId": policy.service_id,
|
||||
"ownerDaemonId": policy.owner_daemon_id,
|
||||
"desired": {
|
||||
"enabled": policy.enabled,
|
||||
"restartMode": policy.restart_mode,
|
||||
"command": policy.command,
|
||||
"args": policy.args,
|
||||
"cwd": policy.cwd,
|
||||
"stdoutArtifact": policy.stdout_artifact,
|
||||
"stderrArtifact": policy.stderr_artifact,
|
||||
},
|
||||
"latestLifecycle": latest.as_ref().map(|receipt| json!({
|
||||
"receiptId": receipt.receipt_id,
|
||||
"status": receipt.status,
|
||||
"action": receipt.action,
|
||||
"processId": receipt.process_id,
|
||||
"startedAtUtc": receipt.started_at_utc,
|
||||
"completedAtUtc": receipt.completed_at_utc,
|
||||
})),
|
||||
"processObservation": process_observation.label(),
|
||||
"privateStateExposed": false,
|
||||
}))?
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -504,26 +530,32 @@ fn managed_service_reconcile(mut args: Args) -> Result<()> {
|
|||
.transpose()?
|
||||
.unwrap_or(ProcessObservation::Missing);
|
||||
if !policy.enabled || policy.restart_mode == "never" {
|
||||
println!("{}", serde_json::to_string_pretty(&json!({
|
||||
"schemaVersion": "epiphany.cultmesh.managed_service_reconcile.v0",
|
||||
"status": "disabled",
|
||||
"serviceId": policy.service_id,
|
||||
"processObservation": observation.label(),
|
||||
"restarted": false,
|
||||
"privateStateExposed": false,
|
||||
}))?);
|
||||
println!(
|
||||
"{}",
|
||||
serde_json::to_string_pretty(&json!({
|
||||
"schemaVersion": "epiphany.cultmesh.managed_service_reconcile.v0",
|
||||
"status": "disabled",
|
||||
"serviceId": policy.service_id,
|
||||
"processObservation": observation.label(),
|
||||
"restarted": false,
|
||||
"privateStateExposed": false,
|
||||
}))?
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
if observation == ProcessObservation::Alive {
|
||||
println!("{}", serde_json::to_string_pretty(&json!({
|
||||
"schemaVersion": "epiphany.cultmesh.managed_service_reconcile.v0",
|
||||
"status": "observed-alive",
|
||||
"serviceId": policy.service_id,
|
||||
"processId": latest.as_ref().and_then(|receipt| receipt.process_id),
|
||||
"processObservation": observation.label(),
|
||||
"restarted": false,
|
||||
"privateStateExposed": false,
|
||||
}))?);
|
||||
println!(
|
||||
"{}",
|
||||
serde_json::to_string_pretty(&json!({
|
||||
"schemaVersion": "epiphany.cultmesh.managed_service_reconcile.v0",
|
||||
"status": "observed-alive",
|
||||
"serviceId": policy.service_id,
|
||||
"processId": latest.as_ref().and_then(|receipt| receipt.process_id),
|
||||
"processObservation": observation.label(),
|
||||
"restarted": false,
|
||||
"privateStateExposed": false,
|
||||
}))?
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
if policy.restart_mode == "on-failure"
|
||||
|
|
@ -531,14 +563,17 @@ fn managed_service_reconcile(mut args: Args) -> Result<()> {
|
|||
receipt.status == "completed" && receipt.exit_code.unwrap_or_default() == 0
|
||||
})
|
||||
{
|
||||
println!("{}", serde_json::to_string_pretty(&json!({
|
||||
"schemaVersion": "epiphany.cultmesh.managed_service_reconcile.v0",
|
||||
"status": "completed-no-restart",
|
||||
"serviceId": policy.service_id,
|
||||
"processObservation": observation.label(),
|
||||
"restarted": false,
|
||||
"privateStateExposed": false,
|
||||
}))?);
|
||||
println!(
|
||||
"{}",
|
||||
serde_json::to_string_pretty(&json!({
|
||||
"schemaVersion": "epiphany.cultmesh.managed_service_reconcile.v0",
|
||||
"status": "completed-no-restart",
|
||||
"serviceId": policy.service_id,
|
||||
"processObservation": observation.label(),
|
||||
"restarted": false,
|
||||
"privateStateExposed": false,
|
||||
}))?
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
if !args.force && policy.cooldown_seconds > 0 {
|
||||
|
|
@ -548,16 +583,19 @@ fn managed_service_reconcile(mut args: Args) -> Result<()> {
|
|||
{
|
||||
let elapsed = Utc::now().signed_duration_since(started.with_timezone(&Utc));
|
||||
if elapsed < Duration::seconds(policy.cooldown_seconds) {
|
||||
println!("{}", serde_json::to_string_pretty(&json!({
|
||||
"schemaVersion": "epiphany.cultmesh.managed_service_reconcile.v0",
|
||||
"status": "cooling-down",
|
||||
"serviceId": policy.service_id,
|
||||
"processObservation": observation.label(),
|
||||
"cooldownSeconds": policy.cooldown_seconds,
|
||||
"elapsedSeconds": elapsed.num_seconds(),
|
||||
"restarted": false,
|
||||
"privateStateExposed": false,
|
||||
}))?);
|
||||
println!(
|
||||
"{}",
|
||||
serde_json::to_string_pretty(&json!({
|
||||
"schemaVersion": "epiphany.cultmesh.managed_service_reconcile.v0",
|
||||
"status": "cooling-down",
|
||||
"serviceId": policy.service_id,
|
||||
"processObservation": observation.label(),
|
||||
"cooldownSeconds": policy.cooldown_seconds,
|
||||
"elapsedSeconds": elapsed.num_seconds(),
|
||||
"restarted": false,
|
||||
"privateStateExposed": false,
|
||||
}))?
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
|
@ -3265,7 +3303,8 @@ fn service_lifecycle_receipt(
|
|||
let receipt_id = args.receipt_id.clone().unwrap_or_else(|| {
|
||||
let base = format!(
|
||||
"daemon-service-lifecycle-receipt-{}-{}",
|
||||
sanitize_id(&args.service_id), sanitize_id(action)
|
||||
sanitize_id(&args.service_id),
|
||||
sanitize_id(action)
|
||||
);
|
||||
if action == "launch" {
|
||||
format!("{base}-{}", started_at.timestamp_millis())
|
||||
|
|
|
|||
|
|
@ -93,6 +93,14 @@
|
|||
- Receipt status is derived as `completed`; callers cannot submit status.
|
||||
- Forbidden evidence: missing, non-JSON, pre-intent, out-of-root, or mismatched-run artifacts.
|
||||
|
||||
## Daemon-supervisor install authority boundary (2026-07-12)
|
||||
|
||||
- Plan commands force non-execution and may only write planned artifacts/receipts.
|
||||
- Execute commands force execution intent and must pass the existing elevation gate before service-manager mutation.
|
||||
- Wrapper command identity matches the Rust command exactly; no hidden `--execute-install` switch selects reality.
|
||||
- Ambiguous install aliases are not accepted.
|
||||
- Negative proof: hostile plan flag cannot mutate; execute without elevation produces an explicit refusal receipt.
|
||||
|
||||
This is the source-grounded map of the live machine. Historical route and
|
||||
bridge anatomy belongs in git history and evidence ledgers, not here.
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@ The monolithic `epiphany-verse-query smoke` fixture writer can no longer accept
|
|||
|
||||
`epiphany-operator-run receipt` no longer accepts `--status`. It loads the latest operator intent and requires matching run id/mode, canonicalizes the result and artifact-root paths, requires the result to be a file contained under the artifact root, parses it as JSON, and rejects it if its modification time predates the intent. Only then does it derive `status=completed`. The wrapper no longer passes a completion assertion. Negative proof rejects caller status and out-of-root artifacts; positive proof uses a post-intent JSON artifact. Next audit daemon-supervisor planning/rehearsal receipts against actual service/process evidence.
|
||||
|
||||
## 2026-07-12 daemon-supervisor plan/execute identity
|
||||
|
||||
Install command names now determine execution authority. `service-install-plan` and `cluster-service-install-plan` force `execute_install=false` even if a hostile flag is supplied. `service-install-execute` and `cluster-service-install-execute` force `execute_install=true` without a separate flag. Ambiguous aliases were deleted, and the wrapper invokes exact command names instead of always invoking plan plus `--execute-install`. Proof in the non-elevated shell: hostile plan remained `planned` / `executed=false`; execute without a flag returned `execution-refused-not-elevated` / `executed=false`. Receipt status now follows an inspectable command boundary rather than hidden argument combination.
|
||||
|
||||
This is the re-entry rite for `E:\Projects\EpiphanyAgent`: the waking chant for
|
||||
the local machine-spirit before it touches the forge.
|
||||
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@ A forged operator-status artifact containing `intentId=forged-intent`, `receiptI
|
|||
|
||||
## Remaining scrutiny
|
||||
|
||||
1. Inspect daemon-supervisor plan/rehearsal receipts separately from execution receipts so planning cannot masquerade as service mutation.
|
||||
2. Extend the same store quarantine invariant to standalone smoke binaries that accept output paths.
|
||||
3. Distill or remove dead public receipt constructors once every named provider executable exists.
|
||||
1. Extend the same store quarantine invariant to standalone smoke binaries that accept output paths.
|
||||
2. Distill or remove dead public receipt constructors once every named provider executable exists.
|
||||
3. Distill obsolete historical authority claims in `state/map.yaml`.
|
||||
|
||||
## Smoke quarantine update
|
||||
|
||||
|
|
@ -30,3 +30,9 @@ A forged operator-status artifact containing `intentId=forged-intent`, `receiptI
|
|||
## Operator-run evidence binding update
|
||||
|
||||
The standalone `receipt` command previously accepted caller status and path strings, then wrote `completed` evidence without inspecting the run. It now requires the latest persisted intent to match run id and mode, derives status internally as `completed`, requires an existing valid JSON result contained by the canonical artifact root, and requires the result modification time to be no earlier than the intent request time. `--status` no longer exists. The PowerShell orchestrator supplies only the result coordinates after its checked subprocess completes.
|
||||
|
||||
## Daemon-supervisor command authority update
|
||||
|
||||
Lifecycle receipt status values already distinguished planned, refused, observed, and executed outcomes, but install command aliases allowed command names and the `--execute-install` flag to disagree. Dispatch now makes command identity authoritative: `service-install-plan` and `cluster-service-install-plan` forcibly disable execution; `service-install-execute` and `cluster-service-install-execute` force execution intent and reach the elevation gate without a side-channel flag. Ambiguous `install-service`, `windows-service-install`, `service-install-windows`, and `cluster-windows-service-install` aliases are removed. The wrapper invokes the exact plan/execute command and no longer appends `--execute-install`.
|
||||
|
||||
Negative proof passed both directions: a plan command given hostile `--execute-install` remained `planned` with `executed=false`; an execute command without the flag reached `execution-refused-not-elevated` with `executed=false` in the non-elevated shell.
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -70,7 +70,7 @@ data_flow:
|
|||
- move historical proof to git, commits, smoke artifacts, or distilled evidence rather than plan prose
|
||||
|
||||
active_subgoals:
|
||||
- Use `notes/conceptual-substitution-audit-2026-07-12.md` plus `notes/receipt-writer-provenance-audit-2026-07-12.md` as the current authority-corrosion maps. Operator-snapshot promotion is cut; verse-query smoke is quarantined. Operator-run completion now binds to a matching persisted intent and a fresh valid JSON result contained under the canonical artifact root; callers cannot supply completion status. Next audit daemon-supervisor plan/rehearsal versus execution provenance, then extend quarantine to standalone smoke binaries.
|
||||
- Use `notes/conceptual-substitution-audit-2026-07-12.md` plus `notes/receipt-writer-provenance-audit-2026-07-12.md` as the current authority-corrosion maps. Snapshot promotion, synthetic smoke escape, and unbound operator completion are cut. Daemon-supervisor install command identity now owns plan versus execute intent; plan forcibly cannot mutate, execute always reaches the elevation gate, ambiguous aliases and side-channel wrapper flags are removed. Next quarantine standalone smoke binaries, remove dead public receipt constructors where providers are missing, and distill obsolete historical authority claims.
|
||||
- `swarm-overview` is an Epiphany-local, renderer-neutral diagnostic projection over provider-owned typed state. It owns no lifecycle, discovery, composition, or mutation authority. Epiphany publishes clean provider-owned Eve surfaces; Odin may discover them; downstream lowerers and compositors remain outside Epiphany's concern.
|
||||
- Idunn owns daemon survival and service lifecycle physiology. Codex/operator sessions may inspect, generate runbooks, and route explicit operator authority, but keeping daemons alive belongs to Idunn-owned service lifecycle receipts, scheduler policy, audits, and aftercare. Do not let Self, diagnostic projections, or ad hoc wrapper summaries become a second daemon-keeper. Global tool readbacks for Self `service-health`, `service-policy-directory`, and `swarm-online-runbook` state `lifecycleOwner=Idunn` and `hostedBody=Epiphany` without service mutation or private-state exposure.
|
||||
- Use `notes/epiphany-cultmesh-dreaming-roadmap.md` as the design authority for distributed Epiphany dreaming. Public dreams are separately authored typed documents distributed through CultMesh/CultNet; private state remains local and cannot be shared by flipping a visibility flag. Foreign dreams are external thought weather until a reviewed local adoption receipt digests them into memory, planning, doctrine, or governance.
|
||||
|
|
|
|||
|
|
@ -1592,7 +1592,7 @@ if ($Mode -eq "cluster-service-install-plan" -or $Mode -eq "cluster-service-inst
|
|||
$clusterServiceId = "epiphany-cluster-daemon-services"
|
||||
}
|
||||
$installArgs = @(
|
||||
"cluster-service-install-plan",
|
||||
"cluster-service-install-$clusterInstallModeName",
|
||||
"--store", $localVerseStore,
|
||||
"--runtime-id", $LocalVerseRuntimeId,
|
||||
"--daemon-id", $DaemonId,
|
||||
|
|
@ -1612,9 +1612,6 @@ if ($Mode -eq "cluster-service-install-plan" -or $Mode -eq "cluster-service-inst
|
|||
if ($ServiceMaxIterations -gt 0) {
|
||||
$installArgs += @("--max-iterations", "$ServiceMaxIterations")
|
||||
}
|
||||
if ($Mode -eq "cluster-service-install-execute") {
|
||||
$installArgs += @("--execute-install")
|
||||
}
|
||||
Invoke-Checked `
|
||||
-Label "write cluster daemon Windows service install $clusterInstallModeName" `
|
||||
-FilePath $daemonSupervisorExe `
|
||||
|
|
@ -1982,7 +1979,7 @@ if ($Mode -eq "service-install-plan" -or $Mode -eq "service-install-execute") {
|
|||
$resultPath = Join-Path $artifactRoot "daemon-service-install-$installModeName.stdout.json"
|
||||
$installScriptPath = Join-Path $artifactRoot "epiphany-daemon-supervisor-install.ps1"
|
||||
$installArgs = @(
|
||||
"windows-service-install",
|
||||
"service-install-$installModeName",
|
||||
"--store", $localVerseStore,
|
||||
"--runtime-id", $LocalVerseRuntimeId,
|
||||
"--daemon-id", $DaemonId,
|
||||
|
|
@ -2001,9 +1998,6 @@ if ($Mode -eq "service-install-plan" -or $Mode -eq "service-install-execute") {
|
|||
if ($ServiceMaxIterations -gt 0) {
|
||||
$installArgs += @("--max-iterations", "$ServiceMaxIterations")
|
||||
}
|
||||
if ($Mode -eq "service-install-execute") {
|
||||
$installArgs += @("--execute-install")
|
||||
}
|
||||
Invoke-Checked `
|
||||
-Label "write daemon supervisor Windows service install $installModeName" `
|
||||
-FilePath $daemonSupervisorExe `
|
||||
|
|
|
|||
Reference in a new issue