docs: capture personal-agent runtime readiness snapshot

This commit is contained in:
Svrnty
2026-06-14 08:40:58 -04:00
parent 412f669b93
commit 8274edffeb
6 changed files with 315 additions and 1 deletions
+1
View File
@@ -10,6 +10,7 @@ JP's personal assistant / chief of staff. Daily briefing, inbox triage, comms in
- **Proton/rclone package candidate:** [`docs/contracts/personal-agent-proton-rclone-package.json`](docs/contracts/personal-agent-proton-rclone-package.json) — Mail, Calendar, Contacts, and Drive surfaces with redacted runtime inventory and no readiness overclaim. - **Proton/rclone package candidate:** [`docs/contracts/personal-agent-proton-rclone-package.json`](docs/contracts/personal-agent-proton-rclone-package.json) — Mail, Calendar, Contacts, and Drive surfaces with redacted runtime inventory and no readiness overclaim.
- **Secondbrain proposal route:** [`docs/contracts/personal-agent-secondbrain-proposal-route.json`](docs/contracts/personal-agent-secondbrain-proposal-route.json) — proposal-only personal memory intake; durable apply remains owned by Secondbrain. - **Secondbrain proposal route:** [`docs/contracts/personal-agent-secondbrain-proposal-route.json`](docs/contracts/personal-agent-secondbrain-proposal-route.json) — proposal-only personal memory intake; durable apply remains owned by Secondbrain.
- **Conductor/Curator service handoff:** [`docs/contracts/personal-agent-conductor-curator-service-handoff.json`](docs/contracts/personal-agent-conductor-curator-service-handoff.json) — redacted service map for future route selection and hygiene review pickup. - **Conductor/Curator service handoff:** [`docs/contracts/personal-agent-conductor-curator-service-handoff.json`](docs/contracts/personal-agent-conductor-curator-service-handoff.json) — redacted service map for future route selection and hygiene review pickup.
- **Runtime readiness snapshot:** [`docs/contracts/personal-agent-runtime-readiness-snapshot.json`](docs/contracts/personal-agent-runtime-readiness-snapshot.json) — redacted per-surface runtime state and gaps; aggregate readiness remains degraded.
- **Historical Steev reference redirect:** [`docs/STEEV-MASTER.md`](docs/STEEV-MASTER.md). - **Historical Steev reference redirect:** [`docs/STEEV-MASTER.md`](docs/STEEV-MASTER.md).
## Structure ## Structure
+5
View File
@@ -39,3 +39,8 @@ items:
status: complete status: complete
source: docs/contracts/personal-agent-conductor-curator-service-handoff.json source: docs/contracts/personal-agent-conductor-curator-service-handoff.json
owner: jp owner: jp
- id: PACR-007
title: Runtime Readiness And Always-On Proof
status: complete
source: docs/contracts/personal-agent-runtime-readiness-snapshot.json
owner: jp
+1
View File
@@ -18,6 +18,7 @@ Active authority:
- `docs/contracts/personal-agent-proton-rclone-package.json` - `docs/contracts/personal-agent-proton-rclone-package.json`
- `docs/contracts/personal-agent-secondbrain-proposal-route.json` - `docs/contracts/personal-agent-secondbrain-proposal-route.json`
- `docs/contracts/personal-agent-conductor-curator-service-handoff.json` - `docs/contracts/personal-agent-conductor-curator-service-handoff.json`
- `docs/contracts/personal-agent-runtime-readiness-snapshot.json`
- `docs/prd/2026-06-14-personal-agent-context-runtime-prd.md` - `docs/prd/2026-06-14-personal-agent-context-runtime-prd.md`
- `docs/supersession/2026-06-14-personal-agent-context-runtime-supersession-register.md` - `docs/supersession/2026-06-14-personal-agent-context-runtime-supersession-register.md`
@@ -0,0 +1,170 @@
{
"schema_version": "personal-agent-runtime-readiness-snapshot/v1",
"status": "active-redacted-runtime-snapshot",
"snapshot_id": "personal-agent-runtime-readiness-2026-06-14",
"profile_identity": "personal-agent",
"display_name": "Steev",
"observed_date": "2026-06-14",
"aggregate_runtime_state": "degraded",
"runtime_readiness_claimed": false,
"seed_readiness_claimed": false,
"core_promotion_claimed": false,
"memory_target": "secondbrain-personal",
"forbidden_memory_targets": [
"orgbrain"
],
"surface_states": [
{
"surface": "imessage.read",
"capability_package": "bluebubbles",
"readiness_state": "ready",
"health_source": "python3 tools/validate_bluebubbles_child.py",
"redacted_health": {
"validator_ok": true,
"read_only_imessage": true,
"memory_domain": "secondbrain-personal",
"orgbrain_forbidden": true,
"package_runtime_claims": false
},
"remaining_gap": "Profile aggregate runtime readiness still false until final acceptance packet."
},
{
"surface": "mail.read",
"capability_package": "proton-rclone",
"readiness_state": "degraded",
"health_source": "MCP registration plus local service inventory",
"redacted_health": {
"mcp_server_enabled": true,
"proton_bridge_systemd_running": true,
"docker_email_gate": "exited-127",
"raw_mail_observed": false
},
"remaining_gap": "Email gate repair or replacement and package child registration remain required."
},
{
"surface": "calendar.read",
"capability_package": "proton-rclone",
"readiness_state": "degraded",
"health_source": "MCP registration plus local service inventory",
"redacted_health": {
"mcp_server_enabled": true,
"calendar_gate_running": true,
"proton_bridge_systemd_running": true,
"raw_calendar_events_observed": false
},
"remaining_gap": "Calendar read has service posture but no governed package child runtime proof."
},
{
"surface": "contacts.read",
"capability_package": "proton-rclone",
"readiness_state": "degraded",
"health_source": "MCP registration plus local service inventory",
"redacted_health": {
"mcp_server_enabled": true,
"docker_contacts_gate": "exited-127",
"raw_contacts_observed": false
},
"remaining_gap": "Contacts gate repair or replacement and package child registration remain required."
},
{
"surface": "drive.read",
"capability_package": "proton-rclone",
"readiness_state": "degraded",
"health_source": "rclone explicit-config about probe",
"redacted_health": {
"rclone_remote_present": true,
"rclone_about_probe": "ok-redacted",
"rclone_rc_unit": "disabled",
"rclone_proxy_unit": "disabled",
"drive_file_names_observed": false,
"drive_file_contents_observed": false
},
"remaining_gap": "Drive read needs governed wrapper and package child before runtime readiness."
}
],
"supervisor_posture": {
"mac_mini_bluebubbles": "package-validator-ok-redacted",
"proton_bridge_service": "active-running",
"proton_bridge_proxy_service": "active-running",
"rclone_rc_service": "disabled-inactive",
"rclone_proxy_service": "disabled-inactive"
},
"named_runtime_gaps": [
{
"id": "proton-email-gate-exited",
"severity": "must-fix",
"state": "sdo-email-gate exited-127",
"impact": "mail.read remains degraded"
},
{
"id": "proton-contacts-gate-exited",
"severity": "must-fix",
"state": "sdo-contacts-gate exited-127",
"impact": "contacts.read remains degraded"
},
{
"id": "stale-protonmail-bridge-container",
"severity": "follow-up",
"state": "stale sdo-protonmail-bridge container exists in Created state",
"impact": "duplicate service topology must be resolved before final runtime readiness"
},
{
"id": "proton-rclone-child-unregistered",
"severity": "must-fix",
"state": "package candidate exists but no registered child workspace",
"impact": "Proton/rclone package cannot claim runtime readiness"
},
{
"id": "secondbrain-apply-blocked",
"severity": "must-fix",
"state": "proposal route exists; durable apply remains blocked",
"impact": "personal memory intake is not durable yet"
},
{
"id": "desktop-adapter-exposure-blocked",
"severity": "follow-up",
"state": "adapter lane must pick up the contract before desktop display",
"impact": "desktop app cannot display final personal-agent runtime readiness yet"
}
],
"optional_reboot_power_loss_proof": {
"status": "not-run",
"required_for_final_always_on_claim": true,
"notes": "Current proof verifies supervisor posture and package validators, not reboot recovery."
},
"observed_commands": [
"python3 tools/validate_bluebubbles_child.py",
"hermes -p steev mcp list",
"systemctl --user show proton-bridge.service proton-bridge-proxy.service rclone-rc.service rclone-proxy.service -p Id -p LoadState -p ActiveState -p SubState -p UnitFileState --no-pager",
"docker ps -a --format '<name status image>' | rg -i 'bluebubbles|proton|calendar|contacts|email|mail|rclone|sdo'",
"rclone --config /home/svrnty/.config/rclone/rclone.conf about proton: --json"
],
"proof_policy": {
"mode": "redacted-only",
"forbidden_fields": [
"raw_messages",
"message_text",
"mail_bodies",
"mail_subjects",
"sender_address",
"recipient_address",
"contact_details",
"calendar_event_details",
"drive_file_names",
"drive_file_contents",
"attachment_content",
"endpoint_payloads",
"credentials",
"secret_values"
]
},
"remaining_gates": {
"proton_email_gate_repair": "blocked-follow-up",
"proton_contacts_gate_repair": "blocked-follow-up",
"proton_rclone_child_registration": "blocked-follow-up",
"secondbrain_durable_apply": "blocked-follow-up",
"desktop_adapter_exposure": "blocked-follow-up",
"reboot_power_loss_drill": "optional-follow-up",
"final_acceptance_packet": "blocked-follow-up"
}
}
@@ -40,6 +40,7 @@ desktop exposure must be treated as one of:
| Personal memory durable apply | blocked-follow-up | Owning Secondbrain/curator route must approve and apply; profile/capability packages do not write durable memory | | Personal memory durable apply | blocked-follow-up | Owning Secondbrain/curator route must approve and apply; profile/capability packages do not write durable memory |
| Personal-agent Conductor/Curator service handoff | active-authority | `docs/contracts/personal-agent-conductor-curator-service-handoff.json` gives route and hygiene lanes a redacted service map | | Personal-agent Conductor/Curator service handoff | active-authority | `docs/contracts/personal-agent-conductor-curator-service-handoff.json` gives route and hygiene lanes a redacted service map |
| Conductor/curator adoption | blocked-follow-up | Owning lanes must explicitly pick up the handoff; this profile does not mutate them | | Conductor/curator adoption | blocked-follow-up | Owning lanes must explicitly pick up the handoff; this profile does not mutate them |
| Personal-agent runtime readiness snapshot | active-authority | `docs/contracts/personal-agent-runtime-readiness-snapshot.json` names per-surface states and runtime gaps without aggregate readiness claim |
| Desktop app exposure | blocked-follow-up | `PACR-008`, after adapter lane release | | Desktop app exposure | blocked-follow-up | `PACR-008`, after adapter lane release |
| Browser/Webwright host control | blocked-follow-up | `PACR-009`, explicit approval only | | Browser/Webwright host control | blocked-follow-up | `PACR-009`, explicit approval only |
@@ -78,6 +79,7 @@ desktop exposure must be treated as one of:
- Graph context should expose the Proton/rclone package candidate as the active standardization pickup, not a runtime-ready child package. - Graph context should expose the Proton/rclone package candidate as the active standardization pickup, not a runtime-ready child package.
- Graph context should expose the personal-agent Secondbrain proposal route as active while keeping durable apply blocked to Secondbrain/curator. - Graph context should expose the personal-agent Secondbrain proposal route as active while keeping durable apply blocked to Secondbrain/curator.
- Graph context should expose the personal-agent Conductor/Curator service handoff as active, while adoption remains blocked to owning lanes. - Graph context should expose the personal-agent Conductor/Curator service handoff as active, while adoption remains blocked to owning lanes.
- Graph context should expose the personal-agent runtime snapshot as degraded until the named runtime gaps close.
- Graph context should not treat legacy Cortex Proton/rclone repositories as active authority. - Graph context should not treat legacy Cortex Proton/rclone repositories as active authority.
- Graph context should not treat duplicate Proton skills as separate current product surfaces. - Graph context should not treat duplicate Proton skills as separate current product surfaces.
- Graph context should mark browser/Webwright host control as separate HITL runtime authority. - Graph context should mark browser/Webwright host control as separate HITL runtime authority.
+136 -1
View File
@@ -22,6 +22,7 @@ REQUIRED = [
"docs/contracts/personal-agent-proton-rclone-package.json", "docs/contracts/personal-agent-proton-rclone-package.json",
"docs/contracts/personal-agent-secondbrain-proposal-route.json", "docs/contracts/personal-agent-secondbrain-proposal-route.json",
"docs/contracts/personal-agent-conductor-curator-service-handoff.json", "docs/contracts/personal-agent-conductor-curator-service-handoff.json",
"docs/contracts/personal-agent-runtime-readiness-snapshot.json",
"docs/prd/2026-06-14-personal-agent-context-runtime-prd.md", "docs/prd/2026-06-14-personal-agent-context-runtime-prd.md",
"docs/issues/2026-06-14-personal-agent-context-runtime-work-orders.md", "docs/issues/2026-06-14-personal-agent-context-runtime-work-orders.md",
"docs/supersession/2026-06-14-personal-agent-context-runtime-supersession-register.md", "docs/supersession/2026-06-14-personal-agent-context-runtime-supersession-register.md",
@@ -112,6 +113,23 @@ REQUIRED_HANDOFF_SERVICES = {
"personal-agent.secondbrain.proposal-route", "personal-agent.secondbrain.proposal-route",
} }
REQUIRED_RUNTIME_SURFACES = {
"imessage.read",
"mail.read",
"calendar.read",
"contacts.read",
"drive.read",
}
REQUIRED_RUNTIME_GAPS = {
"proton-email-gate-exited",
"proton-contacts-gate-exited",
"stale-protonmail-bridge-container",
"proton-rclone-child-unregistered",
"secondbrain-apply-blocked",
"desktop-adapter-exposure-blocked",
}
def read_text(rel: str) -> str: def read_text(rel: str) -> str:
return (ROOT / rel).read_text(encoding="utf-8") return (ROOT / rel).read_text(encoding="utf-8")
@@ -148,6 +166,7 @@ def main() -> int:
"PACR-004", "PACR-004",
"PACR-005", "PACR-005",
"PACR-006", "PACR-006",
"PACR-007",
"status: candidate", "status: candidate",
"owner: jp", "owner: jp",
]: ]:
@@ -739,6 +758,121 @@ def main() -> int:
if remaining_gates.get(gate) != "blocked-follow-up": if remaining_gates.get(gate) != "blocked-follow-up":
errors.append(f"service_handoff_remaining_gate_missing:{gate}") errors.append(f"service_handoff_remaining_gate_missing:{gate}")
runtime = load_json("docs/contracts/personal-agent-runtime-readiness-snapshot.json", errors)
if runtime:
if runtime.get("schema_version") != "personal-agent-runtime-readiness-snapshot/v1":
errors.append("runtime_snapshot_schema_version_invalid")
if runtime.get("status") != "active-redacted-runtime-snapshot":
errors.append("runtime_snapshot_status_invalid")
if runtime.get("profile_identity") != "personal-agent":
errors.append("runtime_snapshot_profile_identity_not_personal_agent")
if runtime.get("display_name") != "Steev":
errors.append("runtime_snapshot_display_name_not_steev")
if runtime.get("aggregate_runtime_state") != "degraded":
errors.append("runtime_snapshot_aggregate_not_degraded")
for key in ["runtime_readiness_claimed", "seed_readiness_claimed", "core_promotion_claimed"]:
if runtime.get(key) is not False:
errors.append(f"runtime_snapshot_overclaim:{key}")
if runtime.get("memory_target") != "secondbrain-personal":
errors.append("runtime_snapshot_memory_target_not_secondbrain_personal")
if "orgbrain" not in runtime.get("forbidden_memory_targets", []):
errors.append("runtime_snapshot_orgbrain_not_forbidden")
surfaces = runtime.get("surface_states", [])
surface_names = {surface.get("surface") for surface in surfaces}
missing_surfaces = sorted(REQUIRED_RUNTIME_SURFACES - surface_names)
if missing_surfaces:
errors.append(f"runtime_snapshot_surfaces_missing:{','.join(missing_surfaces)}")
state_by_surface = {surface.get("surface"): surface.get("readiness_state") for surface in surfaces}
if state_by_surface.get("imessage.read") != "ready":
errors.append("runtime_snapshot_imessage_not_ready")
for surface in ["mail.read", "calendar.read", "contacts.read", "drive.read"]:
if state_by_surface.get(surface) != "degraded":
errors.append(f"runtime_snapshot_surface_not_degraded:{surface}")
for surface in surfaces:
name = surface.get("surface", "<unknown>")
if surface.get("readiness_state") not in {"ready", "degraded", "pending", "blocked", "disabled"}:
errors.append(f"runtime_snapshot_readiness_invalid:{name}")
if not surface.get("capability_package"):
errors.append(f"runtime_snapshot_package_missing:{name}")
if not surface.get("health_source"):
errors.append(f"runtime_snapshot_health_source_missing:{name}")
health = surface.get("redacted_health")
if not isinstance(health, dict):
errors.append(f"runtime_snapshot_health_not_object:{name}")
if "raw_mail_observed" in health and health.get("raw_mail_observed") is not False:
errors.append("runtime_snapshot_raw_mail_observed")
if "raw_calendar_events_observed" in health and health.get("raw_calendar_events_observed") is not False:
errors.append("runtime_snapshot_raw_calendar_observed")
if "raw_contacts_observed" in health and health.get("raw_contacts_observed") is not False:
errors.append("runtime_snapshot_raw_contacts_observed")
if "drive_file_names_observed" in health and health.get("drive_file_names_observed") is not False:
errors.append("runtime_snapshot_drive_file_names_observed")
if "drive_file_contents_observed" in health and health.get("drive_file_contents_observed") is not False:
errors.append("runtime_snapshot_drive_file_contents_observed")
imessage_health = next((surface.get("redacted_health", {}) for surface in surfaces if surface.get("surface") == "imessage.read"), {})
if imessage_health.get("validator_ok") is not True:
errors.append("runtime_snapshot_bluebubbles_validator_not_ok")
if imessage_health.get("read_only_imessage") is not True:
errors.append("runtime_snapshot_imessage_not_readonly")
if imessage_health.get("package_runtime_claims") is not False:
errors.append("runtime_snapshot_bluebubbles_runtime_claim_overclaimed")
posture = runtime.get("supervisor_posture", {})
expected_posture = {
"mac_mini_bluebubbles": "package-validator-ok-redacted",
"proton_bridge_service": "active-running",
"proton_bridge_proxy_service": "active-running",
"rclone_rc_service": "disabled-inactive",
"rclone_proxy_service": "disabled-inactive",
}
for key, expected in expected_posture.items():
if posture.get(key) != expected:
errors.append(f"runtime_snapshot_posture_mismatch:{key}")
gaps = {gap.get("id") for gap in runtime.get("named_runtime_gaps", [])}
missing_gaps = sorted(REQUIRED_RUNTIME_GAPS - gaps)
if missing_gaps:
errors.append(f"runtime_snapshot_gaps_missing:{','.join(missing_gaps)}")
reboot = runtime.get("optional_reboot_power_loss_proof", {})
if reboot.get("status") != "not-run":
errors.append("runtime_snapshot_reboot_status_not_not_run")
if reboot.get("required_for_final_always_on_claim") is not True:
errors.append("runtime_snapshot_reboot_not_required_for_final")
commands = set(runtime.get("observed_commands", []))
for command in [
"python3 tools/validate_bluebubbles_child.py",
"hermes -p steev mcp list",
"rclone --config /home/svrnty/.config/rclone/rclone.conf about proton: --json",
]:
if command not in commands:
errors.append(f"runtime_snapshot_observed_command_missing:{command}")
forbidden_fields = set(runtime.get("proof_policy", {}).get("forbidden_fields", []))
for field in [
"raw_messages",
"message_text",
"mail_bodies",
"contact_details",
"calendar_event_details",
"drive_file_names",
"drive_file_contents",
"endpoint_payloads",
"credentials",
"secret_values",
]:
if field not in forbidden_fields:
errors.append(f"runtime_snapshot_forbidden_field_missing:{field}")
remaining_gates = runtime.get("remaining_gates", {})
for gate in [
"proton_email_gate_repair",
"proton_contacts_gate_repair",
"proton_rclone_child_registration",
"secondbrain_durable_apply",
"desktop_adapter_exposure",
"final_acceptance_packet",
]:
if remaining_gates.get(gate) != "blocked-follow-up":
errors.append(f"runtime_snapshot_remaining_gate_missing:{gate}")
if remaining_gates.get("reboot_power_loss_drill") != "optional-follow-up":
errors.append("runtime_snapshot_reboot_gate_missing")
for rel in ["AGENT.md", "CONTRACT.md", "DISCLOSURE.md", "README.md", "docs/STEEV-MASTER.md"]: for rel in ["AGENT.md", "CONTRACT.md", "DISCLOSURE.md", "README.md", "docs/STEEV-MASTER.md"]:
path = ROOT / rel path = ROOT / rel
if not path.exists(): if not path.exists():
@@ -760,6 +894,7 @@ def main() -> int:
"Proton/rclone package candidate", "Proton/rclone package candidate",
"Personal-agent Secondbrain proposal route", "Personal-agent Secondbrain proposal route",
"Personal-agent Conductor/Curator service handoff", "Personal-agent Conductor/Curator service handoff",
"Personal-agent runtime readiness snapshot",
"superseded", "superseded",
"legacy-reference", "legacy-reference",
"blocked-follow-up", "blocked-follow-up",
@@ -775,7 +910,7 @@ def main() -> int:
result = { result = {
"ok": not errors, "ok": not errors,
"validator": "personal-agent-profile-distribution-v5", "validator": "personal-agent-profile-distribution-v6",
"checked": REQUIRED, "checked": REQUIRED,
"errors": errors, "errors": errors,
"warnings": [], "warnings": [],