Expose Idunn ownership in service policy rows
This commit is contained in:
parent
81362ca33d
commit
f3197ad1f7
5 changed files with 24 additions and 4 deletions
|
|
@ -135,6 +135,8 @@ const WRAPPER_CLUSTER_SERVICE_STOP_EXECUTE_COMMAND: &str =
|
|||
"tools/epiphany_local_run.ps1 -Mode cluster-service-stop-execute";
|
||||
const DIRECT_BIFROST_PUBLICATION_COMMAND: &str =
|
||||
"epiphany-verse-query bifrost-publication --target-repository <repo> --changed-path <path>";
|
||||
const SERVICE_LIFECYCLE_OWNER: &str = "Idunn";
|
||||
const SERVICE_LIFECYCLE_HOSTED_BODY: &str = "Epiphany";
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let args = Args::parse()?;
|
||||
|
|
@ -238,6 +240,8 @@ fn main() -> Result<()> {
|
|||
"status": report.status,
|
||||
"store": args.store,
|
||||
"runtimeId": args.runtime_id,
|
||||
"lifecycleOwner": report.lifecycle_owner,
|
||||
"hostedBody": report.hosted_body,
|
||||
"daemonCount": report.rows.len(),
|
||||
"coveredCount": report.covered_count,
|
||||
"enabledCount": report.enabled_count,
|
||||
|
|
@ -1632,6 +1636,8 @@ fn main() -> Result<()> {
|
|||
.any(|row| {
|
||||
row.contains("MISSING")
|
||||
&& row.contains("Persona")
|
||||
&& row.contains("owner=Idunn")
|
||||
&& row.contains("hostedBody=Epiphany")
|
||||
&& row.contains("followUp=epiphany-daemon-supervisor policy --daemon-id <daemon> --restart-command <exe>")
|
||||
&& row.contains("private=false")
|
||||
})
|
||||
|
|
@ -1685,6 +1691,8 @@ fn main() -> Result<()> {
|
|||
|| !disabled_policy_report.tui_rows.iter().any(|row| {
|
||||
row.contains("DISABLED")
|
||||
&& row.contains("Persona")
|
||||
&& row.contains("owner=Idunn")
|
||||
&& row.contains("hostedBody=Epiphany")
|
||||
&& row.contains("last=never-attempted")
|
||||
&& row.contains("followUp=epiphany-daemon-supervisor policy --daemon-id <daemon> --restart-command <exe>")
|
||||
&& row.contains("private=false")
|
||||
|
|
@ -2843,6 +2851,8 @@ fn main() -> Result<()> {
|
|||
};
|
||||
let ready_policy_report = DaemonRestartPolicyDirectoryReport {
|
||||
status: "ok".to_string(),
|
||||
lifecycle_owner: SERVICE_LIFECYCLE_OWNER.to_string(),
|
||||
hosted_body: SERVICE_LIFECYCLE_HOSTED_BODY.to_string(),
|
||||
rows: Vec::new(),
|
||||
tui_rows: Vec::new(),
|
||||
covered_count: 0,
|
||||
|
|
@ -3232,6 +3242,8 @@ struct DaemonToolDirectoryReport {
|
|||
|
||||
struct DaemonRestartPolicyDirectoryReport {
|
||||
status: String,
|
||||
lifecycle_owner: String,
|
||||
hosted_body: String,
|
||||
rows: Vec<DaemonRestartPolicyDirectoryRow>,
|
||||
tui_rows: Vec<String>,
|
||||
covered_count: usize,
|
||||
|
|
@ -3247,6 +3259,8 @@ struct DaemonRestartPolicyDirectoryReport {
|
|||
struct DaemonRestartPolicyDirectoryRow {
|
||||
cluster_id: String,
|
||||
display_name: String,
|
||||
lifecycle_owner: String,
|
||||
hosted_body: String,
|
||||
daemon_id: String,
|
||||
daemon_status: String,
|
||||
policy_id: String,
|
||||
|
|
@ -4243,7 +4257,9 @@ fn daemon_restart_policy_directory_report_from_rows(
|
|||
_ => "MISSING",
|
||||
};
|
||||
tui_rows.push(format!(
|
||||
"{compact_status} | {display_name} | {} | daemon={} | policy={} | cooldown={}s | reconcile={}s | stale={}s | failures={} | last={} | followUp={} | private={}",
|
||||
"{compact_status} | {display_name} | owner={} | hostedBody={} | {} | daemon={} | policy={} | cooldown={}s | reconcile={}s | stale={}s | failures={} | last={} | followUp={} | private={}",
|
||||
SERVICE_LIFECYCLE_OWNER,
|
||||
SERVICE_LIFECYCLE_HOSTED_BODY,
|
||||
status.daemon_id,
|
||||
status.status,
|
||||
policy_id,
|
||||
|
|
@ -4258,6 +4274,8 @@ fn daemon_restart_policy_directory_report_from_rows(
|
|||
rows.push(DaemonRestartPolicyDirectoryRow {
|
||||
cluster_id: status.cluster_id.clone(),
|
||||
display_name,
|
||||
lifecycle_owner: SERVICE_LIFECYCLE_OWNER.to_string(),
|
||||
hosted_body: SERVICE_LIFECYCLE_HOSTED_BODY.to_string(),
|
||||
daemon_id: status.daemon_id.clone(),
|
||||
daemon_status: status.status.clone(),
|
||||
policy_id,
|
||||
|
|
@ -4284,6 +4302,8 @@ fn daemon_restart_policy_directory_report_from_rows(
|
|||
|
||||
DaemonRestartPolicyDirectoryReport {
|
||||
status,
|
||||
lifecycle_owner: SERVICE_LIFECYCLE_OWNER.to_string(),
|
||||
hosted_body: SERVICE_LIFECYCLE_HOSTED_BODY.to_string(),
|
||||
rows,
|
||||
tui_rows,
|
||||
covered_count,
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ remembers doctrine; the branch remembers the blade.
|
|||
- `tools/epiphany_local_run.ps1 -Mode service-tick` is now the first-class local wrapper for one daemon-supervisor scheduler pulse. It runs through operator run intent/receipt, agent-state SoA refresh, local Verse brake preflight, and `epiphany-daemon-supervisor tick`, while restart authority remains in durable per-daemon policies. Proof seeded one disabled Persona policy as inert metadata, then wrapper artifact `local-20260618-075902-006-e2915574` wrote scheduler receipt `daemon-scheduler-receipt-epiphany-daemon-supervisor-0` with `tickComplete`, `outcomeCount=1`, `skippedCount=1`, `restartedCount=0`, `refusedCount=0`, and `privateStateExposed=false`.
|
||||
- `epiphany-cluster-daemon` is the first real per-cluster daemon heartbeat body. It runs as a narrow Rust binary parameterized by daemon id, publishes typed `epiphany.cultmesh.daemon_status.v0` heartbeats into `.epiphany-run\cultmesh\local-verse.ccmp`, can run once or loop, and exposes no private state. Durable restart policies for Self, Hands, Persona, Imagination, Eyes, Modeling, and Soul now invoke `epiphany-cluster-daemon heartbeat`, not the generic `epiphany-verse-query daemon-status` debug writer. A degraded proof via `service-tick` showed the supervisor invoking all seven daemon bodies and restoring ready liveness with sealed receipts; follow-up service tick no-ops when heartbeats are fresh. `epiphany-daemon-supervisor cluster-service-runbook` and `tools/epiphany_local_run.ps1 -Mode cluster-service-runbook` write a non-mutating service runbook plus `daemon_service_lifecycle` receipt for all seven organ daemon `epiphany-cluster-daemon serve` commands. `epiphany-daemon-supervisor cluster-service-install-plan` and `tools/epiphany_local_run.ps1 -Mode cluster-service-install-plan` write a non-mutating Windows install script plus lifecycle receipt for seven distinct per-organ Windows services. `tools/epiphany_local_run.ps1 -Mode cluster-service-install-execute` requests execution through the same typed path and, in non-elevated shells, writes `execution-refused-not-elevated` with `executed=false` instead of mutating services. `epiphany-daemon-supervisor cluster-service-audit` and wrapper `-Mode cluster-service-audit` read Windows service-manager state for those seven expected service names; current local proof reports seven missing services and `status=incomplete`. `epiphany-daemon-supervisor cluster-service-start`/`cluster-service-stop` and wrapper modes `cluster-service-start-plan`, `cluster-service-stop-plan`, `cluster-service-start-execute`, and `cluster-service-stop-execute` record lifecycle receipts for all seven expected services; plan modes emit seven planned rows, and execute modes refuse without elevation before mutation. The cluster install/audit/control wrapper summaries now print compact `serviceRows` for all seven daemon-owned Windows service names with daemon id, status or observed status, cluster id, executed flag, exit code, start type, and `private=false`; live proofs `local-20260618-211051-126-2a89d61c`, `local-20260618-211051-125-cd687ee2`, `local-20260618-211051-063-f0ff980d`, and `local-20260618-211118-108-df5cb8cd` show the missing audit, ready/demand install-plan, start-planned, and stop-planned row shapes without service mutation. `cluster-service-execution-runbook` writes the admin-gated elevated wrapper sequence starting with cluster-native readiness, then uses `Invoke-EpiphanyRunbookStep` so each install/start/audit/stop step resets `$LASTEXITCODE`, catches thrown/nonzero failures, keeps running to gather more lifecycle receipts, and always runs `cluster-service-execution-audit` from `finally`; the wrapper asks `epiphany-daemon-supervisor cluster-service-execution-runbook` to seal the generated artifact as a typed `daemon_service_lifecycle` receipt with action `cluster-windows-service-execution-runbook`, status `written`, final audit metadata, step-failure policy metadata, and `privateStateExposed=false`. Its JSON and typed receipt args expose `runbookTryModes`, `finalAuditMode`, `finalAuditRunsInFinally=true`, `stepFailurePolicy=continue-after-step-failure`, `continueAfterStepFailure=true`, `nonzeroExitFailsStep=true`, and `exitsNonzeroAfterFinalAudit=true`, and the compact operator line prints those same aftercare facts. Latest proof `local-20260618-161632-376-436227d8` generated and parsed the robust cluster artifact. Cluster execution audit now requires that runbook witness before considering the elevated readiness/install/start/audit/stop effect chain. Current live audit remains correctly `incomplete` until an elevated operator run produces successful effect receipts. `tools/epiphany_local_run.ps1` builds and requires `epiphany-cluster-daemon` for service modes.
|
||||
- `tools/epiphany_local_run.ps1 -Mode cluster-service-execution-readiness` now prints compact `serviceRows` too. The readiness payload has identity-only per-service rows, so the wrapper uses the global readiness verdict as the default row status; proof `local-20260618-211524-363-5d85b3aa` showed seven `not-elevated` rows with service/daemon/cluster identity and `private=false`. Stop execution refusal remains row-visible as well: proof `local-20260618-211524-345-d580da5c` printed seven `execution-refused-not-elevated` rows without mutating Windows services.
|
||||
- `epiphany-verse-query restart-policy-directory` and `tools/epiphany_local_run.ps1 -Mode service-policy-directory` are the compact scheduler coverage sight rite. They report each daemon's durable restart-policy coverage as `ENABLED`, `DISABLED`, or `MISSING` through a narrow CultMesh restart-policy directory loader without writing policies or commands. Compact rows now include cooldown, reconcile interval, heartbeat stale threshold, failure count, last result, `followUp=<command>`, and `private=false`; the wrapper summary prints Rust-owned `tuiRows` for all seven policy rows with the `service-tick` follow-up instead of rebuilding policy text in PowerShell. Disabled policies count as recovery attention, not harmless coverage. Live wrapper artifact `local-20260618-213147-804-7dec3346` returned `status=ok`, seven daemons, seven covered policies, seven enabled policies, zero disabled, zero missing, zero attention rows, `last=ready`, `cooldown=30s`, `reconcile=60s`, `stale=300s`, `followUp=tools/epiphany_local_run.ps1 -Mode service-tick`, and `privateStateExposed=false`. This is real daemon heartbeat coverage, not yet an installed per-organ OS service.
|
||||
- `epiphany-verse-query restart-policy-directory` and `tools/epiphany_local_run.ps1 -Mode service-policy-directory` are the compact scheduler coverage sight rite. They report each daemon's durable restart-policy coverage as `ENABLED`, `DISABLED`, or `MISSING` through a narrow CultMesh restart-policy directory loader without writing policies or commands. Compact rows now include Idunn lifecycle ownership, Epiphany hosted-body identity, cooldown, reconcile interval, heartbeat stale threshold, failure count, last result, `followUp=<command>`, and `private=false`; the wrapper summary prints Rust-owned `tuiRows` for all seven policy rows with the `service-tick` follow-up instead of rebuilding policy text in PowerShell. Disabled policies count as recovery attention, not harmless coverage. Live wrapper artifact `local-20260619-003720-135-799146f3` returned `status=ok`, `owner=Idunn`, `hostedBody=Epiphany`, seven daemons, seven covered policies, seven enabled policies, zero disabled, zero missing, zero attention rows, `last=ready`, `cooldown=30s`, `reconcile=60s`, `stale=300s`, `followUp=tools/epiphany_local_run.ps1 -Mode service-tick`, and `privateStateExposed=false`. This is real Idunn-owned daemon heartbeat coverage, not yet an installed per-organ OS service.
|
||||
- `epiphany-verse-query poke-down-daemons` and `tools/epiphany_local_run.ps1 -Mode swarm-poke-down` are the current typed "if a service is down, poke it" reflex. They inspect local Verse daemon status rows, write daemon poke intent/receipt documents for every non-ready daemon, respect the same `daemon.lifecycle_poke` swarm brake as single-daemon poke, include target display name/body domain/private Verse id/Eve surface metadata from cluster topology in the operator-safe poke summary, and expose no private state. Compact poke rows now print target, daemon id, observed status, body domain, private Verse, Eve surface, intent id, receipt id/status, resulting status, and `private=false`. Verified: live artifact `local-20260618-180548-293-ff73f9de` temporarily degraded Hands and printed one topology-aware compact poke row; live artifact `local-20260618-180618-002-06e77583` then proved the restored swarm had seven ready daemons and zero non-ready rows; a temp lifecycle brake refused the batch poke; and `epiphany-verse-query smoke` source-proves the ready no-op plus degraded single-poke compact row path.
|
||||
- CultMesh now carries the CultCache SoA ergonomic instead of forcing callers to bypass the mesh node. `CultMeshNode::soa<T>()` returns typed SoA tables for registered documents; the CultMesh crate proves the generic path, and Epiphany's agent-state summary test proves local Verse can project sealed `epiphany.cultmesh.agent_state_soa_summary.v0` rows through SoA columns. The seven-row persisted agent-state SoA remains owned by the agent memory store and mirrored into local Verse only as a private-state-sealed summary. `epiphany-verse-query agent-state-report` and `tools/epiphany_local_run.ps1 -Mode agent-state-soa` now expose that mirrored summary as compact TUI/JSON rows from CultMesh SoA columns without full local Verse serialization; compact rows include role id, agent id, profile kind, portable contract, memory/goal/value counts, and `private=false`. Live wrapper proof `local-20260618-175913-074-b22ff01c` returned `agents=7`, `summaryRows=2`, printed all seven faculties in `agentRows`, and kept `privateStateExposed=False`.
|
||||
- `epiphany-verse-query swarm-status` and `tools/epiphany_local_run.ps1 -Mode swarm-status` are the compact read-only liveness surface for the daemon swarm. They use a narrow CultMesh daemon-liveness loader instead of serializing the full local Verse context, return agent-friendly `READY`/`POKE` TUI rows with daemon id, body domain, private Verse id, Eve surface, `followUp=tools/epiphany_local_run.ps1 -Mode swarm-poke-down`, and `private=false`, and expose no private state. Verified: live wrapper artifact `local-20260618-210235-584-110d1120` saw seven ready daemons and printed the Rust-owned rows in `statusRows`; a temp degraded Hands report returns `attention`, `nonReadyCount=1`, and a `POKE` row with `privateVerse=epiphany.cluster.hands.private`; `epiphany-verse-query smoke` source-proves ready and degraded report paths.
|
||||
|
|
|
|||
Binary file not shown.
File diff suppressed because one or more lines are too long
|
|
@ -2070,7 +2070,7 @@ if ($resultPath -ne "" -and (Test-Path -LiteralPath $resultPath)) {
|
|||
if ($null -ne $result.tuiRows -and $result.tuiRows.Count -gt 0) {
|
||||
$policyRows = Format-TuiRows $result.tuiRows
|
||||
}
|
||||
Write-Host "Service policy directory: status=$($result.status), daemons=$($result.daemonCount), covered=$($result.coveredCount), enabled=$($result.enabledCount), disabled=$($result.disabledCount), missing=$($result.missingCount), attention=$($result.attentionCount), policyRows=$policyRows, privateStateExposed=$($result.privateStateExposed)"
|
||||
Write-Host "Service policy directory: status=$($result.status), owner=$($result.lifecycleOwner), hostedBody=$($result.hostedBody), daemons=$($result.daemonCount), covered=$($result.coveredCount), enabled=$($result.enabledCount), disabled=$($result.disabledCount), missing=$($result.missingCount), attention=$($result.attentionCount), policyRows=$policyRows, privateStateExposed=$($result.privateStateExposed)"
|
||||
} elseif ($Mode -eq "service-plan") {
|
||||
$plannedArgs = "none"
|
||||
if ($null -ne $result.args -and $result.args.Count -gt 0) {
|
||||
|
|
|
|||
Reference in a new issue